基於MSP430F413水果電池供電的低功耗時鍾


  我最早接觸MSP430時候,看到書的第一頁就是一張水果電池的圖片,一直以來想做一個低功耗的可以水果電池供電的系統,畢業之后的下半年選擇MSP430F413單片機來畫了一個低功耗的板子,一直沒有調試成功,液晶顯示太暗幾乎看不到,最近又拿出來調試,更換偏壓電阻,最終更換液晶后才可以正常顯示,先看下最終效果:

最終效果

水果電池時鍾 水果電池時鍾

電路圖:

低功耗電路

調試過程

  最初調試時,先准備好蘋果一個,電池正負極(銅鋅),程序是顯示一個數字,效果如下:

水果電池

  突發奇想,用自來水試了一下,效果也是杠杠的(程序中間修改過,這是顯示較多的液晶段):

水果電池

  時鍾調試效果(這里電池沒有接入電路,調試時所用,當時沒有拿下來,用跳線帽接到水果供電的電路上):

水果電池

  剛剛調試時,萬用表測試水果電池電壓接近0.9V,短路電流25-30uA,接上電路僅顯示數字7的時候,電流12uA,4節水果電池電壓從3.4降到2.6V;水(普通自來水,每個地方水中含有離子數量不一樣,獲得電壓電流都有區別)每節電池0.8V,短路電流接近40uA。

  程序換為時鍾時,水果電池3.4V降到2.2V,大約維1個多小時,液晶完全沒有顯示,電極片換個位置重新插一下,時鍾可以繼續運行,測試電壓和新做水果電池一樣,蘋果都要變干的時候,電壓低一些,液晶明顯變暗。

水果電池

  后來,電路中提供液晶偏壓電壓的電阻有330K改為1M后,系統電流降到大約10uA,水果電池大約可以維持3-4小時,用水做的電池可以維持24小時以上

水果電池

功耗分析

  這個低功耗的電路還有優化空間,單片機的不用的引腳可以再做優化,現有線路中有一般的液晶段引腳沒有使用,卻也提供的驅動波形,這里相對現有系統應當是浪費電流最大的一部分;另外一個優化空間是4個按鍵的上拉電阻太小,10K,3V的時候,按鍵按下瞬間,電流可以達到300uA,用水果電池的時候,按鍵功能不能使用,現在調試的時候,都是先拿CR2302供電,調節好時間后,再用水果(水)電池供電。
  進一步優化功耗后,電流應當可以降到5uA以下。

程序

  按鍵程序繼續使用之前程序庫中的按鍵程序;

  RTC計時使用TI的RTC軟件庫

  段碼液晶的程序由程序庫中的數碼管程序移植而來:

    #include  <msp430x41x.h>
    #include  "segment_lcd_btl006.h"
    
    /*宏定義,數碼管a-h各段對應的比特,更換硬件只用改動以下8行*/
    #define a       0x01                            //  AAAA
    #define b       0x02                            // F    B
    #define c       0x04                            // F    B
    #define d       0x80                            //  GGGG
    #define e       0x40                            // E    C
    #define f       0x10                            // E    C
    #define g       0x20                            //  DDDD  HH
    #define h       0x08        //小數點
    
    /*用宏定義自動生成段碼表,很好的寫法,值得學習*/
    /*更換硬件無需重寫段碼表*/
    const char tab[] = {
        a + b + c + d + e + f,                  // Displays "0"
        b + c,                                  // Displays "1"
        a + b + d + e + g,                      // Displays "2"
        a + b + c + d + g,                      // Displays "3"
        b + c + f + g,                          // Displays "4"
        a + c + d + f +g,                       // Displays "5"
        a + c + d + e + f + g,                  // Displays "6"
        a + b + c,                              // Displays "7"
        a + b + c + d + e + f + g,              // Displays "8"
        a + b + c + d + f + g,                  // Displays "9"
        a + b + c + e + f + g,                  // Displays "A"
        c + d + e + f + g,                      // Displays "B"  
        a + d + e + f,                          // Displays "C"
        b + c + d + e + g,                      // Displays "D"
        a + d + e + f + g,                      // Displays "E"
        a + e + f + g,                          // Displays "F"
        a + c + d + e + f,                      // Displays "G"
        b + c + e + f + g,                      // Displays "H"  
        e + f,                                  // Displays "I"
        b + c + d + e,                          // Displays "J"
        b + d + e + f + g,                      // Displays "K"
        d + e + f,                              // Displays "L"  
        a + c + e + g,                          // Displays "M" 
        a + b + c + e + f,                      // Displays "N"   
        c + e + g,                              // Displays "n"
        c + d + e + g,                          // Displays "o"
        a + b + c + d + e + f,                  // Displays "O"
        a + b + e + f + g,                      // Displays "P"
        a + b + c + f + g,                      // Displays "Q" 
        e + g,                                  // Displays "r"
        a + c + d + f +g,                       // Displays "S"
        d + e + f + g,                          // Displays "t"
        a + e + f ,                             // Displays "T" 
        b + c + d + e + f,                      // Displays "U"
        c + d + e,                              // Displays "v" 
        b + d + f + g,                          // Displays "W"
        b + c + d + f + g,                      // Displays "Y" 
        a + b + d + e + g,                      // Displays "Z"
        g,                                      // Displays "-"
        h,                                      // Displays "."  
        0                                       // Displays " "
    }; 
    #undef a
    #undef b
    #undef c
    #undef d
    #undef e
    #undef f
    #undef g 
    
    void lcd_init()
    {
    
        // Initialize LCD
        LCDCTL = LCDP1+LCDP0+LCD4MUX+LCDON;       // 4-Mux LCD, segments S0-S23
        BTCTL  = BTFRFQ1;                         // Set freqLCD = ACLK/128
        P5SEL  = 0xFC;                            // Set Rxx and COM pins for LCD
    
        // Clear LCD memory to clear display
        for (int i=0; i<12; i++)
        {
            LCDMEM[i] = 0x00;
        }
    }
    
    void lcd_clear()
    {    
        for (int i=0; i<12; i++)
        {
            LCDMEM[i] = 0x00;
        }
    }
    
    //不影響小數點或者冒號
    void lcd_display_char(char ch,char addr)
    {
        addr = addr*2+2;
        LCDMEM[addr] = ((tab[ch]&0x0f)<<4)|(LCDMEM[addr]&0x80);
        LCDMEM[addr+1] = (tab[ch]&0xf0);//|(LCDMEM[addr+1]&0x80)
    }

  計時程序,每隔1s中斷運行一次,計時則秒增1,設置則顯示對應設置界面:

    #include  <msp430x41x.h>
    #include  "RTC_Calendar.h"
    #include  "RTC_TA.h"
    #include "segment_lcd_btl006.h"
    #include "time.h"
    
    char state = 0;  //1-6:年月日 時分秒
    
    void time_init()
    {
        lcd_init();
        setDate(2015,9,13);
        setTime( 0, 0, 0, 1);                  // initialize time to 12:00:00 AM
        TACCR0 = 32768-1;
        TACTL = TASSEL_1+MC_1;                    // ACLK, upmode
        TACCTL0 |= CCIE;                          // enable TA0CCRO interrupt
    }
    
    //兩位時間顯示,格式十六進制高地位 地址0低位,1高位
    void time_display(char time,char addr)
    {
        addr = addr*2;
        lcd_display_char(time>>4,addr+1);
        lcd_display_char((time&0x0f),addr);  
    }
    
    //4位時間顯示,year,格式十六進制各個位 
    void year_display(int year)
    {
        lcd_display_char(year>>12,3);
        lcd_display_char((year>>8)&0x0f,2);  
        lcd_display_char((year>>4)&0x0f,1);  
        lcd_display_char((year)&0x0f,0);  
    }
    
    //計時標志,冒號閃爍
    void tick()
    {
        LCDMEM[1]&=~0X80;
        LCDMEM[2]^=0x80;
        time_display(get24Hour(),1);
        time_display(TI_minute,0);
    }
    
    void setting()
    {
        LCDMEM[1]=0X80;
        switch(state)
            {
                case 1:
                    year_display(TI_year);
                    break;
                case 2:
                    time_display(TI_month==9?TI_month+7:TI_month+1,1);
                    break;
                case 3:
                    time_display(TI_day,0);
                    break;
                case 4:
                    time_display(get24Hour(),1);
                    LCDMEM[2]|=0x80;
                    break;
                case 5:
                    time_display(TI_minute,0);
                    LCDMEM[2]|=0x80;
                    break;
                case 6:
                    time_display(TI_second,0);
                    LCDMEM[2]|=0x80;
                    break;
                default:
                    state = 0;
                    break;
            }
    }
    
    
    // Timer A0 interrupt service routine
    #pragma vector=TIMERA0_VECTOR
    __interrupt void Timer_A (void)
    {
        incrementSeconds();
        if(state == 0)
        {
            tick();
        }
        else
        {
            setting();
        }
        __bic_SR_register_on_exit(LPM3_bits);
    }

  主函數,根據按鍵更改操作狀態,並且設置時間值:

    #include  <msp430x41x.h>
    #include  "RTC_Calendar.h"
    #include  "RTC_TA.h"
    #include  "segment_lcd_btl006.h"
    #include "time.h"
    #include "key.h"
    
    int main( void )
    {
      // Stop watchdog timer to prevent time out reset
        WDTCTL = WDTPW + WDTHOLD;
        FLL_CTL0 |= XCAP14PF;                     // Configure load caps
        time_init();
        KeyInit();
        __bis_SR_register(GIE);
    
        while(1)
        {
            __bis_SR_register(LPM3_bits);           // enter LPM3, clock will be updated
            char key = ReadKey();
            if(key=='0'&&state==1)
            {
                setDate(2015,TI_month>9?TI_month-5:TI_month+1,(TI_day>>4)*10+(TI_day&0x0f));
            }
            if(key=='1')
            {
                if(++state == 7)
                {
                    state = 0;
                }        
            }
            if(key=='2')
            {
                switch(state)
                {
                    case 1:
                        incrementYears();
                        break;
                    case 2:
                        incrementMonths();
                        break;
                    case 3:
                        incrementDays();
                        break;
                    case 4:
                        incrementHours();
                        break;
                    case 5:
                        incrementMinutes();
                        break;
                    case 6:
                        incrementSeconds();
                        break;
                    default:
                        state = 0;
                        break;
                }
            }
            if(state!=0)
            {
                lcd_clear();
                setting();
            }
            else
            {
                tick();
            }
        }
    
        return 0;
    }

最新運行效果

  上午剛剛拍的,昨天(2015-10-02)晚上,發覺液晶有些暗,水里面加了一些鹽,顯示效果更好一些,運行時間應該也會更久:

水果電池

水果電池


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM