了解了8266的串口了,這一節咱就自己寫程序,處理一下數據,如果接收到
0xaa 0x55 0x01 就控制指示燈亮
0xaa 0x55 0x00 就控制指示燈滅
注意哈,我是用的假設沒有操作系統的思路,其實如果有了操作系統應該用操作系統提供的API實現
因為8266是用的FreeRtos,,,我還沒有深入了解這個系統,所以我先用我的方式實現,后期的文章可能需要等些時間更新了,因為我需要充電
定義一些變量
u8 Usart1ReadBuff[Usart1ReadLen]={0};//接收數據的數組 u32 Usart1ReadCnt = 0;//串口1接收到的數據個數 u32 Usart1ReadCntCopy = 0;//串口1接收到的數據個數拷貝 u8 Usart1ReadFlage=0;//串口1接收到一條完整數據
其實就是在滿中斷里面把數據存到咱定義的數組,在空閑中斷里面讀出來剩余的數據
然后置位一個標志,說明接收到一條完整的數據了
LOCAL void uart0_rx_intr_handler(void *para) { /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents * uart1 and uart0 respectively */ uint8 RcvChar; uint8 uart_no = UART0;//UartDev.buff_uart_no; uint8 fifo_len = 0; uint8 buf_idx = 0; //uint8 fifo_tmp[128] = {0};//只是告訴我們這個單片機的內部FIFO是128字節大小 uint32 uart_intr_status = READ_PERI_REG(UART_INT_ST(uart_no)) ;//讀取中斷狀態 while (uart_intr_status != 0x0) { if (UART_FRM_ERR_INT_ST == (uart_intr_status & UART_FRM_ERR_INT_ST)) // 接收幀錯誤中斷,,,可能是數據位數不對,或者接收到的數據不滿8bit...等等 { WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR);// 清除中斷寄存器的 幀錯誤位 } else if (UART_RXFIFO_FULL_INT_ST == (uart_intr_status & UART_RXFIFO_FULL_INT_ST)) //進入FIFO滿中斷 { fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT;//讀出來內部FIFO緩存的數據個數 while (fifo_len--) { if(Usart1ReadCnt<Usart1ReadLen-1)//別超過了數組的大小 { Usart1ReadBuff[Usart1ReadCnt] = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;//取出來一個數據 Usart1ReadCnt++; } else { Usart1ReadCnt = 0; } } WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR);// 清除滿中斷 } else if (UART_RXFIFO_TOUT_INT_ST == (uart_intr_status & UART_RXFIFO_TOUT_INT_ST)) //空閑中斷,證明接受到了一條完整的數據 { fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT;//讀出來接收的數據個數 while (fifo_len--) { if(Usart1ReadCnt<Usart1ReadLen-1)//別超過了數組的大小 { Usart1ReadBuff[Usart1ReadCnt] = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;//取出來一個數據 Usart1ReadCnt++; } else { Usart1ReadCnt = 0; } } Usart1ReadCntCopy = Usart1ReadCnt;//串口1接收到的數據個數拷貝 Usart1ReadCnt = 0; Usart1ReadFlage=1;//串口1接收到一條完整數據 WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR);// 清除空閑標志位 } else if (UART_TXFIFO_EMPTY_INT_ST == (uart_intr_status & UART_TXFIFO_EMPTY_INT_ST))//發送FIFO里面的數據個數少於20個,進入中斷 { WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_TXFIFO_EMPTY_INT_CLR);// 清除中斷標志 CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);//清除中斷 } else { //skip } uart_intr_status = READ_PERI_REG(UART_INT_ST(uart_no)) ; } }
其實現在就是處理
#include "uart.h" extern u8 Usart1ReadBuff[Usart1ReadLen];//接收數據的數組 extern u32 Usart1ReadCnt;//串口1接收到的數據個數 extern u32 Usart1ReadCntCopy;//串口1接收到的數據個數拷貝 extern u8 Usart1ReadFlage;//串口1接收到一條完整數據
處理數據之前先預熱一下操作系統
控制LED 1S亮 1S滅
對了因為咱用的是操作系統哈,所以千萬別這樣想
應該建一個函數,還記得上一節不,對了咱只是說操作系統的使用哈,不講實質
現在呢,把這個函數交給操作系統去管理
然后再完善
但是這樣下載進去,不可以....
還記得上一節說的不,任務必須有延時
延時是用
vTaskDelay(1000/portTICK_RATE_MS );//延時1S
vTaskDelay(2000/portTICK_RATE_MS );//延時2S
有人可能有疑問,為什么要用這個,其實這是操作系統提供的延時的API,調用它給的,操作系統才知道這里要延時一會.我先去執行別的任務去
如果你不要操作系統提供的,用自己的硬延時 類如for 什么的,其實就是在這里等着了,,,,一般哈,對於延時比較苛刻的咱用自己的
比如采集DHT11,DS18B20,等等,,,這種不是很苛刻的,咱就用操作系統提供的
好了現在下載進去,會看到這個燈1S亮,1S滅
現在咱做個好玩的,兩個任務控制兩個燈
下載進去,大家會發現神奇的事情 同時亮,同時滅
其實這就是操作系統的魅力所在....如果任務延時上一樣,那么你會看着兩個函數是同時進行的
首先說一點哈
看着是同時亮和滅,其實他們之間有延時,就是大約延時個任務調度的時間
其實操作系統是不斷的輪詢各個任務,不斷的掛起任務(讓任務停止運行),啟動任務
串口處理放到下一節吧
https://www.cnblogs.com/yangfengwu/p/11087558.html