查看: 1316|回复: 0
收起左侧

第九十二章:CH32V103应用教程——USART-奇偶校验

[复制链接]

  离线 

  • TA的每日心情
    慵懒
    2021-7-23 17:16
  • 签到天数: 17 天

    [LV.4]

    发表于 2021-6-10 20:02:38 | 显示全部楼层 |阅读模式

    有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    本帖最后由 草帽王子 于 2021-9-10 18:27 编辑

    本章教程使用串口1(USART1)进行串口通信过程中的奇偶校验。

    1、USART校验控制简介

    通过设置USART控制寄存器1(USARTx_CTLR1)的位10 PCE位使能开启奇偶校验,具体解释如下图:
    CH32V CH573单片机芯片-第九十二章:CH32V103应用教程——USART-奇偶校验risc-v单片机中文社区(1)

    奇偶校验分为奇校验和偶校验,具体解释如下:
    • 奇校验:此校验位使得一帧中的7或8个LSB数据以及校验位中’1’的个数为奇数。例如:数据=00110101,有4个’1’,如果选择奇校验(在USART_CR1中的PS= 1),校验位将是’1’。
    • 偶校验:校验位使得一帧中的7或8个LSB数据以及校验位中’1’的个数为偶数。例如:数据=00110101,有4个’1’,如果选择偶校验(在USART_CR1中的PS= 0),校验位将是’0’。
    • 关于CH32V103 USART具体信息,可参考CH32V103应用手册。USART标准库函数在第三章节已介绍,在此不再赘述。


    2、硬件设计

    本章教程使用串口1(USART1)进行串口通信并进行奇偶校验,具体连接方式如下:
    硬件连线:
          PA9 —— WCH-Link RX引脚
          PA10 —— WCH-Link TX引脚


    3、软件设计

    本章教程在第三章的基础上进行,串口改为选用串口1,串口奇偶校验具体程序如下:
    usart.h文件
    1. /*
    2. * usart.h
    3. *
    4. *  Created on: May 20, 2021
    5. *      Author: OWNER
    6. */

    7. #ifndef USART_H_
    8. #define USART_H_

    9. #include "ch32v10x_conf.h"

    10. #define  CHECK_NONE_ONE_STOP    1 //无校验位  1个停止位  1有效  0 无效
    11. #define  CHECK_NONE_TWO_STOP    0 //无校验位  2个停止位  1有效  0 无效
    12. #define  CHECK_EVEN    0          //偶数校验   1有效  0 无效
    13. #define  CHECK_ODD     1          //奇数校验   1有效  0 无效

    14. void USARTx_CFG(void);
    15. void USARTx_SendByte(USART_TypeDef* pUSARTx, uint8_t data);
    16. void USARTx_SendStr(USART_TypeDef* pUSARTx, char *str);
    17. void USART1_IRQHandler(void);

    18. #endif /* USART_H_ */
    复制代码
    usart.h文件主要进行相关宏定义和函数声明;
    usart.c文件
    1. /*
    2. * usart.c
    3. *
    4. *  Created on: May 20, 2021
    5. *      Author: OWNER
    6. */
    7. #include "usart.h"

    8. void USART1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

    9. /*******************************************************************************
    10. * Function Name  : USARTx_CFG
    11. * Description    : Initializes the USART2 & USART3 peripheral.
    12. * Input          : None
    13. * Return         : None
    14. *******************************************************************************/
    15. void USARTx_CFG(void)
    16. {
    17.     GPIO_InitTypeDef  GPIO_InitStructure;
    18.     USART_InitTypeDef USART_InitStructure;
    19.     NVIC_InitTypeDef  NVIC_InitStructure;

    20.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);
    21.     //RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

    22.   /* USART1 TX-->A.9   RX-->A.10 */
    23.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    24.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    25.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    26.     GPIO_Init(GPIOA, &GPIO_InitStructure);
    27.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    28.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    29.     GPIO_Init(GPIOA, &GPIO_InitStructure);

    30.     USART_InitStructure.USART_BaudRate = 115200;
    31. //  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    32. //  USART_InitStructure.USART_StopBits = USART_StopBits_1;
    33. //  USART_InitStructure.USART_Parity = USART_Parity_No;
    34.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    35.     USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;

    36. #if(CHECK_EVEN == 1)                                                                                            //如果定义了偶校验  数据位长度要改为9位
    37.     USART_InitStructure.USART_WordLength = USART_WordLength_9b;
    38.     USART_InitStructure.USART_Parity = USART_Parity_Even;
    39. #endif

    40. #if(CHECK_ODD == 1)                                                                                             //如果定义了奇校验  数据位长度要改为9位
    41.     USART_InitStructure.USART_WordLength = USART_WordLength_9b;
    42.     USART_InitStructure.USART_Parity = USART_Parity_Odd;
    43. #endif

    44. #if(CHECK_NONE_ONE_STOP==1)                                                                             //停止位为 一位
    45.     USART_InitStructure.USART_StopBits = USART_StopBits_1;
    46. #endif

    47. #if(CHECK_NONE_TWO_STOP==1)                                                                             //停止位为 两位
    48.     USART_InitStructure.USART_StopBits = USART_StopBits_2;
    49. #endif

    50.     USART_Init(USART1, &USART_InitStructure);

    51.     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    52.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
    53.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    54.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    55.     NVIC_Init(&NVIC_InitStructure);

    56.     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    57.     USART_Cmd(USART1, ENABLE);
    58. }

    59. void USARTx_SendByte(USART_TypeDef* pUSARTx, uint8_t data)
    60. {
    61.     USART_SendData(pUSARTx, data);
    62.     while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
    63. }

    64. void USARTx_SendStr(USART_TypeDef* pUSARTx, char *str)
    65. {
    66.     uint8_t i = 0;
    67.     do
    68.     {
    69.        USARTx_SendByte(pUSARTx, *(str+i));
    70.        i++;
    71.     }while(*(str+i) != '\0');
    72.     while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET);
    73. }


    74. /*******************************************************************************
    75. * Function Name  : USART2_IRQHandler
    76. * Description    : This function handles USART2 global interrupt request.
    77. * Input          : None
    78. * Return         : None
    79. *******************************************************************************/
    80. void USART1_IRQHandler(void)
    81. {
    82.     u16 tem = 0;

    83.     if( (USART_GetITStatus( USART1, USART_IT_RXNE ) != RESET) &&(USART_GetFlagStatus( USART1, USART_FLAG_RXNE ) != RESET) )
    84.     {
    85.         USART_ClearITPendingBit(USART1,USART_IT_RXNE);    //清除中断标志
    86.         USART_ClearFlag(USART1, USART_FLAG_RXNE);

    87.         if( (USART_GetFlagStatus( USART1, USART_FLAG_PE ) == RESET) )
    88.         {
    89.             tem = USART_ReceiveData( USART1 );
    90.             USART_SendData( USART1, tem );
    91.         }
    92.         else
    93.         {
    94.             USARTx_SendStr(USART1, "error.\n");
    95.         }
    96.     }
    97.     USART_GetFlagStatus( USART1, USART_FLAG_PE);
    98.     USART_ReceiveData( USART1 );
    99. }
    复制代码

    usart.c文件主要进行串口奇偶校验的初始化配置以及中断服务函数中对奇偶校验的判断处理。在进行串口初始化的时候,注意要设置对应的奇偶校验,并且要将数据位长度改为9位,此处设置为奇校验。此外,还需要注意的是,串口状态寄存器在先读出USART_STATR,再读出USART_DATAR寄存器后,所有的状态位被清除,即RXNE和PE位也会被清零,所以在判断奇偶标志位错误的时候,应该在读取DR寄存器之前判断,从而判别奇偶校验的正确,具体见下图。
    CH32V CH573单片机芯片-第九十二章:CH32V103应用教程——USART-奇偶校验risc-v单片机中文社区(2)

    main.c文件
    1. /********************************** (C) COPYRIGHT *******************************
    2. * File Name          : main.c
    3. * Author             : WCH
    4. * Version            : V1.0.0
    5. * Date               : 2020/04/30
    6. * Description        : Main program body.
    7. *******************************************************************************/

    8. #include "debug.h"
    9. #include "usart.h"

    10. /*******************************************************************************
    11. * Function Name  : main
    12. * Description    : Main program.
    13. * Input          : None
    14. * Return         : None
    15. *******************************************************************************/
    16. int main(void)
    17. {
    18.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    19.     USARTx_CFG();                                                  /* USART1 INIT */
    20.     USARTx_SendStr(USART1, "This is a test data.\n");
    21.     while(1)
    22.     {
    23.     }
    24. }
    复制代码
    main.c文件主要进行函数初始化。


    4、下载验证

    将编译好的程序下载到开发版并复位,串口打印如下:
    CH32V CH573单片机芯片-第九十二章:CH32V103应用教程——USART-奇偶校验risc-v单片机中文社区(3)
    程序中配置为奇校验,将串口调试工具设置为奇校验,通信正常,具体如下:
    CH32V CH573单片机芯片-第九十二章:CH32V103应用教程——USART-奇偶校验risc-v单片机中文社区(4)
    若串口调试工具配置为偶校验或无校验,通信错误,返回error,具体如下:
    CH32V CH573单片机芯片-第九十二章:CH32V103应用教程——USART-奇偶校验risc-v单片机中文社区(5)

    CH32V USART-奇偶校验.rar
    CH32V CH573单片机芯片-第九十二章:CH32V103应用教程——USART-奇偶校验risc-v单片机中文社区(6) CH32V USART-奇偶校验.rar (441.87 KB, 下载次数: 11)
    链接:https://pan.baidu.com/s/1M2EChRWHRPeDI0D52kqWJg
    提取码:1y2x
    复制这段内容后打开百度网盘手机App,操作更方便哦







    上一篇:拓展补充帖:F103到V103移植说明
    下一篇:第九十三章、CH32V103应用教程——PWM播放音乐(1个TIM)
    RISCV作者优文
    全球首家只专注于RISC-V单片机行业应用的中文网站
    回复

    使用道具 举报

    高级模式
    B Color Image Link Quote Code Smilies

    本版积分规则

    关闭

    RISC-V单片机中文网上一条 /2 下一条



    版权及免责声明|RISC-V单片机中文网 |网站地图

    GMT+8, 2024-11-26 09:48 , Processed in 0.270898 second(s), 47 queries .

    快速回复 返回顶部 返回列表