|
本程序是《MSP430系列單片機(jī)系統(tǒng)工程設(shè)計(jì)與實(shí)踐》書里面的源碼,(包含工程文件(例3.1) )完整例程下載:http://www.torrancerestoration.com/bbs/dpj-46245-1.html

關(guān)于本程序的詳細(xì)解說(shuō)大家可以點(diǎn)擊上圖下載電子書
- /*
-
- 帶攝氏度/華氏度切換的超低功耗溫度計(jì)程序
- 說(shuō)明:在《溫度計(jì)_基本原理》程序中,已經(jīng)實(shí)現(xiàn)了一個(gè)溫度測(cè)量和顯示的系統(tǒng),
- 但因?yàn)椴蓸铀俾屎芸�,且�?duì)基準(zhǔn)源不加控制,耗電很大(800uA左右)。
- 本例中,將溫度采集速度降到1秒一次,且采樣間隙時(shí)間不僅關(guān)閉基
- 準(zhǔn)源,還讓CPU進(jìn)入LPM3休眠狀態(tài),大大節(jié)省了耗電。該程序功耗僅10uA
- 左右,可用紐扣電池長(zhǎng)期運(yùn)行(2年)。實(shí)際上對(duì)于環(huán)境溫度1秒1次采樣仍
- 屬浪費(fèi),如果降到5秒一次,功耗可下降到4uA左右(CR2032電池工作5年)。
- 按KEY3后,CPU進(jìn)入LPM4,功耗下降到0.1uA,這是一種常用的不斷電
- 的關(guān)機(jī)方法。
- 同時(shí),該程序示例了如何例用程序庫(kù)快速的完成開發(fā)任務(wù)。
- //=============================操作說(shuō)明方法==============================
- 按KEY1鍵切換到攝氏度顯示,按KEY2鍵切換到華氏度顯示,按KEY3關(guān)機(jī),
- 關(guān)機(jī)后按復(fù)位鍵可以開機(jī)。
- //===========================溫度計(jì)算公式推導(dǎo)============================
- 430單片機(jī)內(nèi)部溫度傳感器溫度系數(shù)是:1.32mV/K (1.32mv/開爾文)
- 開爾文溫度=攝氏溫度+273K
- 在內(nèi)部基準(zhǔn)電壓Vref=1200mV條件下,ADC數(shù)據(jù)格式設(shè)置為"有符號(hào)"時(shí),
- 0V對(duì)應(yīng)采樣值0,1/2Vref(600mV)對(duì)應(yīng)ADC采樣值32767(忽略實(shí)際誤差)。
- 推導(dǎo)出傳感器輸出Vsensor = (ADC采樣值)/32768 * Vref/2
- Vsensor除以溫度系數(shù)(1.32mV/K)得到開氏溫度:
- DegK = ADC采樣值/65536 * 1200/1.32
- 化簡(jiǎn)后 DegK = (ADC采樣值 * 909)/65536
- 再減去273,得到攝氏溫度:
- DegC = (ADC采樣值 * 909)/65536 - 273
- 為了能顯示小數(shù)點(diǎn)后一位,計(jì)算過(guò)程中先擴(kuò)大10倍,顯示時(shí)加一位小數(shù)點(diǎn)。得
- 到最終計(jì)算公式:
- DegC = (ADC采樣值 * 9090)/65536 - 2730
- 華氏度/攝氏度的轉(zhuǎn)換公式是
- DegF=DegC*(9/5)+32
- 同樣擴(kuò)大10倍得到DegF=DegC*9/5+320
- //===========================溫度校準(zhǔn)與修正============================
- 上述公式是在理想狀況下求得的,實(shí)際上ADC、溫度傳感器都存在誤差。(誤差
- 原理參《超低功耗電壓表》程序),因此需要校準(zhǔn)。在《超低功耗電壓表》中提出的
- 校準(zhǔn)方法在這里同樣適用,即輸入兩個(gè)已知溫度(例如0/100度),記錄ADC讀數(shù),然后
- 根據(jù)兩點(diǎn)坐標(biāo)寫出新的直線公式,即可校準(zhǔn)。
- 但是該方法存在2個(gè)難點(diǎn):第一是在業(yè)余條件下,標(biāo)準(zhǔn)溫度產(chǎn)生比較困難(相對(duì)
- 來(lái)說(shuō),電壓表程序中產(chǎn)生已知電壓容易得多);第二是溫度傳感器位于片內(nèi),難以置入
- 標(biāo)準(zhǔn)溫度中(比如冰水混合物/沸水)。
- 因此,這里提出一種相對(duì)簡(jiǎn)單的近似校準(zhǔn)方法。該溫度計(jì)大部分情況測(cè)量的是室
- 溫附近的范圍(按0-50度考慮),而傳感器的輸出比例系數(shù)是按絕對(duì)零度開始的,因此微
- 小的比例誤差乘以273都是不可忽略的。%2的比例誤差,在27度下(300K)會(huì)造成7.92mV
- 誤差,約6度。因?yàn)殡y以產(chǎn)生標(biāo)準(zhǔn)溫度,所以比例系數(shù)難以校準(zhǔn);但偏移誤差很容易通過(guò)
- 顯示值和普通溫度計(jì)示數(shù)之差得到。我們可以將所有的誤差都折算成偏移誤差,這樣雖
- 然比例誤差無(wú)法完全消除,但因?yàn)闇y(cè)溫范圍不大,影響也相對(duì)小得多。
- 在25度左右的室溫下,抄下430顯示的溫度標(biāo)與準(zhǔn)溫度計(jì)的溫度差T_OFFSET,在顯示
- 的時(shí)候?qū)⑦@個(gè)誤差扣除。按0-50度量程考慮,25度必然是準(zhǔn)確的,按量程25度程正負(fù)25
- K計(jì)算,2%比例誤差造成的溫度誤差只有正負(fù)0.5度,精度已經(jīng)足夠高了。
-
- //=========================================================================
- 注意事項(xiàng):用手觸摸芯片表面可以觀察到顯示溫度立刻上升。但請(qǐng)注意430單片機(jī)
- 屬于靜電敏感芯片,觸摸芯片之前一定要先用手接觸一下大地(水管、
- 電腦機(jī)箱等)再捏住電路板的GND端子(左下角),另一只手才可觸摸芯片。
- (C)西安電子科技大學(xué) 測(cè)控技術(shù)與儀器教研中心 編 寫:謝 楷 2020/02/20
-
- */
- //
- // MSP430FE425
- // ----------------------
- // | XIN|-
- // | | 32kHz
- // |RST XOUT|-
- // | | +----------------------+
- // |A0.6+ -| S0-S15|--->| SoftBaugh LCD_048 |
- // |A0.6- | COM0-COM3|--->| 7.1Digit,4-Mux LCD |
- // | | | | +----------------------+
- // | | | VREF |---+
- // (P1.5)| \| |/ | |
- // KEY1---->| \_/ | -+- 100nF
- // | 內(nèi)部 | -+-
- // | 溫度傳感器 | |
- // (P1.6)| AVss |---+
- // KEY2---->| |
- // | |
- // | |
- // (P1.7)| |
- // KEY3---->| |
- // | |
- //*****************************************************************************
- #include "MSP430X42X.h" /*430單片機(jī)寄存器頭文件*/
- #include "LCD_Display.h" /*LCD顯示函數(shù)庫(kù)頭文件*/
- #include "BasicTimer.h" /*基礎(chǔ)定時(shí)器函數(shù)庫(kù)頭文件*/
- #include "ADC16.h" /*16位ADC函數(shù)庫(kù)頭文件*/
- #define KEY1 (P1IN&BIT5) /*KEY1=P1.5*/
- #define KEY2 (P1IN&BIT6) /*KEY1=P1.6*/
- #define KEY3 (P1IN&BIT7) /*KEY1=P1.7*/
- char Timer1s=16; /*1秒計(jì)時(shí)累加變量*/
- char DegMode=1; /*溫度模式變量*/
- #define Mode_C 1 /*攝氏度 宏定義*/
- #define Mode_F 0 /*華氏度 宏定義*/
- #define T_OFFSET (0) /*25度左右條件下,顯示溫度減去標(biāo)準(zhǔn)溫度計(jì)溫度*/
- /*作為校準(zhǔn)偏移值。注意要乘10倍,10=1.0度*/
- /****************************************************************************
- * 名 稱:PowerOff()
- * 功 能:關(guān)機(jī)
- * 入口參數(shù):無(wú)
- * 出口參數(shù):無(wú)
- * 說(shuō) 明: 關(guān)機(jī)后按復(fù)位鍵開機(jī)。
- ****************************************************************************/
- void PowerOff()
- {
- LCD_Clear();
- LCD_DisplayChar(BR,5);
- LCD_DisplayChar(OO,4);
- LCD_DisplayChar(FF,3); //顯示 '-OFF-'
- LCD_DisplayChar(FF,2);
- LCD_DisplayChar(BR,1);
- Cpu_SleepDelay(32); //'-OFF-' 停留2秒
- LCD_OFF(); //關(guān)閉LCD
- _DINT(); //禁止所有中斷(禁止喚醒CPU)
- LPM4; //進(jìn)入LPM4休眠(最省電的模式,0.1uA)
- //只有復(fù)位才能喚醒CPU,重新執(zhí)行程序
- _NOP(); //程序永遠(yuǎn)不會(huì)運(yùn)行到這一行
- }
- /****************************************************************************
- * 名 稱:main()主程序
- * 功 能:每1秒采集溫度一次并顯示;每1/16秒掃描一次按鍵并處理。
- * 入口參數(shù):無(wú)
- * 出口參數(shù):無(wú)
- ****************************************************************************/
- void main( void )
- { int i;
- int ADC_Result=0;
- int DegC;int DegF;
- WDTCTL=WDTPW+WDTHOLD; //停止看門狗
- FLL_CTL0|=XCAP18PF; //配置晶振負(fù)載電容
- P1DIR|=BIT0+BIT1+BIT2+BIT3+BIT4;
- P2DIR|=BIT0+BIT1+BIT2+BIT3; //懸空的IO口要置為輸出
- P1OUT =0; //不確定電平會(huì)造成IO耗電
- P2OUT =0;
- BT_Init(16); //BasicTimer設(shè)置為1/16秒中斷(喚醒)CPU一次
- LCD_Init(); //LCD初始化
- UART_Init(2400,n,8,1);
- ADC16_Init(0,6,'S',1);//ADC16初始化,設(shè)置ADC0采樣溫度傳感器,有符號(hào),增益=1
- while(1)
- {
- Cpu_SleepWaitBT();//CPU休眠,等待被BasicTimer喚醒
- //-----------以下代碼1/16秒運(yùn)行一次--------------
- if(KEY1==0) DegMode=Mode_C; //如果KEY1被按下,切換成攝氏度顯示模式
- if(KEY2==0) DegMode=Mode_F; //如果KEY2被按下,切換成華氏度顯示模式
- if(KEY3==0) PowerOff(); //如果KEY3被按下,關(guān)機(jī)
- Timer1s++; //1秒累加計(jì)數(shù)
- if(Timer1s>=16) //16次累加=1秒
- {
- Timer1s=0;
- //-----------以下代碼1秒運(yùn)行一次-----------------
- ADC16_VrefOn(); //打開基準(zhǔn)源
- for(i=0;i<30;i++); //略等待,等基準(zhǔn)穩(wěn)定
- ADC_Result=ADC16_Sample(0,1);//采樣ADC0,單次采樣
- ADC16_VrefOff(); //關(guān)閉基準(zhǔn)源
- DegC=((long int)ADC_Result * 9090)/65536 - 2730;//計(jì)算攝氏度
- DegC-=T_OFFSET; //扣除校準(zhǔn)偏移量
- DegF=DegC*9/5+320; //計(jì)算華氏度
- if(DegMode==Mode_C) //如果處于攝氏度顯示模式
- {
- LCD_DisplayDecimal(DegC,1); //顯示攝氏度,帶1位小數(shù)
- LCD_InsertChar(DT);
- LCD_InsertChar(CC); // 尾部添加單位: 'C
- }
- if(DegMode==Mode_F) //如果處于華氏度顯示模式
- {
- LCD_DisplayDecimal(DegF,1);//顯示攝氏度,帶1位小數(shù)
- LCD_InsertChar(DT);
- LCD_InsertChar(FF); // 尾部添加單位: 'F
- }
- }
- }
- }
復(fù)制代碼
|
|