华大单片机HC32L110 HC32F003 HC32F005 UART串口通讯

关注、星标、置顶公众号

目录

  • 前言
  • 数据格式
  • 波特率产生
  • 相关寄存器
  • 相关程序
    • 配置中断相关内容
    • 配置通讯相关内容
    • 配置波特率
    • 串口及接收中断配置
    • 接收中断回调函数
    • 主逻辑
  • UART模式对比
  • 不同配置波特率误差表


前言

华大单片机HC32L110、HC32F003和HC32F005系列MCU有相同的UART通讯模块,因此这三个系列UART模块的使用程序也相同,本文将介绍通过中断的方式进行UART的通讯。


数据格式

此UART模块共有模式0~模式3四种通讯模式,其中模式0为半双工同步通讯模式,此模式为同步模式不在我们今天的讨论范围之内。此模块支持8bit、9bit的数据格式,因此异步通讯的数据格式为:1位起始位,8bit或9bit的数据位,1位结束位。模式1为8bit数据位的全双工异步模式;模式2和模式3为9bit数据位的全双工异步通讯模式。具体如下图:
华大单片机HC32L110 HC32F003 HC32F005 UART串口通讯_第1张图片
由上图可知模式2和模式3中数据多了个TB8位。该位在多机通讯环境下使用时,当 TB8=1,表明所接收的是地址帧;当 TB8=0,表明所接收的是数据帧。当不需要多机通讯时,此位作为奇偶校验位来使用。大家在使用UART模块之前一定要注意确定自己要使用的模式,模式如果选错会直接导致通讯数据出现错误。


波特率产生

异步通讯时波特率有两种产生方式。Mode2为一种方式,Mode1和Mode3为一种方式。
Mode2:
当工作在 Mode2 时,波特率被固定在如下公式所得值:
在这里插入图片描述
其中,UARTx_SCON.DBAUD 表示双倍波特率,Freq 为 PCLK 时钟频率。

Mode1/3:
当工作在 Mode1 或者 Mode3 时,波特率由 TIMER 的溢出时间决定。具体公式如下图
所示:
在这里插入图片描述
其中,UARTx_SCON.DBAUD 表示双倍波特率,Freq 为 PCLK 时钟频率,TM 为TIMER 计数值。注意,TIMER 必须配置为 16 位自动重载入模式,计数寄存器和重载寄存器都得写入 TM 值。UART0对应使用的TIMER是TIM0,UART1对应使用的TIMER是TIM1。对于不同的PCLK产生的不同的波特率误差是有差别的,大家在使用的时候最好先查下误表,看下自己的配置所对应的误差是否在可接受的范围,如果误差不可接受,更改到自己可以接受的误差所对应的配置。不同配置波特率误差表在本文最后。

发送数据
发送数据时,与 UARTx_SCON.REN 的值无关,将所发送数据写入 UARTx_SBUF 寄存器中,数据就会从 TXD 移出(低位在先,高位在后)。

接收数据
接收数据时,需将 UARTx_SCON.REN 位置 1,并将 UARTx_ISR.RI 位清 0。开始接收 RXD 上数据(低位在先,高位在后),当接收完毕,可以从 UARTx_SBUF 寄存器读出。

接收缓存
通用 UART(UART0/1)接收端有一个帧长度(8/9bits)的接收缓存,也就是说当一帧数据接收完毕后,接收缓存中的数据会被一直保持,直到下一帧数据的 Stop 位接收完毕后,接收缓存才会更新为新一帧数据。

发送缓存
通用 UART(UART0/1)发送端不支持发送缓存。如果在发送数据过程中,填写UARTx_SBUF 寄存器,将会破坏当前正在发送数据。软件应该避免这种操作。


相关寄存器

寄存器 符号 描述 说明
UARTx_SBUF 数据寄存器
7:0 SBUF 数据寄存器 发送数据时,待发送数据写入该寄存器;
接收数据时,从该寄存器中读出接收到的数据;
注意,对该寄存器读的值实际是 RxBuffer 中的值,对该寄存器写的值实际是写到了 TXShifter 中。
UARTx_SCON 控制寄存器
9 DBAUD 波特率倍率设置 0:单倍波特率;
1:双倍波特率
7:6 SM01 工作模式配置 00:mode0;01:mode1;
10:mode2;11:mode3
5 SM2 多机通讯使能控制 0:关闭多机通信功能
1:使能多机通信功能
4 REN 接收使能 mode0: 0:发送,1:接收
其他: 0:发送,1:接收/发送
3 TB8 发送数据时待发送的TB8位
2 RB8 接收数据时收到的RB8位
1 TIEN 发送完成中断使能 0:禁止发送完成中断
1:使能发送完成中断
0 RIEN 接收完成中断使能 0:禁止接收完成中断
1:使能接收完成中断
UARTx_ISR 标志位寄存器
2 FE 接收帧错误标志位;硬件置位,软件清零 1:FE中断标志有效
0:FE中断标志无效
1 TI 发送完成中断标志位;硬件置位,软件清零 1:TI中断标志有效
0:TI中断标志无效
0 RI 接收完成中断标志位;硬件置位,软件清零 1:RI中断标志有效
0:RI中断标志无效
UARTx_ICR 中断标志位清除寄存器
2 FECLR 清除接收帧错误标志位 写0清零,写1无效
1 TICLR 清除发送完成中断标志位 写0清零,写1无效
0 RICLR 清除接收完成中断标志位 写0清零,写1无效

相关程序

配置中断相关内容

stcUartIrqCb.pfnRxIrqCb = RxIntCallback; //配置接收中断回调函数
stcUartIrqCb.pfnTxIrqCb = NULL;
stcUartIrqCb.pfnRxErrIrqCb = ErrIntCallback; //配置错误中断回调函数
stcConfig.pstcIrqCb = &stcUartIrqCb; //配置中断服务函数
stcConfig.bTouchNvic = TRUE; //允许中断

配置通讯相关内容

stcConfig.enRunMode = UartMode3; //测试项,更改此处来转换4种模式测试
stcMulti.enMulti_mode = UartNormal; //测试项,更改此处来转换多主机模式,mode2/3才有多主机模//式,此处配置为正常工作模式
stcConfig.pstcMultiMode = &stcMulti; //配置正常或多机工作模式

配置波特率

    stcBaud.bDbaud = 0u;                              //双倍波特率功能
    stcBaud.u32Baud = 9600u;                          //更新波特率位置
    stcBaud.u8Mode = UartMode3;                      //计算波特率需要模式参数
    pclk = Clk_GetPClkFreq();                        //获得PCLK
    timer=Uart_SetBaudRate(UARTCH1,pclk,&stcBaud); //计算波特率所需TIMER值

    stcBtConfig.enMD = BtMode2;                      //自动重装载16位计数器/定时器
    stcBtConfig.enCT = BtTimer;                      //定时模式
    Bt_Init(TIM1, &stcBtConfig);                     //调用basetimer1设置函数产生波特率
    Bt_ARRSet(TIM1,timer);                            //配置重载值
    Bt_Cnt16Set(TIM1,timer);                          //配置计数值
    Bt_Run(TIM1);                                      //启动定时

串口及接收中断配置

    Uart_Init(UARTCH1, &stcConfig);                //串口1初始化
    Uart_EnableIrq(UARTCH1,UartRxIrq);             //允许串口1接收中断
    Uart_ClrStatus(UARTCH1,UartRxFull);            //清串口1接收中断标志
    Uart_EnableFunc(UARTCH1,UartRx);               //串口1接收中断使能

接收中断回调函数

void RxIntCallback(void)
{
    u8RxData[1]=M0P_UART1->SBUF;                    //取出接收数据
    u8RxFlg = 1;                                      //接收标志置1
}

主逻辑

while(1)
{
    CheckFlg = 0;                                           //校验出错标志清零
    if(u8RxFlg)                                             //有接收数据进入,无数据跳过
    {
        u8RxFlg = 0;                                        //接收标志清零
        if(Uart_CheckEvenOrOdd(UARTCH1,Even,u8RxData[1])!=Ok)   //检查偶检验是否成功
        {
            CheckFlg = 1;                                          //偶校验出错
        }
        else
        {
            Uart_SetTb8(UARTCH1,Even,u8RxData[0]);             //根据数据设置TB8位
            Uart_SendData(UARTCH1,u8RxData[0]);               //发送数据
            Uart_SetTb8(UARTCH1,Even,u8RxData[1]);
            Uart_SendData(UARTCH1,u8RxData[1]);
        }
    }
}

UART模式对比

好多朋友在使用UART的时候因为没有掌握4种模式的差别,所示调试的时候总是接收数据不对,走了很多弯路,现在就把不同种的差别总结一下。
半双工同步模式
Mode0 波特率为固定的 PCLK 时钟的 1/12。不常用。
全双工异步模式
Mode1 数据位8位,不带检验位,不带多机通讯功能,波特率由TIMER产生,常用;
Mode2 数据位9位,带检验位,带多机通讯功能,波特率为与PCLK有关的固定值,不常用;
Mode3 数据位9位,带检验位,带多机通讯功能,波特率由TIMER产生,常用。
不同模式的总结可以参考下表:
华大单片机HC32L110 HC32F003 HC32F005 UART串口通讯_第2张图片


不同配置波特率误差表

华大单片机HC32L110 HC32F003 HC32F005 UART串口通讯_第3张图片
华大单片机HC32L110 HC32F003 HC32F005 UART串口通讯_第4张图片
华大单片机HC32L110 HC32F003 HC32F005 UART串口通讯_第5张图片
华大单片机HC32L110 HC32F003 HC32F005 UART串口通讯_第6张图片
华大单片机HC32L110 HC32F003 HC32F005 UART串口通讯_第7张图片
华大单片机HC32L110 HC32F003 HC32F005 UART串口通讯_第8张图片
华大单片机HC32L110 HC32F003 HC32F005 UART串口通讯_第9张图片
华大单片机HC32L110 HC32F003 HC32F005 UART串口通讯_第10张图片
华大单片机HC32L110 HC32F003 HC32F005 UART串口通讯_第11张图片
华大单片机HC32L110 HC32F003 HC32F005 UART串口通讯_第12张图片
华大单片机HC32L110 HC32F003 HC32F005 UART串口通讯_第13张图片
华大单片机HC32L110 HC32F003 HC32F005 UART串口通讯_第14张图片


关注微信公众号『芯缘意码』,查看更多内容,回复“加群”加入技术交流群。
淘宝 店铺 搜索 『芯缘意码』,购买开发学习板仿真器。
公众号:芯缘意码https://shop219666036.taobao.com


你可能感兴趣的:(华大单片机教程)