电赛 MSP430 Lab
Lab1
目的:调试环境,实验结果如图
Lab2
看门狗定时器
看门狗定时器 (Watchdog Timer(WDT_A))实际上是一个特殊的定时器,可以用来作为看门狗使用,也可以用作定时器。
所谓的看门狗功能,是指可以监控程序是否由于某些干扰或者错误而跑飞。其原理就是发生故障的时间满足规定的定时时间后,产生一个非屏蔽中断,使系统复位。这样当在调试程序或预计程序在某个地方可能瞬时发生错误时(如外部电路干扰),选用设置看门狗定时中断可以避免程序跑飞。
当然,它也可以用作一般的定时功能,当定时器溢出时即进行系统复位。
喂狗,就是在看门狗定时器溢出之前对其进行清零的操作。
时钟
MSP430中一共有三个时钟系统,分别为ACLK、MCLK、SMCLK。四个时钟源,外部的包括LFXT1(晶振源,通常接32.768kHz)、XT2(可选高频振荡器,外接标准高速晶振);内部的包括DCO(内部晶振)、VCO(内部低频振荡器)。
与时钟有关的寄存器:DCOCTL、BCSCTL1、BCSCTL2、BCSCTL3
DCO(Digitally Controlled Oscillator),不含晶振,可以产生较为准确的振荡频率,但是会受温度和电源电压的影响产生漂移。
管脚指配:
P1DIR = BIT6;
P1OUT = 0;
BIT6指0x0040。
控制输出代码:
P1OUT = BIT6;
_delay_cycles(100);
P1OUT = 0;
_delay_cycles(5000);
示例代码补充:
BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;
BCSCTL2 |= SELM_1 + DIVM_3; //SELM控制分频数,SELM_3闪烁最慢
修改_delay_cycles(100)中延时周期,可以观察到闪烁频率减小;更改DCOCTL、BCSCTL1、BCSCTL2、BCSCTL3这四个寄存器就可以切换各种时钟。
Lab3
LPM模式
MSP430中,用到5种低功耗,LPM0,LPM1,LPM2,LPM3,LPM4,这五种低功耗各种解释如下 :
LPM0:CPU停止工作,MCLK时钟停止,SMCLK、ACLK时钟还在工作。
LPM1:CPU停止工作,MCLK时钟停止,在活动模式如果DCO没有作为MCLK和SMCLK时钟时,则直流发生器被禁止,否则就保持活动状态,SMCLK、ACLK时钟依然还在工作。
LPM2:CPU停止工作,MCLK、SMCLK时钟停止工作,如果DCO没有作为MCLK、SMCLK,自动被禁止直流发生器保持有效,ACLK还处于工作中。
LPM3:CPU停止工作,MCLK、SMCLK时钟停止工作,DCO时钟也停止工作,仅ACLK时钟还处于工作状态。
LPM4:CPU停止工作,MCLK、SMCLK时钟停止工作,DCO时钟也停止工作,ACLK也停止工作。此时功耗最低。
SR寄存器
中断函数
由于有两个输出位置,所以定义方向时写成如下形式。
P1DIR |= BIT0+BIT6;
__ interrupt前面是两个下划线,表示该函数为中断服务函数这种特殊的函数
__interrupt void Port_1(void)
{
unsigned int Push_Key=0;
Push_Key=P1IFG & (~P1DIR);
_delay_cycles(10000);
if ((P1IN&Push_Key)==0)
{
P1OUT ^= BIT0;
switch(Push_Key)
{
case BIT3: P13_Onclick(); break;
default: break;
}
}
P1IFG=0;
}
由于_delay_cycles()这个函数入口只能是常数,所以选用改变时钟来改变频率。
中断函数和主函数循环采用全局变量,用case语句设置寄存器控制时钟。
static unsigned int Freq=0;
Freq++;
if (Freq>3)
Freq=0;
switch(Freq)
{
case 0: DCOCTL = CALDCO_1MHZ; BCSCTL1 = CALBC1_1MHZ;
break;
case 1: DCOCTL = CALDCO_8MHZ; BCSCTL1 = CALBC1_8MHZ;
break;
case 2: DCOCTL = CALDCO_12MHZ; BCSCTL1 = CALBC1_12MHZ;
break;
default: break;
}
Lab4
PWM即脉冲宽度调制。
实验通过按键生成两路频率、相位改变的正弦波。
改变频率需通过改变步进,而步进为宏定义无法作为变量,根据lab3的思路,改成了static int,不知道这么做合不合理,但是频率和相位确实都会改变。每次按键按下时,修改步进,修改查表的初始位置来改变相位和频率。
static int CH2_INC_PHASE=1;
static int CH1_INC_PHASE=3;
if(!(P1IN & BIT3)){ // if key is push, its val is 0
if(CH2_INC_PHASE<6)
CH2_INC_PHASE=CH2_INC_PHASE+1;
else
CH2_INC_PHASE=1;
if(CH1_INC_PHASE<6)
CH1_INC_PHASE=CH1_INC_PHASE+2;
else
CH1_INC_PHASE=1;
ch2_index += CH2_INC_PHASE; while(ch2_index >= SIN_NUM){ch2_index -= SIN_NUM; }