本帖最后由 liuje 于 2020-9-26 13:19 编辑
大家好, 這是我第一次發帖. 我是業餘單片機愛好者, 業餘玩玩. 本身不是學這個的.
無意中看到新唐N76E616的資料, 帶LCD驅動. 低功耗雖不如STM8L, 但CP值更高, 所以來玩看看.
這也是第一次做51編程. 之前主要是玩STM8與STM32.
測試板是淘寶買的, 把電源LED去掉了, 否則基本就要消耗掉1-2mA, 根本不用談什麼低功耗了.
LCD也是找公版現成的. 引腳排列剛好符合這塊板的IO管腳排列, 直接焊上就完事.
然後NTC10K熱敏電阻通過10K電阻分壓做ADC. 熱敏電阻VCC電壓部份改以IO直接推動.
以便在掉電模式下, 關閉此輸出, 否則這邊, 常態將消耗大約 3.3V / (10000+10000) = 165uA
常規性持續消耗1百多uA. 這樣也做不好低功耗的.
根據前輩提供的低功耗定律, MCU在醒來後, 一定要快速做完所有事, 再重新去睡覺.
我做了MCU在喚醒後, 分別跑11.0592MHZ以及10KHZ兩者速度, 在同等條件下的平均電流比照,
可以看下圖, 平均電流相差了12倍之多 (180uA對比14uA) . 應驗了前輩們的說法 .
而這個最小系統, 帶上此LCD, 掉電睡眠狀態為12.3uA , 以鈕扣電池CR2032來驅動的話(容量約200mA):
按60秒平均電流 14.33uA此條件下, 不考慮電池自放電, 還有需考量N76E616最低工作電壓只到2.ˋ4V,
我們在200mA容量打個7折的話也就是 140mA , (140000 / 14.33 = 9769 / 24(換算為天) = 407天.
也就是, 應該能撐上1年~1年半. 算是還不錯了.
** 掉電睡眠時間為 4秒 ***
我不確定帶LCD的狀態下, 12.3uA是否為最小極限了. 有興趣歡迎來挑戰一下最低極限.
附上測試代碼供參考, 也請大家不要噴我, 我不是碼農, 純脆自學興趣.
歡迎交流 ~
[主要代碼]
void main (void)
{
/* Note
MCU power on system clock is HIRC (11.0592MHz), so Fsys = 11.0592MHz
*/
#if 0
Set_All_GPIO_Quasi_Mode();
#if DEBUG_PORT == 0
InitialUART0_Timer1_Type1(9600); /* 9600 Baud Rate*/
#elif DEBUG_PORT == 1
InitialUART1_Timer3(9600); /* 9600 Baud Rate*/
#endif
Show_FW_Version_Number_To_PC();
printf ("\n*===================================================================");
printf ("\n* Name: N76E616 LCD Demo Code.");
printf ("\n*===================================================================\n");
#endif
LCD_Initial();
/* Change system closk source */
#if SYS_CLK_EN == 1
#if SYS_SEL == 0
System_Clock_Select(E_HXTEN); //Fosc = 2~16MHz XTAL
#elif SYS_SEL == 1
System_Clock_Select(E_LXTEN); //Fosc = 32.768KHz XTAL
#elif SYS_SEL == 2
System_Clock_Select(E_HIRCEN); //Fosc = 11.0592MHz Internal RC
#endif
#endif
// set_CLOEN; //Clock out on P0.7
#if SYS_DIV_EN == 1
CKDIV = SYS_DIV; //Fsys = Fosc / (2* CLKDIV) = Fcpu
#endif
#if 0
Set_All_GPIO_Quasi_Mode();
#else
#if PORT0_MODE == 0 //Quasi-Bidirectional
P0M1 = 0x00;
P0M2 = 0x00;
#elif PORT0_MODE == 1 //Push-Pull
P0M1 = 0x00;
P0M2 = 0xFF;
#elif PORT0_MODE == 2 //Input-Only
P0M1 = 0xFF;
P0M2 = 0x00;
#elif PORT0_MODE == 3 //Open-Drain
P0M1 = 0xFF;
P0M2 = 0xFF;
#endif
#if PORT1_MODE == 0 //Quasi-Bidirectional
P1M1 = 0x00;
P1M2 = 0x00;
#elif PORT1_MODE == 1 //Push-Pull
P1M1 = 0x00;
P1M2 = 0xFF;
#elif PORT1_MODE == 2 //Input-Only
P1M1 = 0xFF;
P1M2 = 0x00;
#elif PORT1_MODE == 3 //Open-Drain
P1M1 = 0xFF;
P1M2 = 0xFF;
#endif
#if PORT2_MODE == 0 //Quasi-Bidirectional
P2M1 = 0x00;
P2M2 = 0x00;
#elif PORT2_MODE == 1 //Push-Pull
P2M1 = 0x00;
P2M2 = 0xFF;
#elif PORT2_MODE == 2 //Input-Only
P2M1 = 0xFF;
P2M2 = 0x00;
#elif PORT2_MODE == 3 //Open-Drain
P2M1 = 0xFF;
P2M2 = 0xFF;
#endif
#if PORT3_MODE == 0 //Quasi-Bidirectional
P3M1 = 0x00;
P3M2 = 0x00;
#elif PORT3_MODE == 1 //Push-Pull
P3M1 = 0x00;
P3M2 = 0x7F;
#elif PORT3_MODE == 2 //Input-Only
P3M1 = 0x7F;
P3M2 = 0x00;
#elif PORT3_MODE == 3 //Open-Drain
P3M1 = 0x7F;
P3M2 = 0x7F;
#endif
#if PORT4_MODE == 0 //Quasi-Bidirectional
P4M1 = 0x00;
P4M2 = 0x00;
#elif PORT4_MODE == 1 //Push-Pull
P4M1 = 0x00;
P4M2 = 0x7F;
#elif PORT4_MODE == 2 //Input-Only
P4M1 = 0x7F;
P4M2 = 0x00;
#elif PORT4_MODE == 3 //Open-Drain
P4M1 = 0x7F;
P4M2 = 0x7F;
#endif
#if PORT5_MODE == 0 //Quasi-Bidirectional
P5M1 = 0x00;
P5M2 = 0x00;
#elif PORT5_MODE == 1 //Push-Pull
P5M1 = 0x00;
P5M2 = 0xFF;
#elif PORT5_MODE == 2 //Input-Only
P5M1 = 0xFF;
P5M2 = 0x00;
#elif PORT5_MODE == 3 //Open-Drain
P5M1 = 0xFF;
P5M2 = 0xFF;
#endif
#endif
set_ADCEN; // 使能ADC
ADCCON0 = 0x02; //select ADC pin (P02)
set_P0M1_2; //set ADC pin is input only mode ((P02)
clr_P0M2_2;
set_P02DIDS; //disable digital connection (P02 Disbale Digtal Input)
/******************************************************************************
* FUNCTION_PURPOSE: ADC Clock Divider Select
******************************************************************************/
set_ADCDIV2; // 決定ADC(除頻)轉換時間 ADCDIV[2:0] 111 : FADC=FSYS/128.
set_ADCDIV1;
set_ADCDIV0;
////***** LIRC enable part***** 切換時鐘為LIRC(10KHZ)
////** Since LIRC is always enable, switch to LIRC directly
//set_OSC1; //switching system clock source if needed
//clr_OSC0;
//while((CKEN&SET_BIT0)==1); //check system clock switching OK or NG
//clr_HIRCEN; // HIRC Disbale
while(1)
{
P00=0; // NTC10K
P01=1; // NTC10K VCC給電 (P00 : VCC / P01 : GND)
set_ADCEN; // 使能ADC
set_P0M1_2; // set ADC pin is input only mode ((P02)
clr_P0M2_2;
clr_ADCF;
set_ADCS; //Trigger ADC start conversion
while(ADCF == 0);
ADCF = 0;
TEMP_AD = ((uint16_t)ADCRH)<<2 | ADCRL;
TEMP_AD += 4; // 補償NTC分壓電阻, 以IO管腳輸出HIGH做為VDD時, 實際電壓比板子VDD要低一點.
TEMP = NTC_ADC2Temperature(TEMP_AD);
Show_Temp_In_LCD(TEMP);
//Timer0_Delay1ms(10);
clr_ADCEN; // 關閉ADC
clr_BODEN; // 關閉BOD檢測
WakeUp_Init(); // 定時喚醒MCU設置
P00=0; // 將所有I/O口合理設置為輸出 HIGH or LOW, 避免洩漏電流
P01=0; // 關閉NTC10K分壓電阻VCC電源
P02=0;
P03=0;
P04=0;
P05=0;
P06=0;
P07=0;
P20=1; //P20要嘛設為RESET,如果是設為GPIO則必須上拉, 否則會增加耗電流
P21=1; //RXD(LED) = 1 (板載 RXD LED熄滅)
P22=1; //TXD(LED) = 1 (板載 TXD LED熄滅)
P23=0;
P24=0;
P25=0;
P26=0;
P27=0;
P30=0;
P31=0;
P32=0;
P33=0;
P34=0;
P35=0;
P36=0;
P37=0;
P50=0;
P51=0;
P52=0;
P53=0;
P54=0;
P55=0;
P56=0;
P57=0;
set_PD; //進入掉電模式
}
}
N76E616_LCD_NTC10K_Lowpower_12.3uA.rar
(131.17 KB)
(掉電模式下電流)
(喚醒後, MCU運行於10KHZ, 運行60秒平均電流 : 180.43uA)
(喚醒後, MCU運行於11.0592MHZ, 運行60秒平均電流 : 14.33uA)
|
共1人点赞
|