STM32
直播中

申换换

7年用户 1474经验值
私信 关注
[问答]

STM32F103单片机串口通信带奇偶校验位的代码分享

STM32F103单片机串口通信带奇偶校验位的代码分享

回帖(1)

潘佼佼

2021-12-3 10:53:44
       在调试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个停止位,偶校验。





串口测试效果如下:





如果串口助手设置和单片机发送不一致时,接收到的数据就为乱码。





源码地址https://download.csdn.net/download/qq_20222919/12921508
举报

更多回帖

发帖
×
20
完善资料,
赚取积分