在调试Modubus协议时需要用到串口的奇偶校验位,但是平时用串口时很少用到奇偶校验位,网上搜相关的历程也很少,将自己写的串口奇偶校验代码分享上来方便以后查阅。
如果用库函数的话,添加奇偶检验位就很简单,在初始化串口的时候,将默认的无校验位修改为奇校验或者偶校验,同时将数据位设置为9位。
串口初始化代码如下:
- #include "uart2.h"
- #define CHECK_NONE_ONE_STOP 0 //无校验位 1个停止位 1有效 0 无效
- #define CHECK_NONE_TWO_STOP 1 //无校验位 2个停止位 1有效 0 无效
- #define CHECK_EVEN 1 //偶数校验 1有效 0 无效
- #define CHECK_ODD 0 //奇数校验 1有效 0 无效
- void uart2_init( u32 baud )
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- USART_InitTypeDef USART_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );
- RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART2, ENABLE );
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init( GPIOA, &GPIO_InitStructure );
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init( GPIOA, &GPIO_InitStructure );
- NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init( &NVIC_InitStructure );
- USART_InitStructure.USART_BaudRate = baud;
- USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位
- USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位
- USART_InitStructure.USART_StopBits = USART_StopBits_1; //1位停止位
- #if(CHECK_EVEN == 1) //如果定义了偶校验 数据位长度要改为9位
- USART_InitStructure.USART_WordLength = USART_WordLength_9b;
- USART_InitStructure.USART_Parity = USART_Parity_Even;
- #endif
- #if(CHECK_ODD == 1) //如果定义了偶校验 数据位长度要改为9位
- USART_InitStructure.USART_WordLength = USART_WordLength_9b;
- USART_InitStructure.USART_Parity = USART_Parity_Odd;
- #endif
- #if(CHECK_NONE_ONE_STOP==1) //停止位为 一位
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- #endif
- #if(CHECK_NONE_TWO_STOP==1) //停止位为 两位
- USART_InitStructure.USART_StopBits = USART_StopBits_2;
- #endif
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_Init( USART2, &USART_InitStructure );
- USART_ITConfig( USART2, USART_IT_RXNE, ENABLE );
- USART_Cmd( USART2, ENABLE );
- }
- void USART2_IRQHandler( void )
- {
- u16 tem = 0;
- if( USART_GetITStatus( USART2, USART_IT_RXNE ) != RESET )
- {
- tem = USART_ReceiveData( USART2 );
- USART_SendData( USART2, tem );
- }
- }
复制代码
通过宏定义来设置是否使用奇偶校验位,停止位为1位还是2位。如果使用了奇偶校验时,要将数据位设置为9位。设置好之后就不用管了,具体校验工作由硬件来完成。
在串口中断函数中实现的功能是,将串口2接收到的数据通过串口2发送出去。
在宏定义中设置为2个停止位,偶校验。
串口测试效果如下:
如果串口助手设置和单片机发送不一致时,接收到的数据就为乱码。
|