關注+星標公眾號,不錯過精彩內容

作者 | strongerHuang
微信公眾號?|?嵌入式專欄
很多初學者覺得自己學的東西很基礎,擔心今后實際工作用不到。
有初學者問了這樣的問題:單片機真正開發產品和學習的時候有什么差別,平時學的LED、ADC這些東西,在實際項目中會用到嗎?
雖然技術更新迭代很快,但有很多基本的技術,仍然在實際項目中會用到,今天就拿LED為例來說說吧。
LED有哪些作用

拿狀態指示燈來說,一個項目的LED狀態指示燈可以直觀明了的指示設備的運行狀態,比如:運行、故障、待機、死機等常見狀態。通過RGB,或者紅黃綠不同顏色LED組合,可以實現更多狀態的指示。
下面針對LED狀態燈,說幾點細節的內容。
LED狀態燈實現
這里結合代碼為大家分享一些項目中常見的LED狀態燈的實現方法。
1.單色LED運行狀態指示燈
通過閃爍(一亮一滅)指示設備運行的狀態的指示燈,一個關鍵作用:設備有沒有死機。
很多產品中都會用到,你買一個開發板,提供的綜合例程也基本都有。
裸機情況下(一般狀態機),在某一個狀態實現LED閃爍:
int main(void){??//系統初始化while(1){????//do?somethingswitch(State){case 狀態1://do somethingbreak;case 狀態2://do something??????break;··??????·case 狀態燈:ED_TOGGLE(); //LED閃爍break;}}}
RTOS情況下,新建一個狀態燈線程,在線程里面直接控制即可:
void StatusLight_Task(void *pvParameters){??static?TickType_t?xLastWakeTime;//初始化xLastWakeTime = xTaskGetTickCount();for(;;){????//do?somethingLED_TOGGLE(); //LED閃爍vTaskDelayUntil(&xLastWakeTime, 500);}}
2.單色LED漸變
LED漸變在生活中其實也有一些場景在用,呼吸燈、鍵盤等,其實原來也很簡單,就是控制LED亮度。
控制方法有很多,電壓、PWM都能達到控制LED亮度的效果。當然,現在還有控制LED漸變的專有芯片。

但是,對于單片機項目來說,單片機自身就能實現,如果單獨用一個芯片,就顯得有點多余。
使用DAC輸出模擬量可以實現,但如果多路就不現實,因此這種方法不常見。
常見的是PWM控制IO高低電平(從而控制電壓),這種對于單片機來說有兩種方法:
定時器硬件PWM
控制GPIO口高低電平
a.定時器硬件PWM
一個定時器輸出PWM波形的同時,還需要一個定時器定時更新PWM輸出占空比(修改亮度)。
b.控制GPIO口高低電平
這個方法就比較簡單,控制IO口高低電平時間,只是這個時間需要結合整個項目業務邏輯(特別是裸機情況下),不能出現“卡機”情況。
當然,在RTOS情況下,業務邏輯就比較簡單,單獨一個線程:
LED_ON();vTaskDelay(TimesON);LED_OFF();vTaskDelay(TimesOFF);
這里TimesON 和?TimesOFF是需要結合項目情況修改的變量(比如漸變時間)。
3.多色LED,多種運行狀態
一個設備在沒有顯示屏指示狀態的時候,通過LED指示狀態也是一種方法,比如:紅、黃、綠三色,分別常滅、常亮、閃爍三種狀態。
這種相對第一種單色固定狀態要復雜一點,但實現起來也不難,方法也有很多。
這里分享一些思路:創建一個線程,一個結構體,輪詢各種LED狀態,根據應用修改其各種狀態,以及閃爍時間等。
LED狀態結構體:
typedef struct{uint8_t Mode; //模式uint8_t Status; //當前狀態uint16_t OffTimes; //滅時間uint16_t OnTimes; //亮時間(ms)uint16_t Counter; //計數(計時)void (*OffFun)(void); //滅函數接口void (*OnFun)(void); //亮函數接口}SL_TypeDef;/* 狀態燈 */
LED狀態主線程:
void StatusLight_Task(void *pvParameters){??static?TickType_t?xLastWakeTime;xLastWakeTime = xTaskGetTickCount();for(;;){SL_Scan(&sSLG_Structure); //紅燈SL_Scan(&sSLY_Structure); //黃燈SL_Scan(&sSLR_Structure); //綠燈vTaskDelayUntil(&xLastWakeTime, SL_TASK_PERIOD);}}
static void SL_Scan(SL_TypeDef *SL_Struct){/* 常滅模式 */if(SL_MODE_OFF == SL_Struct->Mode){SL_Struct->Status = SL_STATUS_OFF; //狀態置為"滅"SL_Struct->OffFun(); //滅燈}/* 常亮模式 */else if(SL_MODE_ON == SL_Struct->Mode){SL_Struct->Status = SL_STATUS_ON; //狀態置為"亮"SL_Struct->OnFun(); //亮燈}/* 閃爍模式 */else if(SL_MODE_FLICKER == SL_Struct->Mode){/* 在滅狀態 */if(SL_STATUS_OFF == SL_Struct->Status){SL_Struct->Counter++;if(SL_Struct->Counter >= SL_Struct->OffTimes){SL_Struct->Counter = 0;SL_Struct->OnFun(); //亮燈SL_Struct->Status = SL_STATUS_ON; //狀態置為"亮"}}/* 在亮狀態 */else if(SL_STATUS_ON == SL_Struct->Status){SL_Struct->Counter++;if(SL_Struct->Counter >= SL_Struct->OnTimes){SL_Struct->Counter = 0;SL_Struct->OffFun(); //滅燈SL_Struct->Status = SL_STATUS_OFF; //狀態置為"滅"}}else{SL_Struct->Status = SL_STATUS_OFF; //狀態置為"滅"}}/* 未知模式 */else{SL_Struct->Status = SL_STATUS_OFF; //狀態置為"滅"SL_Struct->OffFun(); //滅燈}}
最后


由于微信公眾號近期改變了推送規則,為了防止找不到,可以星標置頂,這樣每次推送的文章才會出現在您的訂閱列表里。
猜你喜歡:
嵌入式設備AP配網實例分享
嵌入式Linux單板連接飛燕物聯網平臺
分享一種靈活性很高的協議格式(附代碼例子)
嵌入式大雜燴周記 | 第 16 期
嵌入式大雜燴周記 | 第 15 期
訪問非法內存為什么不會出錯?
嵌入式大雜燴周記 | 第 14 期
分享幾個實用的代碼片段(第二彈)
分享一種你可能不知道的bug定位方法
分享一種修改配置文件的方法
《嵌入式大雜燴周記第 13 期:lz4》
《嵌入式并行多線程處理器,了解一下!》
《分享一種修改配置文件的方法》
《分享幾個實用的代碼片段(附代碼例子)》
《廢舊板子再利用:搭建無線調試環境!》
《嵌入式段錯誤的3種調試方法匯總!》
《簡說TCP通信非阻塞接收(附代碼例子)》
《TCP通信常用接口的使用封裝》
《嵌入式軟件中,總線錯誤的坑?替大家先踩一步》
《分享嵌入式軟件調試方法及幾個有用的工具!》
《分享兩點提高編程能力的建議!》
在公眾號聊天界面回復1024,可獲取嵌入式資源;回復?m?,可查看文章匯總