1.切换串口基本知识
关于切换串口的问题,首先由于项目需求,需要3个串口进行通信,但是nordic(52832)这款芯片只有一个串口,所以需要进行串口的切换。
不过唯一感到欣慰的是,只有一个串口需要保持长久的通讯,另外两个串口通讯是短时间的,这样在短时间内使用完串口,再切回主串口,理论上是可行的。
在调试之前,我们需要了解我们的串口的使用基本功能,主串口,目前定义为和模块的通讯串口,这个串口数据的特点是随机吐数据和请求再吐数据,如果其随机吐数据时,我们正在切换串口时,可能会将数据丢失,因此,我们在模块获取数据时,设置一个中断,有数据到来,触发中断,再取数据,将数据放入一个队列中。
理论上是,将发送的数据都加入到一个队列里面,防止多方抢占串口,造成串口数据乱码的现象,因此,我们将另外两个串口的发送和接收都封装到队列里面,这样做的后果是,如果队列里面的指令较多,那么等到自己需要的指令会产生延时,所以在要求实时性比较高的任务时,建议使用io口模拟串口。
好了,废话不多说,下面直接贴代码和思路。
2.切换串口的代码
/*创建队列,将需要发送的数据放入队列之中,以及入队列和出队列的方法*/
CREAT_FIFO uart_cmd;
set_data2fifo(uchar *p); //将数据塞入队列
get_data2fifo(uchar *p);//获取队列中的数据
注:队列的创建和使用都是属于比较基础的知识,这里就不演示基础知识了
static unsigned char uart0_flag = 0;
/*主函数*/
int mian()
{
creat_pthread(thread1,thread2,thread3);
while(1)
{
waith_data; //此处等待数据事件到来,解析数据
if ( 1 == uart0_flag ) //主串口
{
//uart1_init();
analyze_data1();
}
else if ( 2 == uart0_flag ) //复用串口1
{
uart1_init();
uart0_flag = 1;
analyze_data1();
}
else if ( 3 == uart0_flag ) //复用串口2
{
uart1_init();//
analyze_data1();
uart0_flag = 1;
}
else
{
printf("uart switch error!!!\r\n");
}
}
}
thread1: //创建线程1,用来维持和模块通信
use_uart0();//此处初始化串口,修改串口映射脚
set_data2fifo(cmd); //将需要发送的串口数据塞入fifo
push_cmd(); //推动fifo,发送数据
uart0_flag = 1;
thread2: //创建线程2,用来维持和mcu通信
use_uart1();//此处初始化串口,修改串口映射脚
set_data2fifo(cmd); //将需要发送的串口数据塞入fifo
push_cmd(); //推动fifo,发送数据
uart0_flag = 2;
thread3: //创建线程3,用来维持和charge通信
use_uart2();//此处初始化串口,修改串口映射脚
set_data2fifo(cmd); //将需要发送的串口数据塞入fifo
push_cmd(); //推动fifo,发送数据
uart0_flag = 3;
/*********************************************************************************/
总结:
以上内容是我所实现串口切换的大致思路,已经部分伪代码,已经实现的具体代码将贴在下一个章节,大致思路是通过fifo来管理串口发送数据,不让
数据发生混乱,这个不管是串口切换还是不切换都会遇到的问题,最主要的是怎么处理来自不同的模块来的消息,本文主要思路是一个主串口
多个辅串口,辅助串口占用时间有限,所以就不会出现丢包的问题,具体问题具体对待,在调试这个串口切换的时候主要点是怎么确定你是
处于哪个串口?所以加了一个标志位,用来标志你使用的串口。还有就是策略就是切完辅串口,等串口用完了,立马切换回来。还有一些基本问题,比如
乱码问题,这些都需要耐心排查问题,还是那样的一句话,只有静下心来,才能排除问题,完成工作,否则宁愿锻炼身体。