CH582m串口透传程序
参考了沁恒官网22年1月更新的CH583EVT包中的UART1例程
功能:上位机通过串口1发送指令规定串口2和3的波特率,实现串口2和3之间的数据透传
担心串口3的接收中断会被串口2的发送中断打断而导致错误,故不采用在串口3的接收中断中,立即于串口2转发的方式(即串口3的中断服务函数中注释掉的两句),而采用缓存串口3接收的数据,在主函数中转发的方式。
实测串口2和3全部采用中断收发不缓存数据,不会影响串口透传。全部用中断收发,可以减小串口3的缓存,但是在中断使用较多的情况下可能会出问题。代码相似度很高,就不贴了。
#include "CH58x_common.h" uint8_t RxBuff1[50];
uint8_t u1_i = 0; //用于判断字符长度
uint8_t RxBuff2[50];
uint8_t RxBuff3[100]; //串口3的接收缓存,串口2向串口3透传的数据不能溢出该数组
uint8_t trigB = 4; //FIFO的触发字节数,可以设置00b,01b,10b,11b。本程序中用了10b,这里直接赋了4
uint8_t RxBuff1_get = 0; //判断串口1是否接收完了一串字符,在串口1中断中的FIFO超时判断中置1
uint8_t u3_get_flag = 0; //判断串口3是否接收完一串字符串,在串口3中断中的FIFO超时判断中置1
uint8_t baud_get = 0; //判断是否接收到了串口1收到的波特率信息,格式 baud:XXXXX (9600/57600/115200等)
uint8_t u1_get[13] = {}; //接收存放串口1收到的波特率信息,方便仿真观察
uint8_t u3_i = 0; //记录串口3接收到的字节数,以便后续转发
uint32_t baud_num = 0; //存放波特率,用于初始化u2u3的函数 void u1_init()
{
uint32_t x; /* 配置串口1:先配置IO口模式,再配置串口 */
GPIOA_SetBits(GPIO_Pin_9); //先将PA9置位为高
GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU); // RXD-配置上拉输入
GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA); // TXD-配置推挽输出,注意要先让IO口输出高电平 x = 10 * GetSysClock() / 8 / 115200; //串口1定为115200波特率
x = (x + 5) / 10; //整型运算中四舍五入
R16_UART1_DL = (uint16_t)x; //给波特率寄存器赋值 R8_UART1_FCR = (2 << 6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN;
//FIFO控制寄存器配置,10左移6位:触发点4字节;收发FIFO数据都清空;FIFO使能
R8_UART1_LCR = RB_LCR_WORD_SZ; //线路控制寄存器配置,选择串口数据长度
R8_UART1_IER = RB_IER_TXD_EN | RB_IER_RECV_RDY | RB_IER_LINE_STAT; //中断使能控制器配置,TX引脚输出使能;接收中断使能;接收线路状态中断使能
R8_UART1_MCR |= RB_MCR_INT_OE; //调制解调器控制寄存器配置,允许串口的中断请求输出
R8_UART1_DIV = 1; //用于波特率配置,参考手册中的公式 PFIC_EnableIRQ(UART1_IRQn); //中断注册 UART1_SendByte('O');
UART1_SendByte('K');
} void u2u3_init(uint32_t btl) //波特率数字较大时需要用32位的整型存放,比如115200
{
uint32_t x; /* 配置串口2、3的IO口模式 */
GPIOA_SetBits(GPIO_Pin_7);
GPIOA_ModeCfg(GPIO_Pin_6, GPIO_ModeIN_PU);
GPIOA_ModeCfg(GPIO_Pin_7, GPIO_ModeOut_PP_5mA);
GPIOA_SetBits(GPIO_Pin_5);
GPIOA_ModeCfg(GPIO_Pin_4, GPIO_ModeIN_PU);
GPIOA_ModeCfg(GPIO_Pin_5, GPIO_ModeOut_PP_5mA); x = 10 * GetSysClock() / 8 / btl;
x = (x + 5) / 10;
R16_UART2_DL = (uint16_t)x;
R16_UART3_DL = (uint16_t)x; //寄存器为16位的 R8_UART2_FCR = (2 << 6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN;
R8_UART2_LCR = RB_LCR_WORD_SZ;
R8_UART2_IER = RB_IER_TXD_EN | RB_IER_RECV_RDY | RB_IER_LINE_STAT;
R8_UART2_MCR |= RB_MCR_INT_OE;
R8_UART2_DIV = 1; R8_UART3_FCR = (2 << 6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN;
R8_UART3_LCR = RB_LCR_WORD_SZ;
R8_UART3_IER = RB_IER_TXD_EN | RB_IER_RECV_RDY | RB_IER_LINE_STAT;
R8_UART3_MCR |= RB_MCR_INT_OE;
R8_UART3_DIV = 1; PFIC_EnableIRQ(UART2_IRQn);
PFIC_EnableIRQ(UART3_IRQn); baud_get = 1; //波特率已由串口1获得的标识 UART2_SendByte('O');
UART2_SendByte('K');
UART3_SendByte('O');
UART3_SendByte('K');
} void main()
{
uint8_t i,j; SetSysClock(CLK_SOURCE_PLL_60MHz);
u1_init(); //串口1默认115200波特率 while(!RxBuff1_get)
__nop(); //等待串口1接收指令。串口1接收到一串数据之后,开始处理数据
while(RxBuff1_get)
{
for(i=0; i<u1_i; i++)
{
j = R8_UART1_TFC; //查询 发FIFO计数寄存器的数值,数据过多时不发送数据给FIFO
while(j > 4)
{
j = R8_UART1_TFC; //再读取一遍,等待FIFO有空间存放即将发送的数据。发送数据过快将导致与波特率不匹配而乱码
}
UART1_SendByte(RxBuff1[i]); //反馈上位机
u1_get[i] = RxBuff1[i]; //将RxBuff1中的指令搬到u1_get中,方便仿真观察
}
RxBuff1_get = 0;
} baud_num = u1_get[5]-'0'; //将"baud:"之后的字符转换为数字
for (i=6; i<u1_i; i++)
{
baud_num = baud_num *10;
baud_num += u1_get[i]-'0';
} u2u3_init(baud_num); //初始化u2u3 while(baud_get) //获得波特率,并且u2u3初始化完成之后
{
__nop();
while(u3_get_flag)
{
for(i=0; i<u3_i; i++)
{
j = R8_UART2_TFC; //查询 发FIFO计数寄存器的数值,还有数据时不发送
while(j) //作用和上面判断FIFO数据是否过多类似,_TFC寄存器中的值最多为8,不让FIFO溢出即可
j = R8_UART2_TFC;
UART2_SendByte(RxBuff3[i]); //串口3收到的数据从串口2发出
}
if(i == u3_i)
{
u3_i = 0; //RxBuff3的数组指针归零
u3_get_flag = 0; //清空串口3接收到数据的标志
}
}
}
} __INTERRUPT //硬件压栈
__HIGH_CODE //放在ram里跑,更快
void UART1_IRQHandler(void)
{
volatile uint8_t i; switch(R8_UART1_IIR & RB_IIR_INT_MASK) //获取中断标志
{
case UART_II_LINE_STAT: // 线路状态错误
{
UART1_GetLinSTA(); //读取线路状态寄存器,读取该寄存器将自动清除中断
break;
} case UART_II_RECV_RDY: // 数据达到设置触发点
for(i = 0; i != trigB-1; i++)
{
RxBuff1[u1_i] = UART1_RecvByte();
u1_i++;
}
break; case UART_II_RECV_TOUT: // 接收超时,暂时一帧数据接收完成。注意FIFO里要留有至少一个字符用来比较,判断超时
i = UART1_RecvString(RxBuff1+u1_i);
u1_i += i;
RxBuff1_get = 1;
break; case UART_II_THR_EMPTY: // 发送缓存区空,可继续发送
break; default:
break;
}
} __INTERRUPT //硬件压栈
__HIGH_CODE //下方程序放在ram里跑,更快
void UART2_IRQHandler(void)
{
volatile uint8_t i; switch(R8_UART2_IIR & RB_IIR_INT_MASK) //获取中断标志
{
case UART_II_LINE_STAT: // 线路状态错误
{
UART2_GetLinSTA(); //读取线路状态寄存器,读取该寄存器将自动清除中断
break;
} case UART_II_RECV_RDY: // 数据达到设置触发点
for(i = 0; i != trigB; i++)
{
RxBuff2[i] = UART2_RecvByte();
UART3_SendByte(RxBuff2[i]); //从串口3转发出去
}
break; case UART_II_RECV_TOUT: // 接收超时,暂时一帧数据接收完成
i = UART2_RecvString(RxBuff2);
UART3_SendString(RxBuff2, i);
break; case UART_II_THR_EMPTY: // 发送缓存区空,可继续发送
break; default:
break;
}
} __INTERRUPT //硬件压栈
__HIGH_CODE //放在ram里跑,更快
void UART3_IRQHandler(void)
{
volatile uint8_t i;
switch(R8_UART3_IIR & RB_IIR_INT_MASK) //获取中断标志
{
case UART_II_LINE_STAT: //线路状态错误
{
UART3_GetLinSTA(); //读取线路状态寄存器,读取该寄存器将自动清除中断
break;
} case UART_II_RECV_RDY: // 数据达到设置触发点
for(i = 0; i != trigB-1; i++) //FIFO中留一个字节的数据,用于触发_TOUT标识
{
RxBuff3[u3_i++] = UART3_RecvByte();
//UART2_SendByte(RxBuff3[i]); //先不从串口2转发,防止串口2的发送中断打断串口3的中断服务函数
}
break; case UART_II_RECV_TOUT: // 接收超时,暂时一帧数据接收完成
i = UART3_RecvString(RxBuff3+u3_i);
u3_i += i;
//UART2_SendString(RxBuff3, i); //先不从串口2转发,防止串口2的发送中断打断串口3的中断服务函数
u3_get_flag = 1;
break; case UART_II_THR_EMPTY: // 发送缓存区空,可继续发送
break; default:
break;
}
}
CH582m串口透传程序的更多相关文章
- CC1101 433无线模块,STM8串口透传
CC1101 433无线模块,STM8串口透传 原理图:http://download.csdn.net/detail/cp1300/7496509 下面是STM8程序 CC1101.C /*** ...
- tcp与串口透传(select)
介绍 tcp作为服务端,监听端口8888,实现串口透传,这里是使用select监听tcp的receive和串口的read,单工通信 -p 指定tcp端口 -s 指定串口 -b 指定波特率 支持4800 ...
- ESP8266局域网 路由器下作服务器模式串口透传 arduino uno示例 模板参考2
ESP8266服务器模式串口透传编译需要下载8266的库文件后才可以正常 准备工作 下载一个Arduino IDE,下载8266的库文件ESP8266服务器模式串口透传编译 功能说明 1.直接使用路由 ...
- ESP8266局域网智能家居 路由器下作服务器模式串口透传 无线通信控制 arduino uno示例 模板参考
准备工作 下载一个Arduino IDE, 下载8266的库文件 ESP8266服务器模式串口透传编译 功能说明 1.直接使用路由器中转数据 2.手机放热点模式直接传输数据 两者有访问IP地址的差别, ...
- 18-ESP8266 SDK开发基础入门篇--TCP 服务器 RTOS版,串口透传,TCP客户端控制LED
https://www.cnblogs.com/yangfengwu/p/11112015.html 先规定一下协议 aa 55 02 01 F1 4C 控制LED点亮 F1 4C为CRC高位和低位 ...
- 16-ESP8266 SDK开发基础入门篇--TCP 服务器 非RTOS运行版,串口透传(串口回调函数处理版)
https://www.cnblogs.com/yangfengwu/p/11105466.html 其实官方给的RTOS的版本就是在原先非RTOS版本上增加的 https://www.cnblogs ...
- wifi实现串口透传
环境: 串口服务器Ip:172.16.1.11 串口客户机ip:172.16.1.12 一.网络连接示意图 二.串口服务器的配置 参考:ser2net的编译及测试 三.串口客户端的配置 实际上这是一个 ...
- python 串口 透传
python正常情况通过串口 serial 传输数据的时候,都是以字符串的形式发送的 str = ‘abcd’ ser.write(str.encode())#直接发送str报错,需要发送byte类 ...
- 蓝牙4.0BLE 手机控制 cc2540 CC2541 的串口透传功能已实现
蓝牙4.0BLE 手机控制 cc2540 CC2541 的串口透传功能已实现 尽管蓝牙4.0 BLE芯片CC2540 是单芯片(即用户能够对它进行芯片级代码编写), 是80 ...
- ESP8266串口和MQTT服务器消息互传(版本一) 单纯透传+保存WIFI账号信息
目标 制作一个ESP8266串口和MQTT相互透传的小WIFI,可用手机修改其连接的路由器,由此该模块可以任意加载到各种串口传输的单片机上,完成硬件到云端的传输. 1 实物图 2 MQTT网页测试客户 ...
随机推荐
- FFmpeg 解码内存泄漏汇总,sws_getContext函数无法释放问题
使用FFmpeg库做的项目,调试项目的时候发现,连续解视频进行播放,会有明显内存增加问题.连续工作10个小时后就会 被linux 内核kill掉. 通过逐步注掉代码和网上查阅资料.最后发现内存泄漏有一 ...
- 推荐一款在浏览器编辑`Blazor`的`IDE`
不知道是否有Blazor用户羡慕过React或者Vue用户,在一些组件库中,它们就提供了在当前的组件预览对于组件的实时编辑并且预览? 比如semi-design的这种 在比如codepen这种 由于B ...
- py教学之元组
元组介绍 Python 的元组与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号 ( ),列表使用方括号 [ ]. 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可. tup1 = ...
- 论文翻译:2022_Phase-Aware Deep Speech Enhancement: It’s All About The Frame Length
摘要 虽然相位感知语音处理近年来受到越来越多的关注,但大多数帧长约为32 ms的窄带STFT方法显示出相位对整体性能的影响相当温和.与此同时,现代基于深度神经网络(DNN)的方法,如Conv-TasN ...
- 对线面试官:浅聊一下 Java 虚拟机栈?
对于 JVM(Java 虚拟机)来说,它有两个非常重要的区域,一个是栈(Java 虚拟机栈),另一个是堆.堆是 JVM 的存储单位,所有的对象和数组都是存储在此区域的:而栈是 JVM 的运行单位,它主 ...
- 面向对象程序设计(二):C++模板初探
背景:老师留了一个作业,对两个数组进行相加,但是总是会出现错误:首先我们需要知道当数组作为参数传递的时候是不能用 sizeof 的,因为当数组传入子函数就变成了普通的数组头:这时候使用 sizeof ...
- Spring Boot整合JSP --CRUD
Springboot整合JSP spring boot与视图层次的整合: JSP 效率低 Thymeleaf java Server page 是Java提供的一种动态的网页技术,低层是Servlet ...
- UI自动化中上传与唤醒弹窗
本篇想谈的是在ui自动化中对上传的一些理解,干货满满. 一.是否有必要唤醒弹窗 以selenium为代表的库在进行文件上传时,是可以直接对输入框 "发送" 文件的,其send_ke ...
- windows server backup 无法使用或wbadmin.msc致命错误解决方法
因为黑群辉断电无法自动引导进系统,我也找不到很好的办法,所以决定使用windows server来做NAS服务器,虽然都解决了内网穿透的问题,但是数据安全还在找方案,目前已经解决: 1.购买了一张pc ...
- Where do I Turn?(叉积)
题目: Trouble came from the overseas lands: a three-headed dragon Gorynych arrived. The dragon settled ...