[DemoCode下载] 新唐N76E616 LCD低功耗測試

[复制链接]
1235|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是否為最小極限了. 有興趣歡迎來挑戰一下最低極限.   
附上測試代碼供參考,  也請大家不要噴我, 我不是碼農, 純脆自學興趣.

歡迎交流 ~

[主要代碼]
  1. void main (void)
  2. {
  3.     /* Note
  4.        MCU power on system clock is HIRC (11.0592MHz), so Fsys = 11.0592MHz
  5.     */

  6. #if 0   
  7.     Set_All_GPIO_Quasi_Mode();   

  8.     #if DEBUG_PORT == 0
  9.         InitialUART0_Timer1_Type1(9600);            /* 9600 Baud Rate*/
  10.     #elif DEBUG_PORT == 1
  11.         InitialUART1_Timer3(9600);                  /* 9600 Baud Rate*/
  12.     #endif
  13.     Show_FW_Version_Number_To_PC();
  14.    
  15.     printf ("\n*===================================================================");
  16.     printf ("\n*  Name: N76E616 LCD Demo Code.");
  17.     printf ("\n*===================================================================\n");
  18. #endif
  19.    
  20.     LCD_Initial();

  21.     /* Change system closk source */
  22.     #if SYS_CLK_EN == 1
  23.         #if   SYS_SEL == 0
  24.             System_Clock_Select(E_HXTEN);   //Fosc = 2~16MHz XTAL
  25.         #elif SYS_SEL == 1
  26.             System_Clock_Select(E_LXTEN);   //Fosc = 32.768KHz XTAL
  27.         #elif SYS_SEL == 2
  28.             System_Clock_Select(E_HIRCEN);  //Fosc = 11.0592MHz Internal RC
  29.         #endif
  30.     #endif

  31. //    set_CLOEN;      //Clock out on P0.7
  32.   
  33.     #if SYS_DIV_EN == 1
  34.         CKDIV = SYS_DIV;                    //Fsys = Fosc / (2* CLKDIV) = Fcpu
  35.     #endif

  36.   #if 0
  37.     Set_All_GPIO_Quasi_Mode();
  38.   #else
  39.     #if   PORT0_MODE == 0                   //Quasi-Bidirectional
  40.         P0M1 = 0x00;
  41.         P0M2 = 0x00;
  42.     #elif PORT0_MODE == 1                   //Push-Pull
  43.         P0M1 = 0x00;
  44.         P0M2 = 0xFF;
  45.     #elif PORT0_MODE == 2                   //Input-Only
  46.         P0M1 = 0xFF;
  47.         P0M2 = 0x00;
  48.     #elif PORT0_MODE == 3                   //Open-Drain
  49.         P0M1 = 0xFF;
  50.         P0M2 = 0xFF;
  51.     #endif

  52.     #if   PORT1_MODE == 0                   //Quasi-Bidirectional
  53.         P1M1 = 0x00;
  54.         P1M2 = 0x00;
  55.     #elif PORT1_MODE == 1                   //Push-Pull
  56.         P1M1 = 0x00;
  57.         P1M2 = 0xFF;
  58.     #elif PORT1_MODE == 2                   //Input-Only
  59.         P1M1 = 0xFF;
  60.         P1M2 = 0x00;
  61.     #elif PORT1_MODE == 3                   //Open-Drain
  62.         P1M1 = 0xFF;
  63.         P1M2 = 0xFF;
  64.     #endif

  65.     #if   PORT2_MODE == 0                   //Quasi-Bidirectional
  66.         P2M1 = 0x00;
  67.         P2M2 = 0x00;
  68.     #elif PORT2_MODE == 1                   //Push-Pull
  69.         P2M1 = 0x00;
  70.         P2M2 = 0xFF;
  71.     #elif PORT2_MODE == 2                   //Input-Only
  72.         P2M1 = 0xFF;
  73.         P2M2 = 0x00;
  74.     #elif PORT2_MODE == 3                   //Open-Drain
  75.         P2M1 = 0xFF;
  76.         P2M2 = 0xFF;
  77.     #endif

  78.     #if   PORT3_MODE == 0                   //Quasi-Bidirectional
  79.         P3M1 = 0x00;
  80.         P3M2 = 0x00;
  81.     #elif PORT3_MODE == 1                   //Push-Pull
  82.         P3M1 = 0x00;
  83.         P3M2 = 0x7F;
  84.     #elif PORT3_MODE == 2                   //Input-Only
  85.         P3M1 = 0x7F;
  86.         P3M2 = 0x00;
  87.     #elif PORT3_MODE == 3                   //Open-Drain
  88.         P3M1 = 0x7F;
  89.         P3M2 = 0x7F;
  90.     #endif

  91.     #if   PORT4_MODE == 0                   //Quasi-Bidirectional
  92.         P4M1 = 0x00;
  93.         P4M2 = 0x00;
  94.     #elif PORT4_MODE == 1                   //Push-Pull
  95.         P4M1 = 0x00;
  96.         P4M2 = 0x7F;
  97.     #elif PORT4_MODE == 2                   //Input-Only
  98.         P4M1 = 0x7F;
  99.         P4M2 = 0x00;
  100.     #elif PORT4_MODE == 3                   //Open-Drain
  101.         P4M1 = 0x7F;
  102.         P4M2 = 0x7F;
  103.     #endif

  104.     #if   PORT5_MODE == 0                   //Quasi-Bidirectional
  105.         P5M1 = 0x00;
  106.         P5M2 = 0x00;
  107.     #elif PORT5_MODE == 1                   //Push-Pull
  108.         P5M1 = 0x00;
  109.         P5M2 = 0xFF;
  110.     #elif PORT5_MODE == 2                   //Input-Only
  111.         P5M1 = 0xFF;
  112.         P5M2 = 0x00;
  113.     #elif PORT5_MODE == 3                   //Open-Drain
  114.         P5M1 = 0xFF;
  115.         P5M2 = 0xFF;
  116.     #endif
  117.   #endif

  118.     set_ADCEN;                                                        // 使能ADC
  119.         
  120.         ADCCON0 = 0x02;                           //select ADC pin (P02)
  121.     set_P0M1_2;                               //set ADC pin is input only mode ((P02)
  122.     clr_P0M2_2;
  123.     set_P02DIDS;                              //disable digital connection  (P02 Disbale Digtal Input)
  124.         /******************************************************************************
  125.         * FUNCTION_PURPOSE: ADC Clock Divider Select
  126.         ******************************************************************************/        
  127.     set_ADCDIV2;                                                  // 決定ADC(除頻)轉換時間 ADCDIV[2:0] 111 : FADC=FSYS/128.
  128.     set_ADCDIV1;
  129.     set_ADCDIV0;
  130.         
  131.         ////***** LIRC enable part*****                切換時鐘為LIRC(10KHZ)
  132.         ////** Since LIRC is always enable, switch to LIRC directly
  133.     //set_OSC1;                               //switching system clock source if needed
  134.     //clr_OSC0;  
  135.     //while((CKEN&SET_BIT0)==1);              //check system clock switching OK or NG     
  136.     //clr_HIRCEN;                                            // HIRC Disbale
  137.                         
  138.     while(1)
  139.     {               
  140.                 P00=0;                                                        // NTC10K
  141.                 P01=1;                                                        // NTC10K VCC給電 (P00 : VCC / P01 : GND)
  142.                
  143.                 set_ADCEN;                                                // 使能ADC
  144.                 set_P0M1_2;                     // set ADC pin is input only mode ((P02)
  145.                 clr_P0M2_2;
  146.                
  147.         clr_ADCF;
  148.         set_ADCS;                       //Trigger ADC start conversion
  149.                 while(ADCF == 0);
  150.         ADCF = 0;
  151.                
  152.                 TEMP_AD = ((uint16_t)ADCRH)<<2 | ADCRL;
  153.                 TEMP_AD += 4;                                        // 補償NTC分壓電阻, 以IO管腳輸出HIGH做為VDD時, 實際電壓比板子VDD要低一點.
  154.                 TEMP = NTC_ADC2Temperature(TEMP_AD);
  155.                 Show_Temp_In_LCD(TEMP);
  156.                
  157.                 //Timer0_Delay1ms(10);
  158.                         
  159.                 clr_ADCEN;                                                // 關閉ADC
  160.                 clr_BODEN;                                                // 關閉BOD檢測
  161.                 WakeUp_Init();                                        // 定時喚醒MCU設置

  162.                 P00=0;                                                        // 將所有I/O口合理設置為輸出 HIGH or LOW, 避免洩漏電流
  163.                 P01=0;                                                        // 關閉NTC10K分壓電阻VCC電源
  164.                 P02=0;
  165.                 P03=0;
  166.                 P04=0;
  167.                 P05=0;
  168.                 P06=0;
  169.                 P07=0;
  170.                
  171.                 P20=1;                                                        //P20要嘛設為RESET,如果是設為GPIO則必須上拉, 否則會增加耗電流
  172.                 P21=1;                                                        //RXD(LED) = 1 (板載 RXD LED熄滅)
  173.                 P22=1;                                                        //TXD(LED) = 1 (板載 TXD LED熄滅)
  174.                 P23=0;
  175.                 P24=0;
  176.                 P25=0;
  177.                 P26=0;
  178.                 P27=0;
  179.                
  180.                 P30=0;
  181.                 P31=0;
  182.                 P32=0;
  183.                 P33=0;
  184.                 P34=0;
  185.                 P35=0;
  186.                 P36=0;
  187.                 P37=0;
  188.                
  189.                 P50=0;
  190.                 P51=0;
  191.                 P52=0;
  192.                 P53=0;
  193.                 P54=0;
  194.                 P55=0;
  195.                 P56=0;
  196.                 P57=0;

  197.                 set_PD;                                                        //進入掉電模式
  198.     }
  199. }






N76E616_LCD_NTC10K_Lowpower_12.3uA.rar (131.17 KB, 下载次数: 8)


(掉電模式下電流)

(掉電睡眠電流)

(掉電睡眠電流)


(喚醒後, MCU運行於10KHZ, 運行60秒平均電流 : 180.43uA)

(MCU喚醒後運行頻率 10KHZ)

(MCU喚醒後運行頻率 10KHZ)


(喚醒後, MCU運行於11.0592MHZ, 運行60秒平均電流 : 14.33uA)

(MCU喚醒後運行頻率 11.0592 MHZ)

(MCU喚醒後運行頻率 11.0592 MHZ)



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封裝)
2020-10-04_09-17-55.jpg


(自己畫了一塊PCB, 以方便測試AHT10)
2020-10-04_09-25-27.jpg


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

(與SHT20的溫度計錄儀做溫/濕度比較, 精准度已經不錯了)
2020-10-04_08-51-54.jpg

(睡眠10秒喚醒, 60秒平均電流)
N76E616低功耗_LCD_ATH10溫濕度計_10秒喚醒平均電流.jpg



AHT10傳感器資料.pdf

1.1 MB, 下载次数: 5

N76E616_LCD_TEMP&amp;HUMI_AHT10_I2C_P04.P06.rar

175.26 KB, 下载次数: 8

lidi911 发表于 2020-10-8 18:17 来自手机 | 显示全部楼层
不错,感谢楼主分享。
qcliu 发表于 2020-10-10 16:31 | 显示全部楼层
支持楼主一下
tfqi 发表于 2020-10-10 16:31 | 显示全部楼层
感谢楼主的分享
wiba 发表于 2020-10-10 16:31 | 显示全部楼层
看不太懂啊
zljiu 发表于 2020-10-10 16:32 | 显示全部楼层
功耗挺低啊
coshi 发表于 2020-10-10 16:32 | 显示全部楼层
运行的还不错
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

21

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部