欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

STM32下的USART串口通信程序

程序员文章站 2024-02-22 10:08:52
...

一、STM32的USART简介

通用同步异步收发器(Universal Synchronous Asynchronous Receiver and Transmitter)是一个串行通信设备,可以灵活地与外部设备进行全双工数据交换。
串行通信一般是以帧格式传输数据,即是一帧一帧的传输,每帧包含有起始信号、数据信息、停止信息,可能还有校验信息。USART就是对这些传输参数有具体规定,当然也不是只有唯一一个参数值,很多参数值都可以自定义设置,只是增强它的兼容性。
USART满足外部设备对工业标准(NRZ异步串行数据格式的要求,并且使用了小数波特率发生器,可以提供多种波特率,使得它的应用更加广泛。[USART]支持同步单向通信和半双工单线通信;还支持局域互连网络LN、智能卡(SmartCard)协议与IhDA(红外线数据协会)SIR ENDEC规范。
USART支持使用DMA,可实现高速数据通信,
USART在 STM32应用最多莫过于“打印”程序信息,一般在硬件设计时都会预留一个USART通信接口连接电脑,用于在调试程序是可以把一些调试信息“打印”在电脑端的串口调试助手工具上,从而了解程序运行是否正确、如果出错哪具体哪里出错等等。[1]

二、 USART功能框图

USART 的功能框图包含了USART最核心内容,掌握了功能框图,对 USART就有一个整体的把握,在编程时就思路就非常清晰。USART功能框图见下图:[1]
STM32下的USART串口通信程序

  1. ①功能引脚
  2. ②数据寄存器
  3. ③控制器
  4. ④小数波特率生成
  5. 校验控制
  6. 中断控制

具体内容请参考野火官方书籍《零死角玩转STM32——F103指南者》,或者STM32串口通信USART学习笔记

三、 USART接发通信实验

USART只需两根信号线即可完成双向通信,对硬件要求低,使得很多模块都预留USART接口来实现与其他模块或者控制器进行数据传输,比如GSM模块,WIFI模块、蓝牙模块等等。在硬件设计时,注意还需要一根“共地线”
我们可以将数据发送到串口调试助手,我们还可以在串口调试助手发送数据给控制器,控制器程序根据接收到的数据进行下一步工作。
以下将开展USART接发通信实验
任务要求如下:
1)设置波特率为115200,1位停止位,无校验位。
2)STM32系统给上位机(win10)连续发送“hello windows! ”,上位机接收程序可以使用“串口调试助手“,也可自己编程
3)当上位机给stm32发送“Stop,stm32”后,stm32停止发送。

3.1实验环境

①STM32核心板(stm32F103)
②MDK KEIL5
③实验所用串口:USART1
④驱动:CH340

3.2 硬件设计

3.2.1硬件原理图

STM32下的USART串口通信程序

CH340G芯片 的作用是将电脑的USB电平转换为串口的TTL电平。
因此在实验前,确保自己的电脑已经安装了CH340的驱动。
但一般我们在市面上买到的USB-TTL接线器已将整个模块焊接在整体了,这里大家只做个初步了解原理就行。

USB-TTL与STM32F103具体连接方式如下:
STM32下的USART串口通信程序

3.3 软件程序设计

  • 核心代码-串口初识化
void uart_init(u32 bound){
  //GPIO端口设置
  GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟
  
	//USART1_TX   GPIOA.9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
   
  //USART1_RX	  GPIOA.10初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

  //Usart1 NVIC 配置
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
  
   //USART 初始化设置

	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式

  USART_Init(USART1, &USART_InitStructure); //初始化串口1
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
  USART_Cmd(USART1, ENABLE);                    //使能串口1 

}
  • 主函数
int main(void)
 {	
    u8 Stopflag[]="Stop,stm32";     //停止发送信号
    u8 Beginflag[]="Begin,stm32";   //恢复发送信号
 	u16 t,len;  	
	u16 times=0;    //设置计数器
    u16 flag=1,flag_S,flag_B;   //设置标志位
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 //串口初始化为115200
 	//LED_Init();			     //LED端口初始化
	//KEY_Init();          //初始化与按键连接的硬件接口
 	while(1)
	{
        flag_S=flag_B=1;
		if(USART_RX_STA&0x8000)
		{					   
			len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
			printf("\r\n您发送的消息为:\r\n");
			for(t=0;t<len;t++)
			{
                if(Stopflag[t]!=USART_RX_BUF[t]) flag_S=0;  //若接受数据与停止发送信号不同将flag_S置为0
                if(Beginflag[t]!=USART_RX_BUF[t]) flag_B=0; //若接受数据与恢复发送信号不同将flag_B置为0
				USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
			}
			printf("\r\n\r\n");//插入换行
            if(flag_S==1)   //如果flag_S==1表示上位机发送的是停止发送信号
            {
                flag=0;
                printf("已停止发送\r\n\r\n");
            }
            if(flag_B==1)   //如果flag_B==1表示上位机发送的是恢复发送信号 
            {  
                flag=1;
                printf("已恢复发送\r\n\r\n");
            }
			USART_RX_STA=0;
		}
        else
		{
            //flag为1表示允许stm32发送数据
            if(flag==1) times++;
			if(times%100==0&&flag==1)    printf("hello Windows!\r\n"); 
			//if(times%30==0&&flag==1) LED=!LED;   //闪烁LED,提示系统正在运行.
			delay_ms(10);   
		}
	}	 
 }

3.3 烧录程序

这里用的是USB-TTL接线器,需要专门的软件以及与正确的连线才可以烧录程序。
STM32下的USART串口通信程序
STM32下的USART串口通信程序
STM32下的USART串口通信程序

四、 效果演示

演示时需要对XCOM进行相对应的设置才可以正常进行串口通信。
STM32下的USART串口通信程序
STM32下的USART串口通信程序
可以通过动态图可见,基本完成了STM32的串口通信和标志位停止发送的实践要求。

五、 总结

通过此次是实践学习,我明白了串口通信的基本知识和STM32串口通信的基本设置与操作,其中也遇到了不少问题,特别感谢我的老师以及同学对我的耐心讲解和网上资料。

六、 参考资料

[1] 《零死角玩转STM32——F103指南者》
[2]STM32串口通信USART学习笔记
[3]STM32平台的USART串口通信