本文主要是介绍USART串口通讯函数实现 (基于寄存器),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
环境
芯片:STM32F103ZET6
库:来自HAL的STM32F1XX.H
原理图
如图可知TX和RX两条线接到了PA9和PA10
-
Driver_USART1.h
-
#ifndef __DRIVER_USART1_H #define __DRIVER_USART1_H#include "stm32f1xx.h"/*** 初始化USART1 完成相关配置 能够调用下面收发数据的代码*/ void Driver_USART1_Init(void);/*** 发送一个字节* uint8_t ch: 需要发送的一个字节*/ void Driver_USART1_SendChar(uint8_t ch);/*** 接收一个字节* return: uint8_t 接收到的字节*/ uint8_t Driver_USART1_ReceiveChar(void);/*** 发送多个字节* uint8_t *str: 一个字符串* uint8_t len: 字符串长度*/ void Driver_USART1_SendString(uint8_t *str,uint8_t len);/*** 接收多个字节 -> 由于不能确定接收数据的长度 -> 推荐buff够大* 收到空闲位结束* uint8_t buff[]: 存接收到的数据* uint8_t * len: 实际接收数据的长度 -> 需要函数中赋值*/ void Driver_USART1_ReceiveString(uint8_t buff[],uint8_t * len);#endif
-
-
Driver_USART1.c
-
#include "Driver_USART1.h"/*** 初始化USART1 完成相关配置 能够调用下面收发数据的代码*/ void Driver_USART1_Init(void) {/* 1. 打开USART1相关时钟 AFIO主要控制事件和外部中断 -> 片上外设的复用引脚有专门的位控制 */RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;RCC->APB2ENR |= RCC_APB2ENR_USART1EN;/* 2. 配置使用到的引脚模式 -> PA9 TX 复用推挽输出 1011 -> PA10 RX 浮空输入模式 0100 */GPIOA->CRH |= (GPIO_CRH_CNF9_1 | GPIO_CRH_MODE9);GPIOA->CRH &= ~(GPIO_CRH_CNF9_0);GPIOA->CRH |= GPIO_CRH_CNF10_0;GPIOA->CRH &= ~(GPIO_CRH_CNF10_1 | GPIO_CRH_MODE10);/* 3. 配置USART1 */// 3.1 配置波特比率USART1->BRR = 0X0271;// 3.2 数据长度 8位USART1->CR1 &= ~(USART_CR1_M);// 3.3 校验位USART1->CR1 &= ~(USART_CR1_PCE);// 3.4 停止位USART1->CR2 &= ~(USART_CR2_STOP);// 3.5 打开使能开关// 3.5.1 发送开关USART1->CR1 |= USART_CR1_TE;// 3.5.2 接收开关USART1->CR1 |= USART_CR1_RE;// 3.5.3 总开关USART1->CR1 |= USART_CR1_UE; }/*** 发送一个字节* uint8_t ch: 需要发送的一个字节*/ void Driver_USART1_SendChar(uint8_t ch) {// 往DR寄存器直接写 -> 发送数据// 需要等待上一个字节发送完成之后 -> 才能发送下一个字节// SR_TXE 如果数据正在发 -> 0// 如果数据发生完成 -> 1while ((USART1->SR & USART_SR_TXE) == 0);USART1->DR = ch; }/*** 接收一个字节* return: uint8_t 接收到的字节*/ uint8_t Driver_USART1_ReceiveChar(void) {// 接收数据也需要挂起 -> 等待有数据传入// SR_RXNE : 有数据进来 -> 1// 读取一次之后 -> 0while ((USART1->SR & USART_SR_RXNE) == 0);return USART1->DR; }/*** 发送多个字节* uint8_t *str: 一个字符串* uint8_t len: 字符串长度*/ void Driver_USART1_SendString(uint8_t *str, uint8_t len) {for (uint8_t i = 0; i < len; i++){Driver_USART1_SendChar(str[i]);} }/*** 接收多个字节 -> 由于不能确定接收数据的长度 -> 推荐buff够大* 收到空闲位结束* uint8_t buff[]: 存接收到的数据* uint8_t * len: 实际接收数据的长度 -> 需要函数中赋值*/ void Driver_USART1_ReceiveString(uint8_t buff[], uint8_t *len) {uint8_t i = 0;while (1){// 1. 收到数据 存缓存if (USART1->SR & USART_SR_RXNE){buff[i] = USART1->DR;i++;}// 2. 收到空闲 停止if (USART1->SR & USART_SR_IDLE){*len = i;break;}} }
-
这篇关于USART串口通讯函数实现 (基于寄存器)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!