完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
笔者将讲解STM32与外部设备通过串口通信的方式。
所谓串口通信,其实是一个类似于计算机网络的概念,它有物理层,比如规定用什么线通信,几伏特算高电平,几伏特算低电平。传输层,通信前要发RTS,CTS。每一层都有不同的协议所约束。在STM32中采用的USART就是其中之一。 USART模块由GPIO_InitTypeDef结构体控制,它的定义如下 typedef struct { u32 USART_BaudRate; // 波特率 u16 USART_WordLength; // 字长 u16 USART_StopBits; // 停止位 u16 USART_Parity; // 校验位 u16 USART_Mode; // USART 模式 u16 USART_HardwareFlowControl; // 硬件流控制 } USART_InitTypeDef; 外部设备的输入输出分别使用GPIOA的9号和10号管脚,因此我们要先把管脚输入输出模式配置好 GPIO_InitTypeDef GPIO_USART_INIT; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_USART_INIT.GPIO_Pin = GPIO_Pin_9; GPIO_USART_INIT.GPIO_Speed = GPIO_Speed_50MHz; //最高输出速率 50MHz GPIO_USART_INIT.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA,&GPIO_USART_INIT); GPIO_USART_INIT.GPIO_Pin = GPIO_Pin_10; GPIO_USART_INIT.GPIO_Speed = GPIO_Speed_50MHz; //最高输出速率 50MHz GPIO_USART_INIT.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入 GPIO_Init(GPIOA,&GPIO_USART_INIT); 然后我们设置USART,将波特率设置为9600,禁用硬件流控制模式,工作模式允许发送和接收,不设置校验位,数据位为8比特,在帧尾传输1个停止位。 USART_InitTypeDef USART_INIT; USART_INIT.USART_BaudRate = 9600; USART_INIT.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制失能 USART_INIT.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; //接收/发送使能 USART_INIT.USART_Parity = USART_Parity_No; //奇偶失能 USART_INIT.USART_StopBits = USART_StopBits_1; //在帧结尾传输 1 个停止位 USART_INIT.USART_WordLength = USART_WordLength_8b; USART_Init(USART1,&USART_INIT); USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); 当然,处理器不可能时时刻刻检查串口有没有信息传来,因此我们刚刚学习的中断就派上了用场,如果串口传输了信息,那么则请求中断并进行处理。 NVIC_InitTypeDef NVIC_USART_INIT; NVIC_USART_INIT.NVIC_IRQChannel = USART1_IRQn; NVIC_USART_INIT.NVIC_IRQChannelPreemptionPriority = 2; NVIC_USART_INIT.NVIC_IRQChannelSubPriority = 1; NVIC_USART_INIT.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_USART_INIT); USART_Cmd(USART1,ENABLE); 中断回调函数,负责接收信息 u8 RXData; void USART1_IRQHandler() { if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET) { RXData = USART_ReceiveData(USART1); } USART_ClearITPendingBit(USART1,USART_IT_RXNE|USART_IT_TXE); } 依然采取防御式编程,只有确信是被中断调用时才进行消息接收,比较坑的一点在于,回调函数的返回值被写死成void类型了,所以必须定义一个外部变量,进行接收值的传输。 输出函数,注意需要等待,直到信息发送完成的flag被设置。 void USART1_SData(u8 Data) { USART_SendData(USART1,Data); while(!USART_GetFlagStatus(USART1,USART_FLAG_TC)); USART_ClearFlag(USART1,USART_FLAG_TC); } #ifndef _USART_H #define _USART_H #include void usart_configer(); void USART1_SData(u8 Data); void USART1_IRQHandler(); extern u8 RXData; #endif //usart.h #include void usart_configer() { GPIO_InitTypeDef GPIO_USART_INIT; USART_InitTypeDef USART_INIT; NVIC_InitTypeDef NVIC_USART_INIT; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); GPIO_USART_INIT.GPIO_Pin = GPIO_Pin_9; GPIO_USART_INIT.GPIO_Speed = GPIO_Speed_50MHz; GPIO_USART_INIT.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA,&GPIO_USART_INIT); GPIO_USART_INIT.GPIO_Pin = GPIO_Pin_10; GPIO_USART_INIT.GPIO_Speed = GPIO_Speed_50MHz; GPIO_USART_INIT.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA,&GPIO_USART_INIT); //有些参数和串口助手上设置的比较 USART_INIT.USART_BaudRate = 9600; USART_INIT.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_INIT.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; USART_INIT.USART_Parity = USART_Parity_No;//奇偶模式,不设置奇偶 USART_INIT.USART_StopBits = USART_StopBits_1;//停止位 USART_INIT.USART_WordLength = USART_WordLength_8b;//数据位 USART_Init(USART1,&USART_INIT); USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//接收中断 NVIC_USART_INIT.NVIC_IRQChannel = USART1_IRQn; NVIC_USART_INIT.NVIC_IRQChannelPreemptionPriority = 2; NVIC_USART_INIT.NVIC_IRQChannelSubPriority = 1; NVIC_USART_INIT.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_USART_INIT); USART_Cmd(USART1,ENABLE); } void USART1_SData(u8 Data) { USART_SendData(USART1,Data); //USART_SendData(USART1,(u8)USART_GetFlagStatus(USART1,USART_IT_TC)); while(!USART_GetFlagStatus(USART1,USART_FLAG_TC));//等待发送完毕 USART_ClearFlag(USART1,USART_FLAG_TC);//清除标志位 } u8 RXData; void USART1_IRQHandler()//接收 { if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)//判断是否真的是接收中断 每次接收1byte { RXData = USART_ReceiveData(USART1); } USART_ClearITPendingBit(USART1,USART_IT_RXNE|USART_IT_TXE);//清空中断源(接收中断和发送中断) } //usart.c 下面我们进行几个串口通信的实际应用。 实验一:发信实验,让开发板通过串口向电脑发送信息: #include #include #include #include #include #include #include int main() { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); led_configer(); button_configer(); usart_configer(); while(1) { USART1_SData(0x66); } } //main.c 实验二:电脑向串口发送0x55时,开灯,电脑向串口发送0x66时,关灯。 #include #include #include #include #include #include #include int main() { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); led_configer(); button_configer(); usart_configer(); while(1) { if(RXData==0x55) lightup(GPIO_Pin_1); else if(RXData==0x66) shutdown(GPIO_Pin_1); } } //main.c |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1584 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1526 浏览 1 评论
958 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
672 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1567 浏览 2 评论
1852浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
623浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
508浏览 3评论
518浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
494浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-15 16:26 , Processed in 0.896762 second(s), Total 77, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号