完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
最近,在做基于stm32f401串口的ModBus协议通信,遇到了stm32串口发送数据的问题。花了一整天去查找问题,从ModBus协议格式、调度算法到串口配置,最终终于把问题解决,记录下来。
问题描述: ModBus协议中配置stm32f401串口为奇校验,8位数据位,1位停止位,程序如下: 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_StopBits = USART_StopBits_1;//一个停止位 #ifdef EN_FREE_MODBUS //支持ModBus USART_InitStructure.USART_Parity = USART_Parity_Even ;//奇校验,与freeModbus中设置一致 #else USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位 #endif USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式 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 } 采用串口助手接收Modbus发送来的数据,最高位基本都是出错的,有的本来是1收到的是0,有的本来是0收到的是1,只有极少数数据正确。通过分析Modbus协议,未发现问题;串口助手配置也没有问题。最后在网上查到的解决办法,并仔细阅读了stm32的datasheet,有如下表述: M位PCE位 USART帧 0 0 | 起始位 | 8位数据|停止位 | 0 1 | 起始位 | 7位数据|奇偶检验位 | 停止位 | 1 0 | 起始位 | 9位数据 | 停止位 | 1 1 | 起始位 | 8位数据 | 奇偶检验位 | 停止位 | 其中,M位为1代表UART库函数中设置为9位数据,M位为0代表设置为8位数据;PCE位为1代表有奇偶校验,为0代表无校验。可以看出,stm32在设置奇偶校验后将校验位算到了数据位里。因此,在ModBus设置为奇校验后,为了保证数据为8位,需要设置数据位长度为9,即将数据位数设置语句改为下面即可: /*STM32中,设置的数据长度包含校验位。 若设置了奇校验或偶校验,则校验位会占1位。这时要想数据为8位(一般的串口助手直接设置为8位),下面的字长需要设为9位。 若没有设置奇偶校验,则直接设为8位即可。*/ if( USART_InitStructure.USART_Parity == USART_Parity_No ) { USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式 } else { USART_InitStructure.USART_WordLength = USART_WordLength_9b;//字长为9位数据格式 } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1884 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1663 浏览 1 评论
1149 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
763 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1720 浏览 2 评论
1964浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
790浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
614浏览 3评论
631浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
593浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-13 20:50 , Processed in 0.706695 second(s), Total 41, Slave 35 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号