转载注明出处。

沁恒MCU串口使用指南:

适用于WCH的32位MCU和CH559/558单片机
只描述TTL电平的TX+RX形式的常规串口,流控,RS232、RS485不在文章涉及范围之内。
大部分8位机按照标准的51单片机串口操作,建议自行搜索。


分为两部分,串口接收和串口发送:

一、串口发送:

首先摘抄CH573手册描述(请先仔细阅读一下,说不定就看明白了)

  发送的时候我们肯定希望发送速率越快越好,我们就要充分利用“发送空中断”。因为CPU速度肯定比串口发送速度快,所以总是会存在CPU等待串口发送完成这一情况。

  打个比方,有一辆可以坐8个乘客的小巴士,从公司带人去机场,怎么样最快呢,肯定是每次都坐满发车最快~。那怎么知道司机从机场回来,可以安排下一辆车的人了呢?两种方式:
  1、司机给负责人打电话,喊人下来
  2、负责人蹲公司门口看司机回来了没有,当然不一定要持续盯着,可以每隔几秒抬头看一下

两种通知方式,相比下肯定是第一种省力一点的,所以对应到串口上:
  1、FIFO功能毫无疑问要打开(换成8座小巴士)
  2、每次坐满发车(CPU连续填充8个字节)
  3、通知方式可选中断(打电话通知)或者查询(蹲门口盯着),这个取决于对于串口连续发送的效率要求,中断方式效率会高,但是会增加系统复杂程度(中断优先级、嵌套等问题),查询效率没那么高,但是系统会简洁一点,同时查一下中断标志的开销不大(抬头看一眼,不怎么影响低头刷手机哈哈哈)
  4、通知车回来之后,再安排8个人一起上车,如此循环

代码上上述功能的具体实现(伪代码):
1、

R8_UART1_FCR |= (1<<1);


2、

void UART1_SendString( UINT8 *buf )
{UINT8 i;for(i=0;i<8;i++){R8_UART1_THR = *buf++;   }
}

3+4、
查询

void UART1_SendString( PUINT8 buf )
{UINT8 i;for(i=0;i<8;i++){R8_UART1_THR = *buf++;}
}void main(){R8_UART1_IER |= (1<<1);         //使能串口空中断
while(1){{//cpu干别的事}if(R8_UART1_IIR & (1<<1))   //THR寄存器空UART1_SendString( buf );
}
}

中断

void main(){R8_UART1_IER |= (1<<1);         //使能串口空中断PFIC_EnableIRQ( UART1_IRQn );   //打开串口的中断功能while( 1 );
}__attribute__((interrupt("WCH-Interrupt-fast")))
__attribute__((section(".highcode")))
void UART1_IRQHandler( void )
{if(R8_UART1_IIR & (1<<1))   //THR寄存器空UART1_SendString( buf );
}

二、串口接收

串口的接收整体会麻烦很多,因为是被动的。先摘抄手册描述:(同样先仔细阅读一遍)

串口接收首先是个被动的过程,所以我们尽量的用中断来处理。先看一下和接收相关的中断类型:

  ①接收数据可用:接受的字节数达到FIFO的触发点
  ②接收数据超时:超过4个字节时间未收到下一数据

  这两个中断足以应付绝大部分的场景了。因为串口有8字节的FIFO,进来的数据可以稍微缓冲一下,不至于一有数据就要处理,这会变得挺麻烦的,这点相比标准51单片机来说进步很多。

①接收数据可用中断:

  因为数据有可能连续不断的一直发送过来,我们要及时的读取,但是又不能太及时,不然可能影响CPU处理别的东西。
  打个比方,有个消毒房间,会从天花板上喷消毒水对工作人员进行消毒,这个消毒房间最多只能站8个人,每隔一分钟都会有人要进入消毒房间,单人单次消毒不到1分钟就可以完成,但是每多一个人多喷洒一小会的消毒水,防止出现死角没有喷洒到药水。所以我们有两种模式进行消毒:
  ①每来一个人就进去消毒,下一个人来的时候前一个人已经消毒结束了
  ②等多几个人,然后几个人一起进去消毒,下一个人来的时候几个人一起消毒结束了

  两种方式显然都是可以的,但是会有以下的问题,第一种模式会浪费掉更多的药水,每个人都是100%的药水喷洒量,第二种模式平均到每个人的药水用量会节省不少。但是模式二如果进入人数太多,可能消毒所需要的时间会超过1分钟,导致下一个来的人被堵在门口了。所以第二种模式需要根据规则限制人数,防止后来的人堵在门口。

  对应到串口接收上,串口每接收到一个数据就去处理当然可以,但是会导致CPU开销变大。启用“接收数据可用”中断能够节约CPU开销,但是可能存在CPU还没有读取FIFO中数据,下一个数据就到来的情况。所以可能当FIFO还没有满的时候,CPU就可以去将数据取出来,防止出现阻塞(对于串口来说实际上就是丢数据了),这时候产生“接收数据可用”中断的产生条件“FIFO触发点”就有价值了:

结合串口波特率、CPU频率配置合适的触发点,设置成4字节会比较保险且高效一点。
伪代码如下:

UINT8 flag=0;
UINT8 buf[4];
void main( ){R8_UART1_FCR = (R8_UART1_FCR & ~(3<<6))) | (2<<6); //设置4字节FIFO触发点R8_UART1_IER |= 1;  //使能接收数据可用中断while(1){if(flag){flag = 0;printf("1:%02x\n",buf[0]);printf("2:%02x\n",buf[1]);printf("3:%02x\n",buf[2]);printf("4:%02x\n",buf[3]);}}
}
__attribute__((interrupt("WCH-Interrupt-fast")))
__attribute__((section(".highcode")))
void UART1_IRQHandler( void )
{UINT8 i;if(R8_UART1_IIR & (1<<2)){  //中断源为数据接受可用for(i=0;i<4;i++){buf[i] = R8_UART1_RBR;    //直接按照触发点长度读取若干次RBR寄存器}flag = 1;}}

②接收数据超时中断:

  简单说就是串口空闲了会产生中断,主观上可以认为是一帧结束,配合“数据接收可用”中断。通常数据都是有格式,会有固定长度。假设我们FIFO触发点设置4,数据一帧是14字节,一分钟来一帧数据。我们也有两种方式去接收数据:

  1、只判断“数据接收可用“中断,那么这一帧数据会触发3次中断,成功接收到12字节数据,最后剩下的2字节数据会保存在FIFO中,因为2字节不到触发点,所以CPU并不知道要去取数据。直到1分钟之后下一帧数据到来,新一帧的前2字节和前一帧的2字节凑成4字节,新一帧剩余的12字节正好能凑4的整数倍。这样数据倒是不会丢,但是出现了时效性的问题。

  2、开启“接收数据超时“中断,处理前面的那种情况,第一帧到来之后,先连续触发3次FIFO触发点,CPU取走12字节数据,剩余2字节在FIFO中储存,串口空闲4字节时间(当前波特率连续发送4字节所需要的时间),产生了超时中断,因为知道一帧数据就是14字节,当产生超时中断时,FIFO中必然有2字节数据,此时直接读取两次RBR寄存器就可以将一整帧接收完成,而不用傻傻等一分钟那么久了。伪代码如下:

UINT8 flag1=0;
UINT8 flag2=0;
UINT8 buf[4];
void main( ){R8_UART1_FCR = (R8_UART1_FCR & ~(3<<6))) | (2<<6); //设置4字节FIFO触发点R8_UART1_IER |= 1;  //使能接收数据可用中断while(1){if(flag1){flag1 = 0;printf("1:%02x\n",buf[0]);printf("2:%02x\n",buf[1]);printf("3:%02x\n",buf[2]);printf("4:%02x\n",buf[3]);}if(flag2){flag2 = 0;printf("1:%02x\n",buf[0]);printf("2:%02x\n",buf[1]);}}
}
__attribute__((interrupt("WCH-Interrupt-fast")))
__attribute__((section(".highcode")))
void UART1_IRQHandler( void )
{UINT8 i;switch(R8_UART1_IIR & (3<<2)){  case 0x04;    //中断源为数据接受可用for(i=0;i<4;i++){buf[i] = R8_UART1_RBR;    //直接按照触发点长度读取若干次RBR寄存器}flag1 = 1;break;case 0x0c:    //中断源为超时for(i=0;i<2;i++){buf[i] = R8_UART1_RBR;    //直接按照触发点长度读取若干次RBR寄存器}flag2 = 1;break;}if(R8_UART1_IIR & (3<<2))
}

总结:

  至此一个常规的16C550类串口就能够正常工作起来了,关于FIFO触发点的配置,超时中断的利用,还是要结合串口数据一帧的规律来调整。都看到这里了,其实手册讲的也很挺直白了、、、

`

沁恒MCU串口使用指南相关推荐

  1. 沁恒MCU从EVT中提取文件建立MounRiver独立工程

    沁恒的MCU程序开发包简称EVT,是沁恒官方给出的芯片使用参考例程. EVT开发包为了减少体积,将很多工程的文件复用. 当修改一个公用文件(像link.ld,StdPeriphDriver文件夹中的库 ...

  2. 沁恒RISC-V MCU 为全国大学生智能汽车竞赛加速

    §01 沁恒RISC-V   第十七届(2022年)全国大学生智能汽车竞赛规则已发布,沁恒微电子很荣幸继续为大赛提供赞助.其中多车编队组的头车限定使用沁恒微电子的MCU作为主控,跟随车之一可以选用沁恒 ...

  3. 全国大学生智能车竞赛申请沁恒RISC-V MCU样品说明

      第十六届(2021 年)全国大学生智能汽车竞赛规则已发布,沁恒微电子很荣幸成为大赛的赞助商之一.本次大赛推荐使用的WCH 微控制器CH32V103 为沁恒微电子自主研发的32 位通用RISC-V架 ...

  4. 开源基于涂鸦模组和沁恒RISC-V 架构32位MCU的IOT物联网生活环境监测系统及涂鸦模组使用

    文章目录 前言 一.项目简介 二.硬件介绍 1.硬件原理图 1.1核心板 1.2涂鸦模组 1.3供电电路设计 1.4外设电路 1.4总结 二.涂鸦模块通信协议使用 2.1涂鸦模组协议移植 2.2移植步 ...

  5. 沁恒全方位提供多种USB串口驱动第3代USB转串口产品

    沁恒全方位提供多种USB串口驱动程序供选择,支持Windows/Linux/Android/macOS等操作系统.驱动类型说明: VCP:厂商提供仿真串口驱动,支持各操作系统,功能多,效率高,支持高波 ...

  6. 参加全国大学生智能汽车竞赛,快来申请沁恒RISC-V MCU!

    第十六届(2021年)全国大学生智能汽车竞赛规则已发布,沁恒微电子很荣幸成为大赛的赞助商之一.本次大赛推荐使用的WCH微控制器CH32V103为沁恒微电子自主研发的32位通用RISC-V架构MCU. ...

  7. 【沁恒WCH CH32V307V-R1的单线半双工模式串口通讯】

    [沁恒WCH CH32V307V-R1的单线半双工模式串口通讯] 1. 前言 2. 软件配置 2.1 安装MounRiver Studio 3. UASRT项目测试 3.1 打开UASRT工程 3.2 ...

  8. 国产沁恒CH32F103C8T6使用指南

    国产沁恒CH32F103C8T6使用指南 获取更多内容,请关注微信公众号"电路板上的一抹微笑" 前言: CH32F103芯片是由南京沁恒电子产品公司推出的国产ARM芯片,与STM3 ...

  9. 串口转HID键盘鼠标芯片沁恒微电子CH9329

    概述 沁恒微电子CH9329 是一款串口转标准 USB HID 设备(键盘.鼠标.自定义 HID)芯片,根据不同的工作模式, 在电脑上可被识别为标准的 USB 键盘设备.USB 鼠标设备或自定义 HI ...

  10. 沁恒CH552G实现最小系统[沁恒8位机MCU最小系统]

    转载著名出处. 一.目标: 学习沁恒的8位机最小系统的实现. 最小系统连接方式通用下面所有常规8位MCU 二.资料获取: 1.首先从沁恒官网下载CH552的datasheet: CH552官网手册下载 ...

最新文章

  1. 57 Node.js异步编程
  2. 【转】OGRE资源相关分析
  3. ACL 2016 | CopyNet 和 Pointer Softmax
  4. idea 新建ssm java ee_IDEA搭建SSM项目实现增删改查
  5. Table是怎样炼成的:HtmlTable
  6. 2018年python工作好找吗-2018年最新数据:python、大数据、人工智能从业者薪资表...
  7. OSChina 周四乱弹 —— 电脑上都有监视器
  8. mysql recovery_MySQL Recovery
  9. vs2017下载安装教程
  10. 小程序投标书_程序员接私活常用哪些平台?
  11. 学生党直呼哇塞的几个超好用工具
  12. 幸运的人更幸运 - 节选
  13. 如何修改网卡的默认dns服务器,DNS怎么设置?DNS设置大全
  14. Python3 math模块以及运算优先级
  15. 盘点TMT领域10家国内投资机构
  16. 蚂蚁金服若IPO 信贷业务或将得到长远发展
  17. 11.2NOIP模拟赛
  18. 【愚公系列】2022年02月 微信小程序-Component组件的扩展
  19. 互联网医疗大数据类型的深度分析
  20. Android音频开发(1):音频相关知识

热门文章

  1. Pyhon 登陆邮箱
  2. 百度地图API详解之驾车导航
  3. 不用第三方实现外网访问
  4. Unity VR游戏教程
  5. OI生涯回忆录(Part8:至高一省选Day1)
  6. 萝卜章,电子封条……区块链风口将至?
  7. 如何用Python操作Excel自动化办公?一个案例教会你openpyxl——图表设计和透视表
  8. 免费在线二维DataMatrix码生成器
  9. 菜鸟阿鑫对于一堆数组的总结以及理解
  10. 《汇编语言》学习(十三)int指令