信号源。
(2)SMCLK系统子时钟。供外围模块使用。并在使用前可以通过各模块的寄存器实现分频。SMCLK可以选择任何一个振荡器所产生的时钟信号并进行1、2、4、8分频作为其信号源。
(3)ACLK辅助时钟。供外围模块使用。并在使用前可以通过各模块的寄存器实现分频。但ACLK只能由LFXT1进行1、2、4、8分频作为信号源。PUC复位后,MCLK和SMCLK的信号源为DCO,DCO的振荡频率默认为800KHZ。ACLK的信号源为LFXT1。MSP430内部含有晶体振荡器失效监测电路,监测LFXT1(工作在高频模式)和XT2输出的时钟信号。当时钟信号丢失50us时,监测电路捕捉到振荡器失效。如果MCLK信号来自LFXT1或者XT2,那么MSP430自动把MCLK的信号切换为DCO,这样可以保证程序继续运行。但MSP430不对工作在低频模式的LFXT1进行监测。由于单片机内部默认采用的数字时钟受环境影响比较大,计时不准确,所以采用外部的8M石英晶振产生的时钟脉冲进行计数。MSP430内部有三个时钟源,对时钟进行切换时必须有起振时间,只有当时钟源稳定了,单片机才能够正常工作。
MSP430选用内部8M时钟初始化程序如下: void Clock_Init() {
uchar i;
BCSCTL1&=~XT2OFF; //START XT2(8MHZ) BCSCTL2|=SELM1+SELS;
do{ //等待时钟转换 IFG1&=~OFIFG; for(i=0;i<100;i++) _NOP(); }
while((IFG1&OFIFG)!=0); IFG1&=~OFIFG; }
21
计时程序如下: void Clock(void) {
second -= 1; if(second==-1) {
second = 59; minute -= 1;
if(minute ==-1) {
minute = 59;
hour -= 1; hour0 -= 1; if(hour == -1) hour = 23; }
} }
6.2 LCD显示电路的编写
这部分的显示过程主要是显示从定时器A读取的时钟数值,同时当检测到独立式按键有键按下时,显示相应的设置菜单等。 基本操作时序:
读状态:输入:RS=L,RW=H,E=H 输出:DO~D7=状态字 写状态:输入:RS=L,RW=L,D0~D7=指令码,E=高脉冲 输出:无
读数据:输入:RS=H,RW=H,E=H 输出:DO~D7=数据 写数据:输入:RS=H,RW=L,D0~D7=数据,E=高脉冲 输出:无【8】
图13为LCD1602的具体读写时序。
22
a.读操作时序
b.写操作时序
图13 LCD1602的读写时序
红外信号解码及按键处理程序编写:
当红外线接收管接收到红外信号时,通过单片机执行相应的程序进行红外信号的解码,具体解码原理前文已详细叙述,解码得到的键码赋值给data数组,通过检测data[5]和data[6]的值即可执行相应的动作。当检测到ok键被按下时即可执行定时插座的设置功能;当检测到▲键和▼按键时则进行相应的增减定时设置,具体程序编写如下所示:
#pragma vector = PORT1_VECTOR __interrupt void Port1()
23
{
char j,k,n=0; P1IE &=~BIT5; //关中断 delay_us(360); //360us if (IRIN==1) //高电平 {
P1IFG=0x00;
P1IE|=BIT5;//从新打开中断
return;//返回 }
while (!IRIN) //等IR变为高电平,跳过9ms的前导低电平信号。
{delay_us(120);} // for (j=0;j<4;j++)// {
for (k=0;k<8;k++)// {
while (IRIN) //等 IR 变为低电平 {delay_us(120);}
while (!IRIN) //等 IR 变为高电平 {delay_us(120);}
while (IRIN) //计算IR高电平时长 {
delay_us(120);//延时120us,n++ n++; if (n>=30) {
P1IFG=0x00; P1IE|=BIT5;
24
return;}//高电平>30*120=3600us=3.6ms,出错返回 }
dat[j]=dat[j] >> 1;//取出第一位
if (n>=8) {dat[j] = dat[j]|0x80;}//0.96ms,确定为1,否则为0 n=0;// } }
if (dat[2]!=(~dat[3]-0xff00)) //貌似IAR环境下,char变量为16位 {P1IFG=0x00;P1IE|=BIT5;return;}//此句刚开始可以屏蔽,见到效果后再尝试打开校验,出现乱码,返回
dat[5]=dat[2] & 0x0F;//输入的低4位 dat[6]=dat[2] & 0xF0;//高4位 dat[6]=dat[6] >> 4;//移位 if(dat[5] >9)// {
dat[5] = dat[5]+0x37;//转为16进制 } else
dat[5] = dat[5]+0x30; //
if(dat[6] >9)// {
dat[6] = dat[6]+0x37;// } else//
dat[6] = dat[6]+0x30; //
P1IE|=BIT5; P1IFG=0x00;
while(P1IFG&0x11!=0) {
P1IFG=0x00;
25