標籤:style blog http color io 檔案 for ar
每次慌慌張張碼完一段代碼,總是感覺慘不忍睹。但是進度緊,沒辦法只能想著調好了再來整理,但是整下項目折騰完了,人都筋疲力盡了,又懶得整理了。所以每隔一年半載看以前的代碼都覺得是一堆垃圾。
下面找了個簡易的電源管理的模組開刀,試著將通用的部分提取出來。
這個是未做處理的檔案,我們一般也是按正常的邏輯來編碼。
#include "MKL26Z4.h"#include "bat.h"#include "err.h"#include "ntc.h"#include "Events.h"#include "OLED_96X32.h"extern void (*display_array[])(void);void bat_manage_init(void){ SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK; //FGPIOB_PDDR &= ~(1<<16); // Configure as input GPIOB_PDDR &= ~(1<<16); // Configure as input PORTB_PCR16 = (PORT_PCR_MUX(1) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK); }void bat_manage_main_thread(void){ unsigned char iFun=0; static unsigned char bat_charge_cmplt=0; static unsigned char bat_charge_pass=0; static unsigned char old_disp_save_cmplt=0; static unsigned char old_disp_resume_cmplt=0; static unsigned char curr_disp_load_cmplt=0; static void (*pFunSave[FUN_MAX])(void); if(hw_adc_ave(9,16,20)< BAT_PRE_VALUE) { bat_charge_cmplt = 0; } else { bat_charge_cmplt =1; } //接上充電插座 if(!(GPIOB_PDIR&(1<<16))) { //開始充電 if(!bat_charge_cmplt) { //儲存以前的顯存 if(!old_disp_save_cmplt) { for(iFun = 0;iFun< FUN_MAX;iFun++) { pFunSave[iFun]=display_array[iFun]; } old_disp_save_cmplt = 1; } //載入當前的顯存 if(!curr_disp_load_cmplt) { for(iFun = 0;iFun< FUN_MAX;iFun++) { display_array[iFun] = NULL; } display_array[5] = DisplayBatCharge; curr_disp_load_cmplt = 1; } } //已經充滿 else { } bat_charge_pass = 1; } //沒有充電 else { //已經衝過電了 if(bat_charge_pass) { //恢複以前的顯存 if(!old_disp_resume_cmplt) { for(iFun = 0;iFun< FUN_MAX;iFun++) { display_array[iFun]=pFunSave[iFun]; } old_disp_resume_cmplt = 1; } bat_charge_pass = 0; bat_charge_cmplt = 0; old_disp_save_cmplt = 0; curr_disp_load_cmplt = 0; old_disp_resume_cmplt = 0; } //沒衝過電 else { } }}
瞄了一眼上面代碼的邏輯,發現鋰電池充電都只有這四個狀態:
1)正在充電:a、還未充滿 b、已經充滿
2)沒有充電:a、已經衝過電了 b、沒有衝過電
於是公用部分就是4個狀態,提取如下:
bat.h
#ifndef BAT_H#define BAT_H#ifndef FUN_MAX #define FUN_MAX 5#endif#ifndef BAT_GPIO #define BAT_GPIO 0//GPIOB_PDIR&=(1<<16)#endif#ifndef NULL #define NULL 0x00u#endifclass bat{public: bat(); inline void bat_manage_init(void); void bat_monit(); void bat_manage_main_thread(void); void bat_charge_cmplt_callback(); void bat_charge_not_cmplt_callback(); void bat_charge_pass_callback(); void bat_charge_not_pass_callback();private: unsigned char bat_charge_cmplt; unsigned char bat_charge_pass;};
bat.cpp
#include "bat.h"bat::bat(){ bat_manage_init();}void bat::bat_manage_init(){}void bat::bat_monit(){ bat_charge_cmplt = 0; bat_charge_pass = 0;}void bat::bat_charge_cmplt_callback(){}void bat::bat_charge_not_cmplt_callback(){}void bat::bat_charge_pass_callback(){}void bat::bat_charge_not_pass_callback(){}void bat::bat_manage_main_thread(void){ bat_monit(); //接上充電插座 if(!BAT_GPIO) { //開始充電 if(!bat_charge_cmplt) { bat_charge_not_cmplt_callback(); } //已經充滿 else { bat_charge_cmplt_callback(); } } //沒有充電 else { //已經衝過電了 if(bat_charge_pass) { bat_charge_pass_callback(); } //沒衝過電 else { bat_charge_not_pass_callback(); } }}
一眨眼,代碼從C變成C++了,別糾結了,你可以把C++的Class改成C的Struct,Class就是一個帶許可權管理的Struct。
把公用部分的4個狀態提取出來作為一個基類,充電過程中需要定製化處理的部分改造成4個狀態的回呼函數。
下次要用到鋰電池充電管理就可以直接在這個基類的基礎上繼承一個衍生類別,重載這四個回呼函數即可!
void bat_charge_cmplt_callback(); void bat_charge_not_cmplt_callback(); void bat_charge_pass_callback(); void bat_charge_not_pass_callback();
這個代碼的執行個體在網盤裡,感興趣的可以下載debug耍耍,http://pan.baidu.com/s/1VCy6 ,用的QT4.8.5來調試的。程式跟平台無關,隨便用什麼編譯環境都可以。