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來管理串口發送數據,不讓
數據發生混亂,這個不管是串口切換還是不切換都會遇到的問題,最主要的是怎麼處理來自不同的模塊來的消息,本文主要思路是一個主串口
多個輔串口,輔助串口占用時間有限,所以就不會出現丟包的問題,具體問題具體對待,在調試這個串口切換的時候主要點是怎麼確定你是
處於哪個串口?所以加了一個標誌位,用來標誌你使用的串口。還有就是策略就是切完輔串口,等串口用完了,立馬切換回來。還有一些基本問題,比如
亂碼問題,這些都需要耐心排查問題,還是那樣的一句話,只有靜下心來,才能排除問題,完成工作,否則寧願鍛鍊身體。