打印
[DemoCode下载]

新唐N76E616 LCD低功耗測試

[复制链接]
909|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
liuje|  楼主 | 2020-9-25 11:22 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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)



使用特权

评论回复
沙发
zeshoufx| | 2020-9-26 21:37 | 只看该作者
谢谢分享,,,,,,,,,

使用特权

评论回复
板凳
liuje|  楼主 | 2020-10-4 09:22 | 只看该作者
本帖最后由 liuje 于 2020-10-4 09:28 编辑

休假期間, 做了一個奧松AHT10的溫濕度計測試.  AHT10使用I2C接口, 但量測的步驟有點麻煩.    在掉電模式喚醒後, 量測一次溫/濕度總時間, 大約需要100ms,  有點久。   比使用NTC+HR202濕敏電阻的ADC計算方式要讀取時間要長很多, 對低功耗來說, 也會較耗電的.   
AHT10發送完讀取數據的命令後, 還得等待大約70ms才能讀取, 這時候,最好先讓MCU進入掉電模式, 然後在喚醒讀取量測數據, 以降低平均電流.  

AHT10精準度還行, 與SHT20的溫度記錄儀做比照, 在補償了+3.5%RH後 , 運行了一整天, 誤差與SHT20對比, 都在+-3%RH之間.
溫度不用任何補償就很准了,   大約都在+-0.5度C以內.

PCB是使用立創EDA劃的.  然後設為每10秒喚醒一次.   運行60秒的平均電流為18.5uA .  這樣的平均電流, 應可讓CR2020鈕扣電池運行1年,
因此需要拉大喚醒時間到每10秒一次.

AHT10傳感器的C/P值頗高,  也就2塊多.   遠遠比DHT11垃圾等級的精準度要好太多了.  但手工焊接有點麻煩就是.  需要用熱風槍,
它是類似BGA式引腳.  我是請同事幫忙先手焊舖上一層錫, 再用吸錫器吸平焊墊.    最後用熱風槍來吹,  做了兩台, 一台成功, 一台失敗.

(附上代碼如附件)


(AHT10封裝)



(自己畫了一塊PCB, 以方便測試AHT10)



(喚醒後, 讀取AHT10數據所需時間大約要100ms, 在發出讀取命令後, 最好讓MCU先進入掉電模式, 然後醒來再讀取資料, 較省電)


(與SHT20的溫度計錄儀做溫/濕度比較, 精准度已經不錯了)


(睡眠10秒喚醒, 60秒平均電流)




AHT10傳感器資料.pdf

1.1 MB

N76E616_LCD_TEMP&amp;HUMI_AHT10_I2C_P04.P06.rar

175.26 KB

使用特权

评论回复
地板
lidi911| | 2020-10-8 18:17 | 只看该作者
不错,感谢楼主分享。

使用特权

评论回复
5
qcliu| | 2020-10-10 16:31 | 只看该作者
支持楼主一下

使用特权

评论回复
6
tfqi| | 2020-10-10 16:31 | 只看该作者
感谢楼主的分享

使用特权

评论回复
7
wiba| | 2020-10-10 16:31 | 只看该作者
看不太懂啊

使用特权

评论回复
8
zljiu| | 2020-10-10 16:32 | 只看该作者
功耗挺低啊

使用特权

评论回复
9
coshi| | 2020-10-10 16:32 | 只看该作者
运行的还不错

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

21

帖子

1

粉丝