3.4节串口收发实验
本节将学习STM32使用串口与电脑进行通信
a.实验准备:USB转串口模块,ST-Llink下载器,CHEAPX机器人控制板
b.实验目的:STM32串口的使用
c.相关知识点:
串口是一种电子设备间常用的串行通讯方式,电子工程师在调试设备时也经常使用该通讯方式输出调试信息。串口是全双工通信,即可以同时收数据和发数据。发数据使用TX管脚,收数据使用RX管脚。STM32中的USART串口外设已经实现了串口底层协议,所以我们直接使用就行。STM32中的USART串口通信,一般使用中断模式。但有数据过来是,产生中断信号,CPU直接跳转进中断函数运行。注意,STM32是单核单线程处理器,硬件中断的存在,让STM32可以实现上位机多线程类似效果。
d.编程及运行
(1)初始化芯片的串口管脚A9 A10和配置USART,位置如下图。步骤如下:打开对应GPIO口,串口的时钟,再配置管脚参数,配置串口参数。
void initDebugSerial(u32 bound){ GPIO_InitTypeDef GPIO_InitStruct; USART_InitTypeDef USART_InitStruct; NVIC_InitTypeDef NVIC_InitStruct; //Config Clock 配置时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //Enable Clock:USART1,GPIOA //Config GPIO A9 A10 配置芯片管脚 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStruct);//传入结构GPIO_InitStruct,配置GPIOA GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStruct); //传入结构GPIO_InitStruct,配置GPIOA //Config NVIC 配置中断 NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; //IRQChannel 配置中断通道为USART1_IRQn NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=3 ;//PreemptionPriority 抢占优先级 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3; //SubPriority 子优先级 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //ENABLE IRQChannel 使能中断通道 NVIC_Init(&NVIC_InitStruct); //传入结构体NVIC_InitStruct,配置NVIC //Config USART 配置串口 USART_InitStruct.USART_BaudRate = bound; //bound 波特率 USART_InitStruct.USART_WordLength = USART_WordLength_8b;//WordLength 字长8位 USART_InitStruct.USART_StopBits = USART_StopBits_1;//StopBits 停止位 USART_InitStruct.USART_Parity = USART_Parity_No;//Parity 奇偶校验 USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//HardwareFlowControl USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //USART_Mode 串口模式:收发模式 USART_Init(USART1, &USART_InitStruct); //传入结构体USART_InitStruct,配置串口USART1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能串口中断 USART_Cmd(USART1, ENABLE); //使能串口 }
(2)编写串口接收中断函数。使用数组debugRxBuf[20]保存接收到的数据(每接收到一个8位数据,产生一次中断,运行一次USART1_IRQHandler()函数),全局变量debugRxCount用于计数,同时改变数组debugRxBuf[20]下标值,实现数据从debugRxBuf[0],debugRxBuf[1].....依次保存。
u8 debugRxBuf[20]; u8 debugRxCount=0; void USART1_IRQHandler(void) //串口1中断函数,函数名不可改,已在汇编文件startup_stm32f10x_hd.s 中规定好 { if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到串口数据) { debugRxBuf[debugRxCount] =USART_ReceiveData(USART1); //读取接收到的数据 debugRxCount++;//计数 } }
(3)编写主函数,如下:
//串口收发实验 int main(void) { u8 i; u8 txbuf[10]={0,1,2,3,4,5,6,7,8,9}; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //PriorityGroupConfig NVIC中断分组设置 组2(2位抢占优先级,2位响应优先级) initDebugSerial(500000); //先往串口发送十个数 for(i=0;i<10;i++) { while((USART1->SR&0X40)==0);//等待发送完毕 USART1->DR = txbuf[i]; //填充数据 } while(1) { if(debugRxCount>=10)//接收满10个字节,返回该10个数 { for(i=0;i<10;i++) { txbuf[i]=debugRxBuf[i]; } debugRxCount=0;//重新从debugRxBuf[0]开始填充 for(i=0;i<10;i++) { while((USART1->SR&0X40)==0);//等待发送完毕 USART1->DR = txbuf[i]; //填充数据 } } } }
(4)编译运行。步骤如下:打开sscom串口助手软件,并连接USB转串口模块的端口,sscom串口软件配置如下图。
(5)实验结果:如上图所示,程序运行时,串口首先收到十个HEX十六进制数据。我们在sscom串口助手的数据输入窗口中,编写十个十六进制数,点击发送。然后回收单片机回传的这十个数。
e.实验总结:串口的初始化配置和GPIO配置一样,都有标准流程,我们后续使用串口时,参考该程序就可以了。