历史上的今天
返回首页

历史上的今天

今天是:2025年02月08日(星期六)

正在发生

2020年02月08日 | msp430g2553单片机 感应温度的呼吸灯

2020-02-08 来源:eefocus

//程序烧进板子后先进入led灯交替闪烁的待机模式;按下按键后,进入应用模式,绿灯开始呼吸;此时温度上升后绿灯呼吸加快,温度下降后呼吸又会变慢。当温度过高时红灯亮


#include  "msp430g2553.h"


#define     LED1                  BIT0


#define     LED2                  BIT6


#define     LED_DIR               P1DIR


#define     LED_OUT               P1OUT


#define     BUTTON                BIT3  //P1.3为板上按键S2


#define     BUTTON_OUT            P1OUT //端口输出寄存器


#define     BUTTON_DIR            P1DIR //端口方向控制寄存器


#define     BUTTON_IN             P1IN  //端口输入寄存器


#define     BUTTON_IE             P1IE  //端口中断允许寄存器


#define     BUTTON_IES            P1IES //端口中断触发沿控制寄存器


#define     BUTTON_IFG            P1IFG //端口中断标志寄存器


#define     BUTTON_REN            P1REN //端口上下拉电阻使能控制寄存器


#define     APP_STANDBY_MODE      0 //待机模式标志,也就是接上电源(或USB)后红绿灯交替闪的状态


#define     APP_APPLICATION_MODE  1 //应用模式标志,也就是待机模式时按按键后进入的状态,也就是测量温度


#define     TIMER_PWM_MODE        0


long     TIMER_PWM_PERIOD   =   5000;


#define     TIMER_PWM_OFFSET      20


#define     TEMP_SAME             0


#define     TEMP_HOT              1


#define     TEMP_COLD             2


#define     TEMP_THRESHOLD        0


//   Conditions for 9600/4=2400 Baud SW UART, SMCLK = 1MHz


#define     Bitime_5              0x05*4                      // ~ 0.5 bit length + small adjustment


#define     Bitime                13*4//0x0D


unsigned char BitCnt;


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


unsigned char timerMode = TIMER_PWM_MODE;


unsigned char tempMode;


unsigned char calibrateUpdate = 0;


unsigned char tempPolarity = TEMP_SAME;


unsigned int TXByte;


long tempMeasured[8]; //定义数组以计算8次10位ADC温度采样的平均值


unsigned char tempMeasuredPosition=0; //温度测量值数组索引


long tempAverage; //8次10位ADC温度采样的平均值


long tempCalibrated, tempDifference;


void InitializeLeds(void);  //IO端口初始化,设置两颗LED对应的端口并两设置为熄灭初始状态


void InitializeButton(void);  //IO端口初始化,配置按键


void PreApplicationMode(void);                     //进入待机模式,红绿灯交替闪,等待按键 Blinks LED, waits for button press


void ConfigureAdcTempSensor(void);  //配置温度传感器模数转换


void ConfigureTimerPwm(void); //配置定位器为PWM模式


void InitializeClocks(void);  //初始化时钟系统


void main(void)


{


  unsigned char i;


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


  InitializeClocks(); //初始化时钟系统


  InitializeButton(); //配置按键


  InitializeLeds(); //设置端口并两设置两颗LED对应为熄灭初始状态


  PreApplicationMode();


  applicationMode = APP_APPLICATION_MODE; //功能模式标志变成应用模式


  ConfigureAdcTempSensor(); //配置温度传感器模数转换


  ConfigureTimerPwm();  //配置定位器PWM模式


  __enable_interrupt();                     //使能全局中断 Enable interrupts.


  LED_OUT &=~LED1;


  while(1)


  {


    ADC10CTL0 |= ENC + ADC10SC;             //ADC使能,ADC开始转换一次 Sampling and conversion start


    __bis_SR_register(CPUOFF + GIE);


    P1SEL |=BIT6;


    P1OUT |=BIT6;


    ConfigureTimerPwm();


    unsigned int j;


        for(j=0;j

        {


          CCR1=j;


         _delay_cycles(1000);


         }


        for(j=TIMER_PWM_PERIOD ;j>0;j-=1)


        {


          CCR1=j;


          _delay_cycles(1000);


        }


        for (j=TIMER_PWM_PERIOD;j>0;j-=1)


        {


          _delay_cycles(100);


        }


    tempMeasured[tempMeasuredPosition++] = ADC10MEM;  //将温度采样值存入温度值数组下一位


    if (tempMeasuredPosition == 8)


      tempMeasuredPosition = 0; //复位温度采样值数组索引


    tempAverage = 0;


    for (i = 0; i < 8; i++)


      tempAverage += tempMeasured[i];


    tempAverage >>= 3;  //除以8得到平均值   Divide by 8 to get average


    tempDifference = tempAverage - tempCalibrated;  //计算相对于参考温度的差值


    if (tempDifference < -TEMP_THRESHOLD) //如果采样温度值低于参考温度值差值TEMP_THRESHOLD


    {


      tempDifference = -tempDifference; //差值取正


      tempPolarity = TEMP_COLD; //极性变量设为值TEMP_COLD


    }


    else


    if (tempDifference > TEMP_THRESHOLD)  //如果采样温度值高于参考温度值差值TEMP_THRESHOLD


    {

      tempPolarity = TEMP_HOT;  //极性变量设为值TEMP_HOT


    }


    else  //如果相对于参考温度值偏差没有超过阈值TEMP_THRESHOLD


    {


      tempPolarity = TEMP_SAME; //性变量设为值TEMP_SAME


      TACCTL0 &= ~CCIE; //关TACCTL0中断使能


      TACCTL1 &= ~CCIE; //关TACCTL1中断使能


    }


    if (tempPolarity != TEMP_SAME)  //如果相对于参考温度值偏差超过阈值TEMP_THRESHOLD


    {


      tempDifference <<= 9; //温度偏差值乘以8


      //tempDifference += TIMER_PWM_OFFSET; //加上一个偏置值


      TACCR1 = ( (tempDifference) < (TIMER_PWM_PERIOD-1) ? (tempDifference) : (TIMER_PWM_PERIOD-1) ); //置TACCR1,最大为TIMER_PWM_PERIOD-1。


      //TACCR1值控制亮的时间,定时器计数到TACCR1在中断中将关闭灯,在TACCR0中断中亮灯


      TACCTL0 |= CCIE;  //开TACCTL0中断使能


      TACCTL1 |= CCIE;  //开TACCTL1中断使能


    }


  } //返回主循环


}


//进入待机模式,红绿灯交替闪,等待按键


void PreApplicationMode(void)


{


  LED_DIR |= LED1 + LED2; //p1.0和P1.6口为输出


  LED_OUT |= LED1;


  LED_OUT &= ~LED2; //绿灯灭


  BCSCTL1 |= DIVA_1;


  BCSCTL3 |= LFXT1S_2;


  TACCR0 = 1200;


  TACTL = TASSEL_1 | MC_1;


  TACCTL1 = CCIE + OUTMOD_3;


  TACCR1 = 600;


  __bis_SR_register(LPM3_bits + GIE);


}


//配置温度传感器模数转换


void ConfigureAdcTempSensor(void)


{

  unsigned char i;


  /* Configure ADC Temp Sensor Channel */


  ADC10CTL1 = INCH_10 + ADC10DIV_3; //选择ADC通道为温度传感器,时钟4分频         // Temp Sensor ADC10CLK/4


  ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;  // VR+ = VREF+ and VR- = VSS,采样保持时间=64×ADC10CLK周期,打开内部参考电压,打开ADC模块,ADC中断允许


  __delay_cycles(1000); //延时等待ADC参考电压建立                     // Wait for ADC Ref to settle


  ADC10CTL0 |= ENC + ADC10SC; //ADC使能,ADC开始转换一次                // Sampling and conversion start


  __bis_SR_register(CPUOFF + GIE);  //进入省电模式LPM0,等待AD转换完成中断          // LPM0 with interrupts enabled


  tempCalibrated = ADC10MEM;


  for (i=0; i < 8; i++)


    tempMeasured[i] = tempCalibrated;


  tempAverage = tempCalibrated; //第一次转换,平均温度取样值和校准值相等


}


//配置定位器为PWM模式


void ConfigureTimerPwm(void)


{


  timerMode = TIMER_PWM_MODE;


  TACCR0 = TIMER_PWM_PERIOD;                              //


  TACTL = TASSEL_2 | MC_1;  //定时器时钟源选择辅助时钟SMCLK,增计数模式                  // TACLK = SMCLK, Up mode.


  TACCTL1 = OUTMOD_7;//CCIE + OUTMOD_3;  //捕获/比较控制寄存器1设置为比较模式,输出模式为“置位/复位” ,中断允许  ??OUTMOD_3有什么用?                // TACCTL1 Capture Compare


}


//TACCR0中断专用, Timer A0 interrupt service routine


#pragma vector=TIMER0_A0_VECTOR


__interrupt void Timer_A (void)


{


    if (tempPolarity == TEMP_HOT)


    {


      //LED_OUT |= LED1;  //如果相对于参考温度偏差为正,LED1绿灯置为亮


    TIMER_PWM_PERIOD -= tempDifference;


     if (TIMER_PWM_PERIOD < 0)


     {


     LED_DIR |= LED1;


     LED_OUT |= LED1;


     //TIMER_PWM_PERIOD = 1;


     }


     tempCalibrated = tempAverage;


    }


    if (tempPolarity == TEMP_COLD)


    {


      //LED_OUT |= LED2;  //如果相对于参考温度偏差为负,LED2红灯置为亮


    TIMER_PWM_PERIOD += tempDifference;


    tempCalibrated = tempAverage;


    if (TIMER_PWM_PERIOD>0)


    {


    LED_OUT &= ~LED1;


    }


    }


    TACCTL0 &= ~CCIFG;  //清中断标志位??有必要么?不是自动清除?


    TACCTL0 &= ~CCIE;


}


//TACCR1和定时器共用中断向量


#pragma vector=TIMER0_A1_VECTOR


__interrupt void ta1_isr(void)


{


  TACCTL1 &= ~CCIFG;  //捕获比较中断标志CCIFG。比较模式:定时器 TAR 值等于寄存器 CCR1 值时CCIFG置位。需手动清除


  if (applicationMode == APP_APPLICATION_MODE)


  {


    //LED_OUT &= ~(LED1 + LED2);  //如果程序运行至是应用模式,置两灯皆灭


    TACCTL1 &= ~CCIE;


  }


  else


    LED_OUT ^= (LED1 + LED2); //如果是待机模式,异或,原来两个灯本来就是一亮一灭的,所以反复中断的效果是交替闪烁。PreApplicationMode(void)中


}


void InitializeClocks(void)


{


  BCSCTL1 = CALBC1_1MHZ;  //用FLASH中信息存贮器A段的校准数据设置基本时钟系统控制寄存器 1                    // Set range

推荐阅读

史海拾趣

FDK AMERICA公司的发展小趣事

在竞争激烈的电子市场中,FDK AMERICA公司始终坚持品质至上的原则。公司严格控制产品质量,从原材料采购到生产流程再到售后服务,每一个环节都力求做到精益求精。这种对品质的执着追求赢得了客户的信赖,也为公司树立了良好的品牌形象。

ELINA INDEK公司的发展小趣事

在电子行业中,技术变革日新月异,市场竞争异常激烈。面对这些挑战,因美纳始终保持着敏锐的洞察力和灵活的反应能力。公司不断调整产品策略和市场布局,积极应对行业变革。同时,因美纳还注重培养员工的创新能力和团队协作精神,为公司的发展提供源源不断的动力。

Digilent公司的发展小趣事

在全球节能意识日益增强的背景下,DIALIGHT致力于推动绿色照明的发展。公司的LED产品具有高效节能、长寿命和环保等优点,有助于减少能源消耗和环境污染。此外,DIALIGHT还积极参与各种绿色照明项目,为推动可持续发展贡献自己的力量。

Electronic Transistors Corp公司的发展小趣事

作为一家领先的电子企业,ETC公司深知自身肩负的社会责任。公司积极履行社会责任,关注环境保护和资源节约。ETC通过引进先进的生产工艺和设备,减少生产过程中的能源消耗和废弃物排放。同时,公司还积极参与公益事业和社会活动,为社会做出了积极贡献。这些举措不仅提升了ETC的企业形象,也为公司的可持续发展奠定了坚实的基础。

AMERICASEMI [America Semiconductor, LLC]公司的发展小趣事

随着电子行业的快速发展,AMERICASEMI意识到只有不断创新才能在市场中立于不败之地。因此,公司加大了对研发的投入,积极引进先进的技术和设备,不断提升自身的研发能力。经过多年的努力,AMERICASEMI成功研发出多款具有创新性的半导体产品,如高性能的功率管理芯片和低功耗的传感器等,这些产品在市场上获得了广泛的认可。

台湾三礼(3L)公司的发展小趣事

在技术创新方面,三礼公司一直保持着领先地位。2009年,公司成功完成了UPI、DPI压模型电感量产布线及自制粉料能力,并获得了Texas Instrument认证。同时,公司重新发布了愿景并重新定义了3L,将持续改善、精益生产、以客为尊作为公司的三个核心L。随后,公司成立了精实中心,进一步推进精益生产的自动化配置,实现了生产效率的大幅提升和不良品及库存的减少。

问答坊 | AI 解惑

我的PXA270跑不起来了!请大家帮帮忙啊!

  我完全仿照PXA270开发板,做的PCB,现在出现的情况就是,板子完全能够实现BOOTLOAD的下载, 但是BOOTLOAD始终不能运行,我已经检查过了外围电压,似乎都完全正确,我现在已经没有办法了, 求大家帮帮忙 ,帮我分析下原因啊!谢谢!…

查看全部问答>

驱动开发

我刚学驱动开发。希望大虾给点建议,该看些什么书?…

查看全部问答>

移植ucosii的时候ads编译器遇到的问题

我是新手,第一次移植系统,在移植过程中遇到了以下问题,我尽量把相关的函数都贴出来: 在os_cpu.h中,我定义了函数: #define        OS_ENTER_CRITICAL()        ARMDisableInt() #define  &n ...…

查看全部问答>

哪个有在JZ4730上PS2的驱动开发经验的?

有的话,能否赐教下本人,给个思路,或者可以参照系统中的哪些文件,都可以,只要是有帮助的都有分…

查看全部问答>

vc编的程序转为evc4在WINCE上运行问题

VC6编的程序,想在ARM9模块上运行,程序是关于串口输入输出的,还有同上位机数据库连接的内容,用了MFC。 请问一下,我这个程序转为EVC4程序,要作些什么,难度几何?…

查看全部问答>

.net 1.0 调用.net 2.0的 dll

做一个程序 需在WinCE系统.net 1.0 上运行,有什么方法用.net 2.0里实现的功能吗?比如实现WebBrowser功能,能否引用System.Windows.Forms.dll来实现? 虽然几乎不可能,但我还是要问,想知道为什么不行?…

查看全部问答>

111

111222222 [ 本帖最后由 lelede1987 于 2011-3-30 18:11 编辑 ]…

查看全部问答>

Spartan-6 LX9 Microboard不用XCF04怎么实现配置

Spartan-6 LX9 Microboard开发板中不用XCF04怎么实现配置的。   想知道原来装有XCFO4,怎样去掉。 好像只有TDO信号没连拉到JTAG。   [ 本帖最后由 sdjntl 于 2011-8-4 17:39 编辑 ]…

查看全部问答>

简易空间方位测量

        小弟在此向各位大侠请教,各位大侠好,小弟在这有礼了!         小弟这里遇到一个问题,请问如何用最一般的设备测出一个物体相对于测量的空间方位。   ...…

查看全部问答>

petalinux移植

大家谁有petalinux源代码,和fs-boot源码。想学习学习。先谢谢了。…

查看全部问答>