一、串口介绍
1.1、USART其实就是一种设备与设备之间的通讯协议。具体协议内容请查看
STM32 USART通信协议详细讲解—小白入门_stm32 usart cts rts-CSDN博客
1.2、下面我们来看看芯片有多少个串口资源给我们使用
1.2.1、从选型手册查看可以得出(USART+UART)共有5个
1.2.2、从系统架构图可以看出USART0是挂载到APB2总线上的,最大时钟是108MHz,USART1,USART2,UART3,UART4,都在APB1总线上,最大时钟未54MHz
1.3、USART模块内部框图介绍
从上图红色区域为芯片外部也就是引脚,其他在芯片内部,重要引脚描述如下
引脚 | 类型 | 描述 |
RX | 输入 | 接收数据 |
TX | 输出 I/O(单线模式/智能卡模式) | 发送数据。当USART使能后,若无数据发送,默认为高电平 |
CK | 输出 | 用于同步通信的串行时钟信号 |
nCTS | 输入 | 硬件流控模式发送使能信号 |
nRTS | 输出 | 硬件流控模式发送请求信号 |
二、寄存器介绍
2.1、状态寄存器(USART_STAT)
2.2、数据寄存器(USART_DATA)
2.3、波特率寄存器(USART_BAUD)
2.4、控制寄存器0(USART_CTL0)
2.5、控制寄存器1(USART_CTL1)
2.6、控制寄存器2(USART_CTL2)
2.7、保护时间和预分频器寄存器(USART_GP)
三、函数介绍
3.1、函数汇总
3.2、部分函数详细描述
函数名 | 描述 | ||||||
usart_deinit |
| ||||||
usart_baudrate_set |
| ||||||
usart_word_length_set |
| ||||||
usart_stop_bit_set |
| ||||||
usart_parity_config |
| ||||||
usart_hardware_flow_cts_config |
| ||||||
usart_hardware_flow_rts_config |
| ||||||
usart_receive_config |
| ||||||
usart_transmit_config |
| ||||||
usart_enable |
| ||||||
四、USART初始化
4.1、USART使用步骤
1、串口时钟使能GPIO时钟使能
2、串口复位
3、GPIO端口模式设置
4、串口参数初始化
5、开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)
6、使能串口
7、编写中断处理函数
4.2、引脚分布
4.3、初始化函数
USART初始化,我这里硬件只能使用PC10和PC11需要重映射(如果你们不是使用的引脚则不需要使用函数“gpio_pin_remap_config”),我们在初始化时需要把他的模式设置为复用功能。这里把串口的Tx引脚设置为复用推挽输出,Rx应交设置为浮空输入,数据完全由外部输入决定。
我们配置USART2通讯参数为:波特率 115200,字长为 8,1个停止位,没有校验位,不使用硬件流控制。
void USART_init(int baud)
{
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_AF);
rcu_periph_clock_enable(RCU_USART2);
gpio_pin_remap_config(GPIO_USART2_PARTIAL_REMAP, ENABLE);
gpio_init(GPIOC,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_11);
gpio_init(GPIOC,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_10);
usart_deinit(USART2); //复位外设USART2
usart_baudrate_set(USART2,baud); //设置波特率为9600,也就是设置2.3(USART_BAUD)寄存器
usart_word_length_set(USART2,USART_WL_8BIT);//设置字长,也就是数据位
usart_stop_bit_set(USART2,USART_STB_1BIT);//设置停止位为1位
usart_parity_config(USART2,USART_PM_NONE);//无奇偶校验位
usart_hardware_flow_cts_config(USART2,USART_CTS_DISABLE);//关闭CTS硬件控制流范围
usart_hardware_flow_rts_config(USART2,USART_RTS_DISABLE);//关闭CTS硬件控制流范围
usart_receive_config(USART2,USART_RECEIVE_ENABLE);//使能接收
usart_transmit_config(USART2,USART_TRANSMIT_ENABLE);//使能发送
usart_enable(USART2);
nvic_irq_enable(USART2_IRQn,0,0);//使能USART2中断
usart_interrupt_enable(USART2,USART_INT_RBNE);//使能串口接收中断
}
4.4、中断函数
使能了USART2接收中断,当USART2接收到数据就会执行USART2_IRQHandler()函数,
void USART2_IRQHandler()
{
unsigned char data;
if(usart_interrupt_flag_get(USART2,USART_INT_FLAG_RBNE)!=RESET)//判断是不是串口接收中断
{
data=usart_data_receive(USART2);//获取收到的数据
usart_data_transmit(USART2,data);//把收到的数据发送回去
while(usart_flag_get(USART2,USART_FLAG_TBE)==RESET);//等待发送完成
// usart_interrupt_flag_clear(USART2,USART_INT_RBNE);
}
}
串口对应的中断处理函数名称可以在“startup_gd32f10x_hd.s”查看
4.5、主函数
4.6、实验结果
通过串口助手,我们把串口设置波特率,停止位,数据位,校验位和我们程序设置的一样,然后,在发送区输入数字,点发送,可以看出我们发送什么他就返回什么
用逻辑分析仪抓出的波形如下(注意这里发送的是1,而不是上面串口助手的数字)
五、扩展printf重定向实现
GD32fxxx stm32fxx printf c语言实现_gd32 printf-CSDN博客
六、问题
我在调试这个程序的时候遇到一个问题,初始化的时候我没有初始化GPIOC时钟,但是却能收到上位机发送的数据,但是不能把收到的数据发送出去。这个原因是什么,难道输入是不需要GPIO时钟吗,请各位大佬指点一下这个是什么原因。(复现这个问题,可以把USART_init函数中的rcu_periph_clock_enable(RCU_GPIOC);注释掉就可以复现了)