既然时钟系统,ADC系统和定时器系统的功能都已经得到了验证。那么接下来就要着手确定程序的逻辑了,我们可以尝试着从以下的方式来控温:
(1)使用TA1计时器计时10ms,每到10ms进行ADC采样。
(2)将ADC12采集到温度值使用PID算法得到控制量,然后再送到电路板上的P7.3/TA1.2的管脚上(这个管脚连接在温控MOS管的栅极),由此便可以实现温控控制。
通过以上的想法得知,这个需要while(1)语句,即要一直运行。但是需要时钟中断,从而实现每隔10ms就可以进行ADC采样。
先验证一下可不可以只通过一个计时器如TA1,就实现每隔10ms进入中断(使用LED灯来展示效果),同时在中断内部实现PWM的电压输出(设置占空比越来越小)。
/*这个范例的主要可以用来实现几个功能
1:每隔10ms产生一个中断使得P11.0处的LED灯开始闪烁
2:产生PWM的信号(56管脚 P7.3/TA1.2 为了验证进了中断,每次进入中断后会实时改变PWM的占空比)。
其实主要的作用是验证我的温控程序里面只需要使用一个定时器就可以实现功能
*/
#include "io430x54xA.h"
//这个函数用来产生5MHz的时钟信号
void InitClock()
{
P1DIR |= BIT0;
P1SEL |= BIT0; //ACLK output,这时候可以使用示波器观察时钟信号
UCSCTL3 |= SELREF_2; // FLLref = REFO
UCSCTL4 = SELM__DCOCLKDIV + SELS__DCOCLKDIV + SELA__DCOCLKDIV;// 时钟来源:主系统时钟来源DCOCLKDIV;子系统时钟来源DCOCLKDIV;辅助系统时钟来源DCOCLKDIV
UCSCTL5 |= DIVM__1 + DIVS__1 + DIVA__1; // 分频:主系统时钟1分频;子系统时钟1分频;辅助系统时钟1分频
__bis_SR_register(SCG0); // Disable FLL
UCSCTL1 = DCORSEL_6; // 10.7MHz<Fdco<39MHz
UCSCTL2 |= FLLD__2 +151 ; // 5MHz DCOCLKDIV Fdco/4
__bic_SR_register(SCG0); // Enable FLL
// 等待错误标志清除,振动器稳定
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
}
//初始化Timer_A
void Init_Timer_A()
{
P7DIR |= 0x08; // P7.3 output
P7SEL |= 0x08; // P7.3 options select
P11DIR |= 0x01; // P11.0 output red_LED
TA1CCTL0 = CCIE; // CCR0 interrupt enabled
TA1CCR0 = 50000; //设置周期为10ms
TA1CCTL2 = OUTMOD_3; // CCR1 set/reset
TA1CCR2 = 40000; // CCR1 original PWM duty cycle 1/5
TA1CTL = TASSEL_2 + MC_1 + TACLR; // SMCLK, upmode, clear TAR
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
InitClock();
Init_Timer_A();
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 ,Interrupt enabled
__no_operation(); // For debugger
}
#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER1_A0_ISR(void)
{
P11OUT ^= 0x01;
TA1CCR2 -= 100;
}
将源代码下载进msp430中可以发现,PWM的输出信号确实是占空比在增加,周期为10ms。所以实现了题目中所需要的TA1既要实现定时中断,又要实现PWM的输出。
但是LED灯并没有闪烁。
那么为什么LED灯没有闪烁呢?
很简单啦,因为10ms的闪烁时间,由于视觉残留的原因,人眼是分辨不出来的啦。所以呢,虽然进入了中断,但是并没有看到闪烁。
那么你可能又要问我了,那你把周期设置大一点不就好了吗?为啥子TA1CCR0 不设置为500000呢?
那是因为TA1CCR0是一个16位的寄存器,所以设置为500000会出现溢出。
那你又要问我了,那你把时钟频率设置低一点不就好了吗?为什么不这么设置呢?
因为我懒!