G2553里面有没有温度传感器啊??

2019-03-24 09:42发布

有的话怎么设置呢? 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
19条回答
寒雪剑91
1楼-- · 2019-03-26 04:06
 精彩回答 2  元偷偷看……
457887107
2楼-- · 2019-03-26 07:24
  1. /*这是2012.1.3在官方网站http://processors.wiki.ti.com/index.php?title=MSP430_LaunchPad_(MSP-EXP430G2)#Complete_Projects 下载的,版本号:slac435b
  2. *中文为本人http://wangfuchong.com添加的注释,切记不一定正确,仅供尽可能地快速了解程序的结构。
  3. ×还是有一些疑惑,总觉得有不够严谨的可能,大家帮助分析。
  4. * main.c
  5. *
  6. * MSP-EXP430G2-LaunchPad User Experience Application
  7. *
  8. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
  9. *
  10. *
  11. *  Redistribution and use in source and binary forms, with or without
  12. *  modification, are permitted provided that the following conditions
  13. *  are met:
  14. *
  15. *    Redistributions of source code must retain the above copyright
  16. *    notice, this list of conditions and the following disclaimer.
  17. *
  18. *    Redistributions in binary form must reproduce the above copyright
  19. *    notice, this list of conditions and the following disclaimer in the
  20. *    documentation and/or other materials provided with the   
  21. *    distribution.
  22. *
  23. *    Neither the name of Texas Instruments Incorporated nor the names of
  24. *    its contributors may be used to endorse or promote products derived
  25. *    from this software without specific prior written permission.
  26. *
  27. *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  28. *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  29. *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  30. *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  31. *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  32. *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  33. *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  34. *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  35. *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36. *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  37. *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */


  40. /******************************************************************************
  41. *                  MSP-EXP430G2-LaunchPad User Experience Application
  42. *
  43. * 1. Device starts up in LPM3 + blinking LED to indicate device is alive   
  44. *    + Upon first button press, device transitions to application mode
  45. * 2. Application Mode
  46. *    + Continuously sample ADC Temp Sensor channel, compare result against
  47. *      initial value        
  48. *    + Set PWM based on measured ADC offset: Red LED for positive offset, Green
  49. *      LED for negative offset
  50. *    + Transmit temperature value via TimerA UART to PC  
  51. *    + Button Press --> Calibrate using current temperature  
  52. *                       Send character '? via UART, notifying PC
  53. *
  54. * Changes:
  55. *
  56. * 1.2  + Updated register naming conventions to reflect latest standard by TI
  57. *                  e.g.: CCR0 --> TACCR0, CCTL0 --> TACCTL0
  58. *             + Changed method to capture TAR value into TACCR0 by using capture a
  59. *               SW-triggered event. [Changing TACCR input from GND to VCC]
  60. ×     1.2是与版本slac435a相比新更改的部分
  61. * 1.1  + LED1 & LED2 labels changed so that Green LED(LED2) indicates sampled
  62. *        temperature colder than calibrated temperature and vice versa
  63. *        with Red LED (LED1).
  64. *      + Turn off peripheral function of TXD after transmitting byte to
  65. *        eliminate the extra glitch at the end of UART transmission
  66. * 1.0  Initial Release Version
  67. *
  68. * Texas Instruments, Inc.
  69. ******************************************************************************/
  70.   
  71. #include  "msp430g2231.h"

  72. #define     LED1                  BIT0  //绿灯,BIT0,BIT6之类的是宏定义,请在头文件"msp430g2231.h"中查看
  73. #define     LED2                  BIT6  //红灯,参见MSP-EXP430G2 LaunchPad Experimenter Board User's Guide
  74. #define     LED_DIR               P1DIR
  75. #define     LED_OUT               P1OUT



  76. #define     BUTTON                BIT3  //P1.3为板上按键S2
  77. #define     BUTTON_OUT            P1OUT //端口输出寄存器
  78. #define     BUTTON_DIR            P1DIR //端口方向控制寄存器
  79. #define     BUTTON_IN             P1IN  //端口输入寄存器
  80. #define     BUTTON_IE             P1IE  //端口中断允许寄存器
  81. #define     BUTTON_IES            P1IES //端口中断触发沿控制寄存器
  82. #define     BUTTON_IFG            P1IFG //端口中断标志寄存器
  83. #define     BUTTON_REN            P1REN //端口上下拉电阻使能控制寄存器

  84. #define     TXD                   BIT1                      // TXD on P1.1
  85. #define     RXD                   BIT2                      // RXD on P1.2

  86. #define     APP_STANDBY_MODE      0 //待机模式标志,也就是接上电源(或USB)后红绿灯交替闪的状态
  87. #define     APP_APPLICATION_MODE  1 //应用模式标志,也就是待机模式时按按键后进入的状态,也就是测量温度

  88. #define     TIMER_PWM_MODE        0
  89. #define     TIMER_UART_MODE       1 //串口模式状态
  90. #define     TIMER_PWM_PERIOD      2000  
  91. #define     TIMER_PWM_OFFSET      20

  92. #define     TEMP_SAME             0
  93. #define     TEMP_HOT              1
  94. #define     TEMP_COLD             2

  95. #define     TEMP_THRESHOLD        5  

  96. //   Conditions for 9600/4=2400 Baud SW UART, SMCLK = 1MHz
  97. #define     Bitime_5              0x05*4                      // ~ 0.5 bit length + small adjustment
  98. #define     Bitime                13*4//0x0D   

  99. #define     UART_UPDATE_INTERVAL  1000  //主循环次数进行一次串口发送温度值


  100. unsigned char BitCnt;


  101. unsigned char applicationMode = APP_STANDBY_MODE; //功能模式标志,初始值为待机模式
  102. unsigned char timerMode = TIMER_PWM_MODE;

  103. unsigned char tempMode;
  104. unsigned char calibrateUpdate = 0;
  105. unsigned char tempPolarity = TEMP_SAME;
  106. unsigned int TXByte;
  107.                               
  108. /* Using an 8-value moving average filter on sampled ADC values */  
  109. long tempMeasured[8]; //定义数组以计算8次10位ADC温度采样的平均值
  110. unsigned char tempMeasuredPosition=0; //温度测量值数组索引
  111. long tempAverage; //8次10位ADC温度采样的平均值

  112. long tempCalibrated, tempDifference;


  113.   
  114. void InitializeLeds(void);  //IO端口初始化,设置两颗LED对应的端口并两设置为熄灭初始状态
  115. void InitializeButton(void);  //IO端口初始化,配置按键
  116. void PreApplicationMode(void);                     //进入待机模式,红绿灯交替闪,等待按键 Blinks LED, waits for button press
  117. void ConfigureAdcTempSensor(void);  //配置温度传感器模数转换
  118. void ConfigureTimerPwm(void); //配置定位器为PWM模式
  119. void ConfigureTimerUart(void);  //配置定时器为Uart模式
  120. void Transmit(void);  //串口发送子程序
  121. void InitializeClocks(void);  //初始化时钟系统


  122. void main(void)
  123. {
  124.   unsigned int uartUpdateTimer = UART_UPDATE_INTERVAL;  //主循环次数进行一次串口发送温度值
  125.   unsigned char i;

  126.   WDTCTL = WDTPW + WDTHOLD;                 // 停止看门狗 Stop WDT

  127.   InitializeClocks(); //初始化时钟系统
  128.   InitializeButton(); //配置按键
  129.   InitializeLeds(); //设置端口并两设置两颗LED对应为熄灭初始状态
  130.   PreApplicationMode();                     //进入待机模式,红绿灯交替闪,等待按键 Blinks LEDs, waits for button press
  131.   //执行PreApplicationMode()将进入低功耗模式,程序停止在此,直到有按键按下
  132.   
  133.   /* 进入应用模式 Application Mode begins */
  134.   applicationMode = APP_APPLICATION_MODE; //功能模式标志变成应用模式
  135.   ConfigureAdcTempSensor(); //配置温度传感器模数转换
  136.   ConfigureTimerPwm();  //配置定位器PWM模式
  137.    
  138.   __enable_interrupt();                     //使能全局中断 Enable interrupts.
  139.   
  140.   /* Main Application Loop */
  141.   while(1)
  142.   {   
  143.     ADC10CTL0 |= ENC + ADC10SC;             //ADC使能,ADC开始转换一次 Sampling and conversion start
  144.     __bis_SR_register(CPUOFF + GIE);        //进入省电模式LPM0,等待AD转换完成中断 LPM0 with interrupts enabled
  145.    
  146.    
  147.     /* Moving average filter out of 8 values to somewhat stabilize sampled ADC */
  148.     tempMeasured[tempMeasuredPosition++] = ADC10MEM;  //将温度采样值存入温度值数组下一位
  149.     if (tempMeasuredPosition == 8)  
  150.       tempMeasuredPosition = 0; 复位温度采样值数组索引
  151.     tempAverage = 0;
  152.     for (i = 0; i < 8; i++)
  153.       tempAverage += tempMeasured[i]; //累加温度采样值数组各值
  154.     tempAverage >>= 3;  //除以8得到平均值   Divide by 8 to get average
  155.    
  156.     if ((--uartUpdateTimer == 0) || calibrateUpdate ) //如果主循环了UART_UPDATE_INTERVAL次或者参考温度按键按过
  157.     {
  158.       ConfigureTimerUart();
  159.       if (calibrateUpdate)
  160.       {
  161.         TXByte = 248;                       //  A character with high value, outside of temp range
  162.         Transmit(); //串口发送值248表示按键按下进行了校准参考
  163.         calibrateUpdate = 0;  //复位参考温度校准标志变量
  164.       }   
  165.       TXByte = (unsigned char)( ((tempAverage - 630) * 761) / 1024 ); //计算温度华氏值
  166.          
  167.       Transmit(); //串口发送华氏温度值
  168.       
  169.       uartUpdateTimer = UART_UPDATE_INTERVAL; //复位循环计数变量
  170.       ConfigureTimerPwm();  //配置定时器回PWM模式   
  171.     }
  172.    
  173.     tempDifference = tempAverage - tempCalibrated;  //计算相对于参考温度的差值
  174.     if (tempDifference < -TEMP_THRESHOLD) //如果采样温度值低于参考温度值差值TEMP_THRESHOLD
  175.     {
  176.       tempDifference = -tempDifference; //差值取正
  177.       tempPolarity = TEMP_COLD; //极性变量设为值TEMP_COLD
  178.       LED_OUT &= ~ LED1;  //LED1绿灯置灭
  179.     }
  180.     else
  181.     if (tempDifference > TEMP_THRESHOLD)  //如果采样温度值高于参考温度值差值TEMP_THRESHOLD
  182.     {
  183.       tempPolarity = TEMP_HOT;  //极性变量设为值TEMP_COLD
  184.       LED_OUT &= ~ LED2;  //LED2红灯置灭
  185.     }
  186.     else  //如果相对于参考温度值偏差没有超过阈值TEMP_THRESHOLD
  187.     {
  188.       tempPolarity = TEMP_SAME; //性变量设为值TEMP_SAME
  189.       TACCTL0 &= ~CCIE; //关TACCTL0中断使能
  190.       TACCTL1 &= ~CCIE; //关TACCTL1中断使能
  191.       LED_OUT &= ~(LED1 + LED2);  //置两灯皆灭
  192.     }
  193.    
  194.     if (tempPolarity != TEMP_SAME)  //如果相对于参考温度值偏差超过阈值TEMP_THRESHOLD
  195.     {      
  196.       tempDifference <<= 3; //温度偏差值乘以8
  197.       tempDifference += TIMER_PWM_OFFSET; //加上一个偏置值
  198.       TACCR1 = ( (tempDifference) < (TIMER_PWM_PERIOD-1) ? (tempDifference) : (TIMER_PWM_PERIOD-1) ); //置TACCR1,最大为TIMER_PWM_PERIOD-1。
  199.       //TACCR1值控制亮的时间,定时器计数到TACCR1在中断中将关闭灯,在TACCR0中断中亮灯
  200.       TACCTL0 |= CCIE;  //开TACCTL0中断使能
  201.       TACCTL1 |= CCIE;  //开TACCTL1中断使能
  202.     }   
  203.   } //返回主循环
  204. }

  205. //进入待机模式,红绿灯交替闪,等待按键
  206. void PreApplicationMode(void)
  207. {   
  208.   LED_DIR |= LED1 + LED2; //p1.0和P1.6口为输出
  209.   LED_OUT |= LED1;                          //绿灯亮 To enable the LED toggling effect
  210.   LED_OUT &= ~LED2; //红灯灭
  211.    
  212.   BCSCTL1 |= DIVA_1;                        //辅助时钟分频设置为2 ,ACLK=6KHz   
  213.   BCSCTL3 |= LFXT1S_2;                      //辅助时钟源选择VLOCLK,12KHz  //ACLK = VLO
  214.   
  215.   TACCR0 = 1200;                             //   
  216.   TACTL = TASSEL_1 | MC_1;  //定时器时钟源选择辅助时钟ACLK,增计数模式                  // TACLK = SMCLK, Up mode.  
  217.   TACCTL1 = CCIE + OUTMOD_3;  //捕获/比较控制寄存器1设置为比较模式,输出模式为“置位/复位” ,中断允许                // TACCTL1 Capture Compare
  218.   TACCR1 = 600;  
  219.   __bis_SR_register(LPM3_bits + GIE);          // LPM0 with interrupts enabled  ??低功耗模式LPM3
  220.     //此时cpu停止,等待中断,如果是比较1中断,则进入中断程序:ta1_isr(void),因为是CC1。
  221.     //如果是按键中断,则进入PORT1_ISR(void)中断服务程序,在PORT1_ISR(void)中将退出此低功耗模式
  222. }

  223. //配置温度传感器模数转换
  224. void ConfigureAdcTempSensor(void)
  225. {
  226.   unsigned char i;
  227.   /* Configure ADC Temp Sensor Channel */
  228.   ADC10CTL1 = INCH_10 + ADC10DIV_3; //选择ADC通道为温度传感器,时钟4分频         // Temp Sensor ADC10CLK/4
  229.   ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;  // VR+ = VREF+ and VR- = VSS,采样保持时间=64×ADC10CLK周期,打开内部参考电压,打开ADC模块,ADC中断允许
  230.   __delay_cycles(1000); //延时等待ADC参考电压建立                     // Wait for ADC Ref to settle  
  231.   ADC10CTL0 |= ENC + ADC10SC; //ADC使能,ADC开始转换一次                // Sampling and conversion start
  232.   __bis_SR_register(CPUOFF + GIE);  //进入省电模式LPM0,等待AD转换完成中断          // LPM0 with interrupts enabled
  233.   tempCalibrated = ADC10MEM;
  234.   for (i=0; i < 8; i++)
  235.     tempMeasured[i] = tempCalibrated;
  236.   tempAverage = tempCalibrated; //第一次转换,平均温度取样值和校准值相等
  237. }

  238. //配置定位器为PWM模式
  239. void ConfigureTimerPwm(void)
  240. {
  241.   timerMode = TIMER_PWM_MODE;
  242.   
  243.   TACCR0 = TIMER_PWM_PERIOD;                              //   
  244.   TACTL = TASSEL_2 | MC_1;  //定时器时钟源选择辅助时钟SMCLK,增计数模式                  // TACLK = SMCLK, Up mode.
  245.   TACCTL0 = CCIE;
  246.   TACCTL1 = CCIE + OUTMOD_3;  //捕获/比较控制寄存器1设置为比较模式,输出模式为“置位/复位” ,中断允许  ??OUTMOD_3有什么用?                // TACCTL1 Capture Compare
  247.   TACCR1 = 1;
  248. }

  249. //配置定时器为Uart模式
  250. void ConfigureTimerUart(void)
  251. {
  252.   timerMode = TIMER_UART_MODE;              // Configure TimerA0 UART TX
  253.                            
  254.   TACCTL0 = OUT;  //输出为高电平                              // TXD Idle as Mark
  255.   TACTL = TASSEL_2 + MC_2 + ID_3; //定时器时钟源选择辅助时钟SMCLK,连续计数模式 ,时钟8分频            // SMCLK/8, continuous mode
  256.   P1SEL |= TXD + RXD;                       //打开P1.1,P1.2引脚特殊功能
  257.   P1DIR |= TXD;                             //P1.1端口方向为输出
  258. }

  259. //串口发送子程序 Function Transmits Character from TXByte
  260. void Transmit()
  261. {
  262.   BitCnt = 0xA; //低电平起始位+8位数据+高电平停止位共10位  // Load Bit counter, 8data + ST/SP

  263.   /* Simulate a timer capture event to obtain the value of TAR into the TACCR0 register */
  264.   //模仿捕捉模式以获得当前的TAR值赋予TACCR0
  265.   TACCTL0 = CM_1 + CCIS_2  + SCS + CAP + OUTMOD0; //上升沿捕捉,输入源为GND,输出模式置位模式           //capture on rising edge, initially set to GND as input // clear CCIFG flag
  266.   TACCTL0 |= CCIS_3;  //改变输入源为VCC,相当于输入源上升沿变化,触发捕捉//change input to Vcc, effectively rising the edge, triggering the capture action

  267.   while (!(TACCTL0 & CCIFG)); //查询TACCTL0中断标志位                                //allowing for the capturing//updating TACCR0.

  268.   TACCR0 += Bitime ;  //首位发送延时                          // Some time till first bit
  269.   TXByte |= 0x100;  //增加停止位                          // Add mark stop bit to TXByte
  270.   TXByte = TXByte << 1; //左移一位右边添加一位0表示起始位                     // Add space start bit
  271.   TACCTL0 =  CCIS0 + OUTMOD0 + CCIE;  //比较模式,OUTMOD0=OUTMOD_1输出模式为置位模式,清中断标志,中断允许          // TXD = mark = idle

  272.   while ( TACCTL0 & CCIE );   //循环,直到反复中断中完成发送                  // Wait for TX completion
  273. }



  274. //TACCR0中断专用, Timer A0 interrupt service routine
  275. #pragma vector=TIMERA0_VECTOR
  276. __interrupt void Timer_A (void)
  277. {
  278.   if (timerMode == TIMER_UART_MODE) //定时器为Uart模式
  279.   {
  280.     TACCR0 += Bitime; //TACCR0加上一位串口数据所需的计数量,准备下一次中断  // Add Offset to TACCR0
  281.     if (TACCTL0 & CCIS0)                      //为什么要? TX on CCI0B?
  282.     {
  283.       if ( BitCnt == 0) //如果全部发送完成
  284.       {         
  285.         P1SEL &= ~(TXD+RXD);  //取消引脚特殊功能
  286.         TACCTL0 &= ~ CCIE ; //关闭中断使能                   // All bits TXed, disable interrupt
  287.       }  
  288.       
  289.       else
  290.       {
  291.         TACCTL0 |=  OUTMOD2;  //注意是“或”运算 ,设置成复位模式(原来为复位OUTMOD0,现在为OUTMOD_3)                  // TX Space
  292.         if (TXByte & 0x01)  
  293.         TACCTL0 &= ~ OUTMOD2; //如果发送的是1,输出模式转为置位模式                // TX Mark
  294.         TXByte = TXByte >> 1; //右移一位,准备下一位发送
  295.         BitCnt --;  //发送位计数
  296.       }
  297.     }
  298.   }
  299.   else  //定位器为PWM模式
  300.   {
  301.     if (tempPolarity == TEMP_HOT)
  302.       LED_OUT |= LED1;  //如果相对于参考温度偏差为正,LED1绿灯置为亮
  303.     if (tempPolarity == TEMP_COLD)      
  304.       LED_OUT |= LED2;  //如果相对于参考温度偏差为负,LED2红灯置为亮
  305.     TACCTL0 &= ~CCIFG;  //清中断标志位??有必要么?不是自动清除?              
  306.   }
  307. }

  308. //TACCR1和定时器共用中断向量
  309. #pragma vector=TIMERA1_VECTOR
  310. __interrupt void ta1_isr(void)
  311. {
  312.   TACCTL1 &= ~CCIFG;  //捕获比较中断标志CCIFG。比较模式:定时器 TAR 值等于寄存器 CCR1 值时CCIFG置位。需手动清除
  313.   if (applicationMode == APP_APPLICATION_MODE)
  314.     LED_OUT &= ~(LED1 + LED2);  //如果程序运行至是应用模式,置两灯皆灭
  315.   else
  316.     LED_OUT ^= (LED1 + LED2); //如果是待机模式,异或,原来两个灯本来就是一亮一灭的,所以反复中断的效果是交替闪烁。PreApplicationMode(void)中
  317.    
  318. }

  319. void InitializeClocks(void)
  320. {

  321.   BCSCTL1 = CALBC1_1MHZ;  //用FLASH中信息存贮器A段的校准数据设置基本时钟系统控制寄存器 1                    // Set range
  322.   DCOCTL = CALDCO_1MHZ; //用FLASH中信息存贮器A段的校准数据设置 DCO 控制寄存器,设置DCO校准为1MHz,详细原理请查看G2系列芯片的Users Guide
  323.   BCSCTL2 &= ~(DIVS_3); //SMCLK为0分频DCO                     // SMCLK = DCO = 1MHz  
  324. }

  325. void InitializeButton(void)                 // Configure Push Button
  326. {
  327.   BUTTON_DIR &= ~BUTTON;  //按键对应的端口方向为输入
  328.   BUTTON_OUT |= BUTTON; //设置输出寄存器对应的按键位为1
  329.   BUTTON_REN |= BUTTON; //使能上拉电阻,因为对应的输出寄存器位为1。反之如果对应的输出寄存器位为0则自动选择下拉电阻。
  330.   BUTTON_IES |= BUTTON; //选择下降沿中断
  331.   BUTTON_IFG &= ~BUTTON;  //中断标志清零
  332.   BUTTON_IE |= BUTTON;  //按键中断允许
  333. }

  334. //设置两颗LED对应的端口并两设置为熄灭初始状态
  335. void InitializeLeds(void)
  336. {
  337.   LED_DIR |= LED1 + LED2; //P1DIR=BIT1+BIT6 p1.0和P1.6口为输出
  338.   LED_OUT &= ~(LED1 + LED2);  //两个LED低电平熄灭
  339. }

  340. /* *************************************************************
  341. * Port Interrupt for Button Press
  342. * 1. During standby mode: to exit and enter application mode
  343. * 2. During application mode: to recalibrate temp sensor
  344. * *********************************************************** */
  345. #pragma vector=PORT1_VECTOR
  346. __interrupt void PORT1_ISR(void)
  347. {   
  348.   BUTTON_IFG = 0; //清P1口所有中断标志
  349.   BUTTON_IE &= ~BUTTON; //禁止按键中断使能,防抖动,经过看门狗定时器延时在看门狗定时器中断中再打开            /* Debounce */
  350.   WDTCTL = WDT_ADLY_250;  //=(WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS0)看门狗设置为定时器模式,计数清零,时钟源为辅助时钟ACLK,定时周期为Taclk×32768
  351.   IFG1 &= ~WDTIFG;  //清看门狗定时器中断标志                 /* clear interrupt flag */
  352.   IE1 |= WDTIE;  //使能看门狗定时器中断
  353.    
  354.   if (applicationMode == APP_APPLICATION_MODE)  //如果是应用模式
  355.   {
  356.     tempCalibrated = tempAverage; //???如果中断发生在for (i = 0; i < 8; i++) tempAverage += tempMeasured[i];不是错了么?
  357.     calibrateUpdate  = 1; //参考温度校准标志变量
  358.   }
  359.   else
  360.   {
  361.     applicationMode = APP_APPLICATION_MODE; //由待机模式切换到应用模式 // Switch from STANDBY to APPLICATION MODE
  362.     __bic_SR_register_on_exit(LPM3_bits); //退出低功耗模式LPM3        
  363.   }   
  364. }

  365. // WDT Interrupt Service Routine used to de-bounce button press
  366. #pragma vector=WDT_VECTOR
  367. __interrupt void WDT_ISR(void)
  368. {
  369.     IE1 &= ~WDTIE;  //禁止看门狗定时器中断                   /* disable interrupt */
  370.     IFG1 &= ~WDTIFG;  //清看门狗定时器中断标志                 /* clear interrupt flag */
  371.     WDTCTL = WDTPW + WDTHOLD; //使看门狗关闭状态        /* put WDT back in hold state */
  372.     BUTTON_IE |= BUTTON;  //使能按键中断             /* Debouncing complete */
  373. }

  374. // ADC10 interrupt service routine
  375. #pragma vector=ADC10_VECTOR
  376. __interrupt void ADC10_ISR (void)
  377. {
  378.   __bic_SR_register_on_exit(CPUOFF);  //退出省电模式        // Return to active mode
  379. }


复制代码
457887107
3楼-- · 2019-03-26 09:05

  1.   
  2. #include  "msp430g2231.h"

  3. #define     LED1                  BIT0  //绿灯,BIT0,BIT6之类的是宏定义,请在头文件"msp430g2231.h"中查看
  4. #define     LED2                  BIT6  //红灯,参见MSP-EXP430G2 LaunchPad Experimenter Board User's Guide
  5. #define     LED_DIR               P1DIR
  6. #define     LED_OUT               P1OUT



  7. #define     BUTTON                BIT3  //P1.3为板上按键S2
  8. #define     BUTTON_OUT            P1OUT //端口输出寄存器
  9. #define     BUTTON_DIR            P1DIR //端口方向控制寄存器
  10. #define     BUTTON_IN             P1IN  //端口输入寄存器
  11. #define     BUTTON_IE             P1IE  //端口中断允许寄存器
  12. #define     BUTTON_IES            P1IES //端口中断触发沿控制寄存器
  13. #define     BUTTON_IFG            P1IFG //端口中断标志寄存器
  14. #define     BUTTON_REN            P1REN //端口上下拉电阻使能控制寄存器

  15. #define     TXD                   BIT1                      // TXD on P1.1
  16. #define     RXD                   BIT2                      // RXD on P1.2

  17. #define     APP_STANDBY_MODE      0 //待机模式标志,也就是接上电源(或USB)后红绿灯交替闪的状态
  18. #define     APP_APPLICATION_MODE  1 //应用模式标志,也就是待机模式时按按键后进入的状态,也就是测量温度

  19. #define     TIMER_PWM_MODE        0
  20. #define     TIMER_UART_MODE       1 //串口模式状态
  21. #define     TIMER_PWM_PERIOD      2000  
  22. #define     TIMER_PWM_OFFSET      20

  23. #define     TEMP_SAME             0
  24. #define     TEMP_HOT              1
  25. #define     TEMP_COLD             2

  26. #define     TEMP_THRESHOLD        5  

  27. //   Conditions for 9600/4=2400 Baud SW UART, SMCLK = 1MHz
  28. #define     Bitime_5              0x05*4                      // ~ 0.5 bit length + small adjustment
  29. #define     Bitime                13*4//0x0D   

  30. #define     UART_UPDATE_INTERVAL  1000  //主循环次数进行一次串口发送温度值


  31. unsigned char BitCnt;


  32. unsigned char applicationMode = APP_STANDBY_MODE; //功能模式标志,初始值为待机模式
  33. unsigned char timerMode = TIMER_PWM_MODE;

  34. unsigned char tempMode;
  35. unsigned char calibrateUpdate = 0;
  36. unsigned char tempPolarity = TEMP_SAME;
  37. unsigned int TXByte;
  38.                               
  39. /* Using an 8-value moving average filter on sampled ADC values */  
  40. long tempMeasured[8]; //定义数组以计算8次10位ADC温度采样的平均值
  41. unsigned char tempMeasuredPosition=0; //温度测量值数组索引
  42. long tempAverage; //8次10位ADC温度采样的平均值

  43. long tempCalibrated, tempDifference;


  44.   
  45. void InitializeLeds(void);  //IO端口初始化,设置两颗LED对应的端口并两设置为熄灭初始状态
  46. void InitializeButton(void);  //IO端口初始化,配置按键
  47. void PreApplicationMode(void);                     //进入待机模式,红绿灯交替闪,等待按键 Blinks LED, waits for button press
  48. void ConfigureAdcTempSensor(void);  //配置温度传感器模数转换
  49. void ConfigureTimerPwm(void); //配置定位器为PWM模式
  50. void ConfigureTimerUart(void);  //配置定时器为Uart模式
  51. void Transmit(void);  //串口发送子程序
  52. void InitializeClocks(void);  //初始化时钟系统


  53. void main(void)
  54. {
  55.   unsigned int uartUpdateTimer = UART_UPDATE_INTERVAL;  //主循环次数进行一次串口发送温度值
  56.   unsigned char i;

  57.   WDTCTL = WDTPW + WDTHOLD;                 // 停止看门狗 Stop WDT

  58.   InitializeClocks(); //初始化时钟系统
  59.   InitializeButton(); //配置按键
  60.   InitializeLeds(); //设置端口并两设置两颗LED对应为熄灭初始状态
  61.   PreApplicationMode();                     //进入待机模式,红绿灯交替闪,等待按键 Blinks LEDs, waits for button press
  62.   //执行PreApplicationMode()将进入低功耗模式,程序停止在此,直到有按键按下
  63.   
  64.   /* 进入应用模式 Application Mode begins */
  65.   applicationMode = APP_APPLICATION_MODE; //功能模式标志变成应用模式
  66.   ConfigureAdcTempSensor(); //配置温度传感器模数转换
  67.   ConfigureTimerPwm();  //配置定位器PWM模式
  68.    
  69.   __enable_interrupt();                     //使能全局中断 Enable interrupts.
  70.   
  71.   /* Main Application Loop */
  72.   while(1)
  73.   {   
  74.     ADC10CTL0 |= ENC + ADC10SC;             //ADC使能,ADC开始转换一次 Sampling and conversion start
  75.     __bis_SR_register(CPUOFF + GIE);        //进入省电模式LPM0,等待AD转换完成中断 LPM0 with interrupts enabled
  76.    
  77.    
  78.     /* Moving average filter out of 8 values to somewhat stabilize sampled ADC */
  79.     tempMeasured[tempMeasuredPosition++] = ADC10MEM;  //将温度采样值存入温度值数组下一位
  80.     if (tempMeasuredPosition == 8)  
  81.       tempMeasuredPosition = 0; 复位温度采样值数组索引
  82.     tempAverage = 0;
  83.     for (i = 0; i < 8; i++)
  84.       tempAverage += tempMeasured[i]; //累加温度采样值数组各值
  85.     tempAverage >>= 3;  //除以8得到平均值   Divide by 8 to get average
  86.    
  87.     if ((--uartUpdateTimer == 0) || calibrateUpdate ) //如果主循环了UART_UPDATE_INTERVAL次或者参考温度按键按过
  88.     {
  89.       ConfigureTimerUart();
  90.       if (calibrateUpdate)
  91.       {
  92.         TXByte = 248;                       //  A character with high value, outside of temp range
  93.         Transmit(); //串口发送值248表示按键按下进行了校准参考
  94.         calibrateUpdate = 0;  //复位参考温度校准标志变量
  95.       }   
  96.       TXByte = (unsigned char)( ((tempAverage - 630) * 761) / 1024 ); //计算温度华氏值
  97.          
  98.       Transmit(); //串口发送华氏温度值
  99.       
  100.       uartUpdateTimer = UART_UPDATE_INTERVAL; //复位循环计数变量
  101.       ConfigureTimerPwm();  //配置定时器回PWM模式   
  102.     }
  103.    
  104.     tempDifference = tempAverage - tempCalibrated;  //计算相对于参考温度的差值
  105.     if (tempDifference < -TEMP_THRESHOLD) //如果采样温度值低于参考温度值差值TEMP_THRESHOLD
  106.     {
  107.       tempDifference = -tempDifference; //差值取正
  108.       tempPolarity = TEMP_COLD; //极性变量设为值TEMP_COLD
  109.       LED_OUT &= ~ LED1;  //LED1绿灯置灭
  110.     }
  111.     else
  112.     if (tempDifference > TEMP_THRESHOLD)  //如果采样温度值高于参考温度值差值TEMP_THRESHOLD
  113.     {
  114.       tempPolarity = TEMP_HOT;  //极性变量设为值TEMP_COLD
  115.       LED_OUT &= ~ LED2;  //LED2红灯置灭
  116.     }
  117.     else  //如果相对于参考温度值偏差没有超过阈值TEMP_THRESHOLD
  118.     {
  119.       tempPolarity = TEMP_SAME; //性变量设为值TEMP_SAME
  120.       TACCTL0 &= ~CCIE; //关TACCTL0中断使能
  121.       TACCTL1 &= ~CCIE; //关TACCTL1中断使能
  122.       LED_OUT &= ~(LED1 + LED2);  //置两灯皆灭
  123.     }
  124.    
  125.     if (tempPolarity != TEMP_SAME)  //如果相对于参考温度值偏差超过阈值TEMP_THRESHOLD
  126.     {      
  127.       tempDifference <<= 3; //温度偏差值乘以8
  128.       tempDifference += TIMER_PWM_OFFSET; //加上一个偏置值
  129.       TACCR1 = ( (tempDifference) < (TIMER_PWM_PERIOD-1) ? (tempDifference) : (TIMER_PWM_PERIOD-1) ); //置TACCR1,最大为TIMER_PWM_PERIOD-1。
  130.       //TACCR1值控制亮的时间,定时器计数到TACCR1在中断中将关闭灯,在TACCR0中断中亮灯
  131.       TACCTL0 |= CCIE;  //开TACCTL0中断使能
  132.       TACCTL1 |= CCIE;  //开TACCTL1中断使能
  133.     }   
  134.   } //返回主循环
  135. }

  136. //进入待机模式,红绿灯交替闪,等待按键
  137. void PreApplicationMode(void)
  138. {   
  139.   LED_DIR |= LED1 + LED2; //p1.0和P1.6口为输出
  140.   LED_OUT |= LED1;                          //绿灯亮 To enable the LED toggling effect
  141.   LED_OUT &= ~LED2; //红灯灭
  142.    
  143.   BCSCTL1 |= DIVA_1;                        //辅助时钟分频设置为2 ,ACLK=6KHz   
  144.   BCSCTL3 |= LFXT1S_2;                      //辅助时钟源选择VLOCLK,12KHz  //ACLK = VLO
  145.   
  146.   TACCR0 = 1200;                             //   
  147.   TACTL = TASSEL_1 | MC_1;  //定时器时钟源选择辅助时钟ACLK,增计数模式                  // TACLK = SMCLK, Up mode.  
  148.   TACCTL1 = CCIE + OUTMOD_3;  //捕获/比较控制寄存器1设置为比较模式,输出模式为“置位/复位” ,中断允许                // TACCTL1 Capture Compare
  149.   TACCR1 = 600;  
  150.   __bis_SR_register(LPM3_bits + GIE);          // LPM0 with interrupts enabled  ??低功耗模式LPM3
  151.     //此时cpu停止,等待中断,如果是比较1中断,则进入中断程序:ta1_isr(void),因为是CC1。
  152.     //如果是按键中断,则进入PORT1_ISR(void)中断服务程序,在PORT1_ISR(void)中将退出此低功耗模式
  153. }

  154. //配置温度传感器模数转换
  155. void ConfigureAdcTempSensor(void)
  156. {
  157.   unsigned char i;
  158.   /* Configure ADC Temp Sensor Channel */
  159.   ADC10CTL1 = INCH_10 + ADC10DIV_3; //选择ADC通道为温度传感器,时钟4分频         // Temp Sensor ADC10CLK/4
  160.   ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;  // VR+ = VREF+ and VR- = VSS,采样保持时间=64×ADC10CLK周期,打开内部参考电压,打开ADC模块,ADC中断允许
  161.   __delay_cycles(1000); //延时等待ADC参考电压建立                     // Wait for ADC Ref to settle  
  162.   ADC10CTL0 |= ENC + ADC10SC; //ADC使能,ADC开始转换一次                // Sampling and conversion start
  163.   __bis_SR_register(CPUOFF + GIE);  //进入省电模式LPM0,等待AD转换完成中断          // LPM0 with interrupts enabled
  164.   tempCalibrated = ADC10MEM;
  165.   for (i=0; i < 8; i++)
  166.     tempMeasured[i] = tempCalibrated;
  167.   tempAverage = tempCalibrated; //第一次转换,平均温度取样值和校准值相等
  168. }

  169. //配置定位器为PWM模式
  170. void ConfigureTimerPwm(void)
  171. {
  172.   timerMode = TIMER_PWM_MODE;
  173.   
  174.   TACCR0 = TIMER_PWM_PERIOD;                              //   
  175.   TACTL = TASSEL_2 | MC_1;  //定时器时钟源选择辅助时钟SMCLK,增计数模式                  // TACLK = SMCLK, Up mode.
  176.   TACCTL0 = CCIE;
  177.   TACCTL1 = CCIE + OUTMOD_3;  //捕获/比较控制寄存器1设置为比较模式,输出模式为“置位/复位” ,中断允许  ??OUTMOD_3有什么用?                // TACCTL1 Capture Compare
  178.   TACCR1 = 1;
  179. }

  180. //配置定时器为Uart模式
  181. void ConfigureTimerUart(void)
  182. {
  183.   timerMode = TIMER_UART_MODE;              // Configure TimerA0 UART TX
  184.                            
  185.   TACCTL0 = OUT;  //输出为高电平                              // TXD Idle as Mark
  186.   TACTL = TASSEL_2 + MC_2 + ID_3; //定时器时钟源选择辅助时钟SMCLK,连续计数模式 ,时钟8分频            // SMCLK/8, continuous mode
  187.   P1SEL |= TXD + RXD;                       //打开P1.1,P1.2引脚特殊功能
  188.   P1DIR |= TXD;                             //P1.1端口方向为输出
  189. }

  190. //串口发送子程序 Function Transmits Character from TXByte
  191. void Transmit()
  192. {
  193.   BitCnt = 0xA; //低电平起始位+8位数据+高电平停止位共10位  // Load Bit counter, 8data + ST/SP

  194.   /* Simulate a timer capture event to obtain the value of TAR into the TACCR0 register */
  195.   //模仿捕捉模式以获得当前的TAR值赋予TACCR0
  196.   TACCTL0 = CM_1 + CCIS_2  + SCS + CAP + OUTMOD0; //上升沿捕捉,输入源为GND,输出模式置位模式           //capture on rising edge, initially set to GND as input // clear CCIFG flag
  197.   TACCTL0 |= CCIS_3;  //改变输入源为VCC,相当于输入源上升沿变化,触发捕捉//change input to Vcc, effectively rising the edge, triggering the capture action

  198.   while (!(TACCTL0 & CCIFG)); //查询TACCTL0中断标志位                                //allowing for the capturing//updating TACCR0.

  199.   TACCR0 += Bitime ;  //首位发送延时                          // Some time till first bit
  200.   TXByte |= 0x100;  //增加停止位                          // Add mark stop bit to TXByte
  201.   TXByte = TXByte << 1; //左移一位右边添加一位0表示起始位                     // Add space start bit
  202.   TACCTL0 =  CCIS0 + OUTMOD0 + CCIE;  //比较模式,OUTMOD0=OUTMOD_1输出模式为置位模式,清中断标志,中断允许          // TXD = mark = idle

  203.   while ( TACCTL0 & CCIE );   //循环,直到反复中断中完成发送                  // Wait for TX completion
  204. }



  205. //TACCR0中断专用, Timer A0 interrupt service routine
  206. #pragma vector=TIMERA0_VECTOR
  207. __interrupt void Timer_A (void)
  208. {
  209.   if (timerMode == TIMER_UART_MODE) //定时器为Uart模式
  210.   {
  211.     TACCR0 += Bitime; //TACCR0加上一位串口数据所需的计数量,准备下一次中断  // Add Offset to TACCR0
  212.     if (TACCTL0 & CCIS0)                      //为什么要? TX on CCI0B?
  213.     {
  214.       if ( BitCnt == 0) //如果全部发送完成
  215.       {         
  216.         P1SEL &= ~(TXD+RXD);  //取消引脚特殊功能
  217.         TACCTL0 &= ~ CCIE ; //关闭中断使能                   // All bits TXed, disable interrupt
  218.       }  
  219.       
  220.       else
  221.       {
  222.         TACCTL0 |=  OUTMOD2;  //注意是“或”运算 ,设置成复位模式(原来为复位OUTMOD0,现在为OUTMOD_3)                  // TX Space
  223.         if (TXByte & 0x01)  
  224.         TACCTL0 &= ~ OUTMOD2; //如果发送的是1,输出模式转为置位模式                // TX Mark
  225.         TXByte = TXByte >> 1; //右移一位,准备下一位发送
  226.         BitCnt --;  //发送位计数
  227.       }
  228.     }
  229.   }
  230.   else  //定位器为PWM模式
  231.   {
  232.     if (tempPolarity == TEMP_HOT)
  233.       LED_OUT |= LED1;  //如果相对于参考温度偏差为正,LED1绿灯置为亮
  234.     if (tempPolarity == TEMP_COLD)      
  235.       LED_OUT |= LED2;  //如果相对于参考温度偏差为负,LED2红灯置为亮
  236.     TACCTL0 &= ~CCIFG;  //清中断标志位??有必要么?不是自动清除?              
  237.   }
  238. }

  239. //TACCR1和定时器共用中断向量
  240. #pragma vector=TIMERA1_VECTOR
  241. __interrupt void ta1_isr(void)
  242. {
  243.   TACCTL1 &= ~CCIFG;  //捕获比较中断标志CCIFG。比较模式:定时器 TAR 值等于寄存器 CCR1 值时CCIFG置位。需手动清除
  244.   if (applicationMode == APP_APPLICATION_MODE)
  245.     LED_OUT &= ~(LED1 + LED2);  //如果程序运行至是应用模式,置两灯皆灭
  246.   else
  247.     LED_OUT ^= (LED1 + LED2); //如果是待机模式,异或,原来两个灯本来就是一亮一灭的,所以反复中断的效果是交替闪烁。PreApplicationMode(void)中
  248.    
  249. }

  250. void InitializeClocks(void)
  251. {

  252.   BCSCTL1 = CALBC1_1MHZ;  //用FLASH中信息存贮器A段的校准数据设置基本时钟系统控制寄存器 1                    // Set range
  253.   DCOCTL = CALDCO_1MHZ; //用FLASH中信息存贮器A段的校准数据设置 DCO 控制寄存器,设置DCO校准为1MHz,详细原理请查看G2系列芯片的Users Guide
  254.   BCSCTL2 &= ~(DIVS_3); //SMCLK为0分频DCO                     // SMCLK = DCO = 1MHz  
  255. }

  256. void InitializeButton(void)                 // Configure Push Button
  257. {
  258.   BUTTON_DIR &= ~BUTTON;  //按键对应的端口方向为输入
  259.   BUTTON_OUT |= BUTTON; //设置输出寄存器对应的按键位为1
  260.   BUTTON_REN |= BUTTON; //使能上拉电阻,因为对应的输出寄存器位为1。反之如果对应的输出寄存器位为0则自动选择下拉电阻。
  261.   BUTTON_IES |= BUTTON; //选择下降沿中断
  262.   BUTTON_IFG &= ~BUTTON;  //中断标志清零
  263.   BUTTON_IE |= BUTTON;  //按键中断允许
  264. }

  265. //设置两颗LED对应的端口并两设置为熄灭初始状态
  266. void InitializeLeds(void)
  267. {
  268.   LED_DIR |= LED1 + LED2; //P1DIR=BIT1+BIT6 p1.0和P1.6口为输出
  269.   LED_OUT &= ~(LED1 + LED2);  //两个LED低电平熄灭
  270. }

  271. /* *************************************************************
  272. * Port Interrupt for Button Press
  273. * 1. During standby mode: to exit and enter application mode
  274. * 2. During application mode: to recalibrate temp sensor
  275. * *********************************************************** */
  276. #pragma vector=PORT1_VECTOR
  277. __interrupt void PORT1_ISR(void)
  278. {   
  279.   BUTTON_IFG = 0; //清P1口所有中断标志
  280.   BUTTON_IE &= ~BUTTON; //禁止按键中断使能,防抖动,经过看门狗定时器延时在看门狗定时器中断中再打开            /* Debounce */
  281.   WDTCTL = WDT_ADLY_250;  //=(WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS0)看门狗设置为定时器模式,计数清零,时钟源为辅助时钟ACLK,定时周期为Taclk×32768
  282.   IFG1 &= ~WDTIFG;  //清看门狗定时器中断标志                 /* clear interrupt flag */
  283.   IE1 |= WDTIE;  //使能看门狗定时器中断
  284.    
  285.   if (applicationMode == APP_APPLICATION_MODE)  //如果是应用模式
  286.   {
  287.     tempCalibrated = tempAverage; //???如果中断发生在for (i = 0; i < 8; i++) tempAverage += tempMeasured[i];不是错了么?
  288.     calibrateUpdate  = 1; //参考温度校准标志变量
  289.   }
  290.   else
  291.   {
  292.     applicationMode = APP_APPLICATION_MODE; //由待机模式切换到应用模式 // Switch from STANDBY to APPLICATION MODE
  293.     __bic_SR_register_on_exit(LPM3_bits); //退出低功耗模式LPM3        
  294.   }   
  295. }

  296. // WDT Interrupt Service Routine used to de-bounce button press
  297. #pragma vector=WDT_VECTOR
  298. __interrupt void WDT_ISR(void)
  299. {
  300.     IE1 &= ~WDTIE;  //禁止看门狗定时器中断                   /* disable interrupt */
  301.     IFG1 &= ~WDTIFG;  //清看门狗定时器中断标志                 /* clear interrupt flag */
  302.     WDTCTL = WDTPW + WDTHOLD; //使看门狗关闭状态        /* put WDT back in hold state */
  303.     BUTTON_IE |= BUTTON;  //使能按键中断             /* Debouncing complete */
  304. }

  305. // ADC10 interrupt service routine
  306. #pragma vector=ADC10_VECTOR
  307. __interrupt void ADC10_ISR (void)
  308. {
  309.   __bic_SR_register_on_exit(CPUOFF);  //退出省电模式        // Return to active mode
  310. }


复制代码
lpmrzx
4楼-- · 2019-03-26 12:36
 精彩回答 2  元偷偷看……
chuzhitian
5楼-- · 2019-03-26 15:04
但是INCH10是在哪儿啊?在单片机内部吗??
chunyang
6楼-- · 2019-03-26 19:36
片内温度传感器是为了应对超低功耗下的便携产品中的低精度温度测量,如果参数不能满足或工艺条件不准许,那就应该外扩适当的传感器。

一周热门 更多>

相关问题

    相关文章