串口分布
串口內部自帶一個FIFO緩存,數據接收以后先緩存到內部FIFO緩存里面
內部FIFO滿了以后進入FIFO滿中斷
串口打開了串口超時(空閑)中斷:超過兩個字節的時間沒有接受到數據,進入串口超時(空閑)中斷
NONOS(先看串口接收)
1.初始化串口是使用下面的函數
里面只寫了設置波特率,如果需要設置其它參數可以參考代碼的最下面
2.默認是使用串口0輸出日志
咱先不用修改,咱先把串口基本操作學完
3.提供的串口中斷接收里面是使用任務通知的形式(關於任務通知參見上一節系統任務(消息隊列,通知))
在內部FIFO接收到數據的時候發送任務消息出去
在任務中讀取數據(讀取數據默認提供的是存儲到數組緩存里面)
4.咱們獲取數據呢是使用下面的函數
函數返回值是獲取的數據個數;形參1是咱要把數據拷貝到的數組地址;形參2是咱想獲取的數據個數
5.官方還貼心的給了例子
定時器每隔10ms輪訓,每次嘗試獲取128字節數據,獲取到數據之后,直接返回接收的數據
6.咱們就直接拷貝到主函數試一試
7.串口接收緩存默認是256字節,如果數據的每一幀的數據量大於這個值,就需要增加
8.再提醒下哈,下面只是嘗試獲取128字節,假設緩存里面有10個數據,那么也只會返回10個.
假設緩存里面有500個,那么會返回128個.
一般這個值取最大可能返回的數據個數.
9.注意:一般是接收到一條完整的數據之后再去處理數據,但是特殊場合需要快速的通信,如果每條數據的時間間隔小於10ms,
那么便會出現粘包.可以使用任務把輪訓間隔縮小到1ms;
首先把串口的任務優先級改為最高
然后在主函數加一個優先級別低的任務
/************任務*************/ #define os_event_t_buff_len 255 /*消息隊列長度;最大255*/ os_event_t os_event_t_buff[os_event_t_buff_len]; //存儲消息的數組 #define TaskPrio 0 //任務等級(0,1,2(最高)) uint32 os_task_t_delay=0;//在任務里面做延時 /************串口接收緩存**************/ uint8 uart_buf[UART_RX_BUFFER_SIZE]={0}; uint16 len = 0;
void os_task_t_callback(os_event_t *events){ if(events->sig == 0 && events->par ==0){ system_os_post(TaskPrio, 0, 0); } os_task_t_delay++; if(os_task_t_delay>300){//大約1ms os_task_t_delay=0; len = rx_buff_deq(uart_buf, 128 );//嘗試從緩存中獲取128字節串口數據 tx_buff_enq(uart_buf,len);//把接收的數據返回 } }
system_os_task(os_task_t_callback, TaskPrio, os_event_t_buff, os_event_t_buff_len); system_os_post(TaskPrio, 0, 0);
當然一般串口10ms已經適應了基本上所有的項目了
10.如果想把數據直接存儲到自己定義數組里面
把UART_BUFF_EN改為0
NONOS(串口發送數據)
默認的發送是使用的緩存+中斷發送
建議用戶直接使用這種方式.因為發送數據的時候不會阻塞.
關於 os_printf
os_printf函數一般是做日志打印的,默認是使用串口0打印;可以配置到串口1上(gpio2口上)
os_printf函數可以使用下面的函數關閉或者開啟打印
system_set_os_print (0);//0:關閉打印 1:開啟打印