瞭解了8266的串口了,這一節咱就本身寫程序,處理一下數據,若是接收到html
0xaa 0x55 0x01 就控制指示燈亮數組
0xaa 0x55 0x00 就控制指示燈滅緩存
注意哈,我是用的假設沒有操做系統的思路,其實若是有了操做系統應該用操做系統提供的API實現函數
由於8266是用的FreeRtos,,,我尚未深刻了解這個系統,因此我先用個人方式實現,後期的文章可能須要等些時間更新了,由於我須要充電ui
定義一些變量spa
u8 Usart1ReadBuff[Usart1ReadLen]={0};//接收數據的數組 u32 Usart1ReadCnt = 0;//串口1接收到的數據個數 u32 Usart1ReadCntCopy = 0;//串口1接收到的數據個數拷貝 u8 Usart1ReadFlage=0;//串口1接收到一條完整數據
其實就是在滿中斷裏面把數據存到咱定義的數組,在空閒中斷裏面讀出來剩餘的數據操作系統
而後置位一個標誌,說明接收到一條完整的數據了3d
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)) ; } }
其實如今就是處理code
#include "uart.h" extern u8 Usart1ReadBuff[Usart1ReadLen];//接收數據的數組 extern u32 Usart1ReadCnt;//串口1接收到的數據個數 extern u32 Usart1ReadCntCopy;//串口1接收到的數據個數拷貝 extern u8 Usart1ReadFlage;//串口1接收到一條完整數據
處理數據以前先預熱一下操做系統htm
控制LED 1S亮 1S滅
對了由於咱用的是操做系統哈,因此千萬別這樣想
應該建一個函數,還記得上一節不,對了咱只是說操做系統的使用哈,不講實質
如今呢,把這個函數交給操做系統去管理
而後再完善
可是這樣下載進去,不能夠....
還記得上一節說的不,任務必須有延時
延時是用
vTaskDelay(1000/portTICK_RATE_MS );//延時1S
vTaskDelay(2000/portTICK_RATE_MS );//延時2S
有人可能有疑問,爲何要用這個,其實這是操做系統提供的延時的API,調用它給的,操做系統才知道這裏要延時一會.我先去執行別的任務去
若是你不要操做系統提供的,用本身的硬延時 類如for 什麼的,其實就是在這裏等着了,,,,通常哈,對於延時比較苛刻的咱用本身的
好比採集DHT11,DS18B20,等等,,,這種不是很苛刻的,咱就用操做系統提供的
好了如今下載進去,會看到這個燈1S亮,1S滅
如今咱作個好玩的,兩個任務控制兩個燈
下載進去,你們會發現神奇的事情 同時亮,同時滅
其實這就是操做系統的魅力所在....若是任務延時上同樣,那麼你會看着兩個函數是同時進行的
首先說一點哈
看着是同時亮和滅,其實他們之間有延時,就是大約延時個任務調度的時間
其實操做系統是不斷的輪詢各個任務,不斷的掛起任務(讓任務中止運行),啓動任務
串口處理放到下一節吧