找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5357|回复: 0
收起左侧

MSP430单片机带摄氏度/华氏度切换的超低功耗温度计程序 带前台与后台

[复制链接]
ID:108615 发表于 2016-3-14 19:55 | 显示全部楼层 |阅读模式
本程序是《MSP430系列单片机系统工程设计与实践》书里面的源码,(包含工程文件(例3.1) )完整例程下载:http://www.51hei.com/bbs/dpj-46245-1.html


关于本程序的详细解说大家可以点击上图下载电子书

  1. /*
  2.                
  3.                 带摄氏度/华氏度切换的超低功耗温度计程序


  4.   说明:在《温度计_基本原理》程序中,已经实现了一个温度测量和显示的系统,
  5.         但因为采样速率很快,且对基准源不加控制,耗电很大(800uA左右)。
  6.             本例中,将温度采集速度降到1秒一次,且采样间隙时间不仅关闭基
  7.         准源,还让CPU进入LPM3休眠状态,大大节省了耗电。该程序功耗仅10uA
  8.         左右,可用纽扣电池长期运行(2年)。实际上对于环境温度1秒1次采样仍
  9.         属浪费,如果降到5秒一次,功耗可下降到4uA左右(CR2032电池工作5年)。
  10.             按KEY3后,CPU进入LPM4,功耗下降到0.1uA,这是一种常用的不断电
  11.         的关机方法。
  12.             同时,该程序示例了如何例用程序库快速的完成开发任务。

  13. //=============================操作说明方法==============================

  14.     按KEY1键切换到摄氏度显示,按KEY2键切换到华氏度显示,按KEY3关机,
  15.     关机后按复位键可以开机。

  16. //===========================温度计算公式推导============================

  17.             430单片机内部温度传感器温度系数是:1.32mV/K (1.32mv/开尔文)
  18.         开尔文温度=摄氏温度+273K
  19.             在内部基准电压Vref=1200mV条件下,ADC数据格式设置为"有符号"时,
  20.         0V对应采样值0,1/2Vref(600mV)对应ADC采样值32767(忽略实际误差)。
  21.             推导出传感器输出Vsensor = (ADC采样值)/32768 * Vref/2
  22.             Vsensor除以温度系数(1.32mV/K)得到开氏温度:
  23.               DegK = ADC采样值/65536 * 1200/1.32
  24.        化简后 DegK = (ADC采样值 * 909)/65536
  25.        再减去273,得到摄氏温度:
  26.               DegC = (ADC采样值 * 909)/65536 - 273
  27.        为了能显示小数点后一位,计算过程中先扩大10倍,显示时加一位小数点。得
  28.        到最终计算公式:
  29.               DegC = (ADC采样值 * 9090)/65536 - 2730
  30.        华氏度/摄氏度的转换公式是
  31.               DegF=DegC*(9/5)+32
  32.        同样扩大10倍得到DegF=DegC*9/5+320

  33. //===========================温度校准与修正============================
  34.        上述公式是在理想状况下求得的,实际上ADC、温度传感器都存在误差。(误差
  35.   原理参《超低功耗电压表》程序),因此需要校准。在《超低功耗电压表》中提出的
  36.   校准方法在这里同样适用,即输入两个已知温度(例如0/100度),记录ADC读数,然后
  37.   根据两点坐标写出新的直线公式,即可校准。
  38.       但是该方法存在2个难点:第一是在业余条件下,标准温度产生比较困难(相对
  39.   来说,电压表程序中产生已知电压容易得多);第二是温度传感器位于片内,难以置入
  40.   标准温度中(比如冰水混合物/沸水)。
  41.       因此,这里提出一种相对简单的近似校准方法。该温度计大部分情况测量的是室
  42.   温附近的范围(按0-50度考虑),而传感器的输出比例系数是按绝对零度开始的,因此微
  43.   小的比例误差乘以273都是不可忽略的。%2的比例误差,在27度下(300K)会造成7.92mV
  44.   误差,约6度。因为难以产生标准温度,所以比例系数难以校准;但偏移误差很容易通过
  45.   显示值和普通温度计示数之差得到。我们可以将所有的误差都折算成偏移误差,这样虽
  46.   然比例误差无法完全消除,但因为测温范围不大,影响也相对小得多。
  47.       在25度左右的室温下,抄下430显示的温度标与准温度计的温度差T_OFFSET,在显示
  48.   的时候将这个误差扣除。按0-50度量程考虑,25度必然是准确的,按量程25度程正负25
  49.   K计算,2%比例误差造成的温度误差只有正负0.5度,精度已经足够高了。
  50.      
  51. //=========================================================================
  52.   注意事项:用手触摸芯片表面可以观察到显示温度立刻上升。但请注意430单片机
  53.             属于静电敏感芯片,触摸芯片之前一定要先用手接触一下大地(水管、
  54.             电脑机箱等)再捏住电路板的GND端子(左下角),另一只手才可触摸芯片。

  55.   (C)西安电子科技大学 测控技术与仪器教研中心   编 写:谢 楷 2020/02/20
  56.   
  57. */
  58. //
  59. //                   MSP430FE425
  60. //             ----------------------
  61. //            |                   XIN|-
  62. //            |                      | 32kHz
  63. //            |RST               XOUT|-
  64. //            |                      |    +----------------------+
  65. //            |A0.6+ -|        S0-S15|--->|   SoftBaugh LCD_048  |
  66. //            |A0.6-  |     COM0-COM3|--->|   7.1Digit,4-Mux LCD |
  67. //            |     | |              |    +----------------------+
  68. //            |     | |         VREF |---+
  69. //      (P1.5)|    \| |/             |   |
  70. //   KEY1---->|     \_/              |  -+- 100nF
  71. //            |    内部              |  -+-
  72. //            | 温度传感器           |   |
  73. //      (P1.6)|                 AVss |---+
  74. //   KEY2---->|                      |
  75. //            |                      |
  76. //            |                      |
  77. //      (P1.7)|                      |
  78. //   KEY3---->|                      |
  79. //            |                      |
  80. //*****************************************************************************
  81. #include "MSP430X42X.h"      /*430单片机寄存器头文件*/
  82. #include "LCD_Display.h"     /*LCD显示函数库头文件*/
  83. #include "BasicTimer.h"      /*基础定时器函数库头文件*/
  84. #include "ADC16.h"           /*16位ADC函数库头文件*/

  85. #define KEY1 (P1IN&BIT5)     /*KEY1=P1.5*/
  86. #define KEY2 (P1IN&BIT6)     /*KEY1=P1.6*/
  87. #define KEY3 (P1IN&BIT7)     /*KEY1=P1.7*/

  88. char Timer1s=16;             /*1秒计时累加变量*/
  89. char DegMode=1;              /*温度模式变量*/
  90. #define Mode_C 1             /*摄氏度 宏定义*/
  91. #define Mode_F 0             /*华氏度 宏定义*/

  92. #define T_OFFSET (0)         /*25度左右条件下,显示温度减去标准温度计温度*/
  93.                              /*作为校准偏移值。注意要乘10倍,10=1.0度*/
  94. /****************************************************************************
  95. * 名    称:PowerOff()
  96. * 功    能:关机
  97. * 入口参数:无
  98. * 出口参数:无
  99. * 说    明: 关机后按复位键开机。
  100. ****************************************************************************/
  101. void PowerOff()
  102. {
  103.    LCD_Clear();
  104.    LCD_DisplayChar(BR,5);   
  105.    LCD_DisplayChar(OO,4);
  106.    LCD_DisplayChar(FF,3);  //显示 '-OFF-'
  107.    LCD_DisplayChar(FF,2);   
  108.    LCD_DisplayChar(BR,1);  
  109.    Cpu_SleepDelay(32);     //'-OFF-' 停留2秒
  110.    LCD_OFF();              //关闭LCD
  111.    _DINT();                //禁止所有中断(禁止唤醒CPU)
  112.    LPM4;                   //进入LPM4休眠(最省电的模式,0.1uA)
  113.                            //只有复位才能唤醒CPU,重新执行程序
  114.    _NOP(); //程序永远不会运行到这一行
  115. }
  116. /****************************************************************************
  117. * 名    称:main()主程序
  118. * 功    能:每1秒采集温度一次并显示;每1/16秒扫描一次按键并处理。
  119. * 入口参数:无
  120. * 出口参数:无
  121. ****************************************************************************/
  122. void main( void )
  123. { int i;
  124.   int ADC_Result=0;
  125.   int DegC;int DegF;
  126.   WDTCTL=WDTPW+WDTHOLD;  //停止看门狗
  127.   FLL_CTL0|=XCAP18PF;          //配置晶振负载电容
  128.   P1DIR|=BIT0+BIT1+BIT2+BIT3+BIT4;
  129.   P2DIR|=BIT0+BIT1+BIT2+BIT3;       //悬空的IO口要置为输出
  130.   P1OUT =0;                         //不确定电平会造成IO耗电
  131.   P2OUT =0;   
  132.   BT_Init(16);     //BasicTimer设置为1/16秒中断(唤醒)CPU一次
  133.   LCD_Init();      //LCD初始化
  134.   UART_Init(2400,n,8,1);
  135.   ADC16_Init(0,6,'S',1);//ADC16初始化,设置ADC0采样温度传感器,有符号,增益=1
  136.   while(1)
  137.   {
  138.     Cpu_SleepWaitBT();//CPU休眠,等待被BasicTimer唤醒
  139.     //-----------以下代码1/16秒运行一次--------------
  140.     if(KEY1==0) DegMode=Mode_C;  //如果KEY1被按下,切换成摄氏度显示模式
  141.     if(KEY2==0) DegMode=Mode_F;  //如果KEY2被按下,切换成华氏度显示模式
  142.     if(KEY3==0) PowerOff();      //如果KEY3被按下,关机
  143.     Timer1s++;                   //1秒累加计数
  144.     if(Timer1s>=16)              //16次累加=1秒
  145.     {
  146.        Timer1s=0;
  147.     //-----------以下代码1秒运行一次-----------------
  148.        ADC16_VrefOn();           //打开基准源
  149.        for(i=0;i<30;i++);       //略等待,等基准稳定
  150.        ADC_Result=ADC16_Sample(0,1);//采样ADC0,单次采样
  151.        ADC16_VrefOff();          //关闭基准源
  152.        DegC=((long int)ADC_Result * 9090)/65536 - 2730;//计算摄氏度
  153.        DegC-=T_OFFSET;            //扣除校准偏移量
  154.        DegF=DegC*9/5+320;                              //计算华氏度
  155.        if(DegMode==Mode_C)       //如果处于摄氏度显示模式
  156.        {
  157.          LCD_DisplayDecimal(DegC,1); //显示摄氏度,带1位小数
  158.          LCD_InsertChar(DT);         
  159.          LCD_InsertChar(CC);         // 尾部添加单位: 'C  
  160.        }
  161.        if(DegMode==Mode_F)       //如果处于华氏度显示模式
  162.        {
  163.          LCD_DisplayDecimal(DegF,1);//显示摄氏度,带1位小数
  164.          LCD_InsertChar(DT);
  165.          LCD_InsertChar(FF);     // 尾部添加单位: 'F
  166.        }        
  167.     }
  168.   }
  169. }
复制代码



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表