📄 time_cont.c
字号:
#include <msp430x13x.h>
#define uchar unsigned char
#define unit unsigned int
void delay(int v);
void d1ms(void);
uchar kbscan(void); /*输出键值*/
uchar kbjust(void); /*有按键为1*/
void key0(void); /*调时间*/
void key1(void); /*调闹钟时间*/
void dsp(void); //显示子程序
uchar dot=0,bell=0,bellcontr=1,bbb=0;
uchar out=0x08; //p4.3
uchar x[6]={1,2,0,0,0,0},y1=20,y2=00,y3=00,s01; /*显缓,计时单元*/
uchar timjust[6]={0x21,0x21,0x21,0x21,0x21,0x21};
struct
{uchar hour,mte;}time[6]={{6,0},{6,5},{6,10},{7,40},{13,40},{17,20}};
/*time[5]为6个时间控制点*/
uchar seg[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,
0xbf,0x86,0xdb,0xcf,
0xe6,0xed,0xfd,0x87,
0xff,0xef,0xf7,0xfc,
0xb9,0xde,0xf9,0xf1,
0x80,0x40,0x00,0x73,0xc0};
void key3(void) //控制输出与否位求反
{
bellcontr^=1;
}
void key0(void) //设定实时时间
{
x[0]=0x21;
x[1]=0x21; //最前面两显示器显示中间杠--,提示为时间设置
x[2]=0x22;
x[3]=0x22;
x[4]=0x22;
x[5]=0x22; //接着后面4位不显示,等待键盘的输入
x[2]=kbscan();
x[3]=kbscan();
x[4]=kbscan();
x[5]=kbscan(); //键盘输入值送入后面4位显示器
y1=x[2];
y1=y1*10;
y1=y1+x[3];
y1=x[2]*10+x[3]; //前两个输入数据作为时间的小时值被保存
y2=x[4]*10+x[5]; //最后两个输入作为时间的分钟值被保存
y3=0; //秒被清零
}
void key1(void) //设定6个控制时间点
{
uchar tmp;
uchar i=0;
for(i=0;i<6;i++) //循环6次
{
x[0]=i+1; //第一位显示控制时间点的序号
x[1]=timjust[i]; //
x[2]=(time[i].hour)/10; //在显示器的后面4位显示原先的控制时间点与序号
x[3]=(time[i].hour)%10;
x[4]=(time[i].mte)/10;
x[5]=(time[i].mte)%10;
tmp=kbscan(); //按键为何值
if(tmp==0) //如果按键为“0”
{
x[2]=0x22; //说明需要改变相应的控制时间点
x[3]=0x22; //先将显示清除,序号不变
x[4]=0x22;
x[5]=0x22;
x[2]=kbscan(); //输入4位数为改变后的控制时间点
x[3]=kbscan();
x[4]=kbscan();
x[5]=kbscan();
time[i].hour=x[2]*10+x[3]; //记录如相应的缓存
time[i].mte=x[4]*10+x[5];
kbscan();
}
else
if(tmp==0x0b) //如果为“B”
x[1]=0x21;
else x[1]=0x22;
timjust[i]=x[1];
kbscan();
}
}
void main(void) //系统主程序
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
TACTL = TASSEL1 + TACLR; // SMCLK, clear TAR
CCTL0 = CCIE; // CCR0 interrupt enabled
CCR0 = 50000;
P4DIR |= 0x08; // P1.0 output
TACTL |= MC1; // Start Timer_A in continuous mode
_EINT(); // Enable interrupts
while(1) //主循环
{
uchar j;
x[0]=y1/10; //拆分时间值到对应的显示缓存
if(x[0]==0) //如果时间的小时值的十位为“0”
x[0]=0x22; //则不予显示(符合习惯)
if(dot==1) //与电子表对应的秒闪烁
x[1]=y1%10+0x10;
else
x[1]=y1%10;
x[2]=y2/10;
x[3]=y2%10;
x[4]=y3/10;
if(bellcontr==1) //输出控制位在最后单元的小数点显示
x[5]=y3%10+0x10; //如果控制信号输出,则最后小数点亮
else
x[5]=y3%10;
dsp(); //调用显示
if(kbjust()!=0) //有否按下的按键
{ //如果有,则:
switch(kbscan()) //判断什么键值
{
case 0: //0:调时间
{
key0();
break;
}
case 1: //1:设定时间控制点
{key1();
break;
}
case 11: //11:设定到时间控制点后,是否输出
{key3();
break;
}
}
}
bbb=0;
if(bellcontr ==1) //如果输出畅通
{
for(j=0;j<6;j++) //判断实时时间与6个控制点是否有相等
if((y1==time[j].hour)&(y2==time[j].mte))
{
P4OUT |= BIT3; //则输出高电平驱动打铃
break;
}
else
P4OUT &= ~BIT3; //不满足打铃条件输出低电平
}
}
}
unsigned char key(void)
{
unsigned char x=0xff;
P1DIR=0X0F;
P1OUT=0X01; //扫描第一行
if((P1IN&0X70)==0X10)
x=0;
else
if((P1IN&0X70)==0X20)
x=1;
else
if((P1IN&0X70)==0x40)
x=2;
else
{
P1OUT=0X2; //扫描第二行
if((P1IN&0X70)==0X10)
x=3;
else
if((P1IN&0X70)==0X20)
x=4;
else
if((P1IN&0X70)==0x40)
x=5;
else
{
P1OUT=0X4; //扫描第三行
if((P1IN&0X70)==0X10)
x=6;
else
if((P1IN&0X70)==0X20)
x=7;
else
if((P1IN&0X70)==0x40)
x=8;
else
{P1OUT=8; //扫描第四行
if((P1IN&0X70)==0X10)
x=9;
else
if((P1IN&0X70)==0X20)
x=10;
else
if((P1IN&0X70)==0x40)
x=11;
}
}
}
return(x);
}
unsigned char kbjust(void)
{unsigned char x;
P1DIR=0XFF;
P1OUT=0X0;
P1DIR=0x0f;
P1OUT=0x0f; //键盘硬件:P10--P13为行线,最上面一根为P10
x=(P1IN&0X70); // P14--P16为列线,最左边一根为P14,列线下拉
return(x); // 无按键,返回 0 ; 有按键返回非0
}
uchar kbscan(void)
{
uchar temp;
kbscant: dsp();
if(kbjust()!=0X00)
{
dsp(); //消抖动
if(kbjust()!=0X0)
temp=key(); //按键键值保存临时单元
kbscant2: if(kbjust()!=0X00)
goto kbscant2; //等按键松开
else
return(temp); //松开后返回
}
goto kbscant;
}
void d1ms(void)
{
int tmp=500;
while(tmp)
tmp--;
}
void delay(int v)
{
while(v!=0)v--;
}
void dsp(void)
{
unsigned char i=0;
unsigned char temp=0x1;
for(i=0;i<6;i++)
{
P1DIR=0XFF;
P5DIR=0XFF;
P1DIR=0XFF;
P1OUT=~temp;
temp=temp<<1;
P5OUT=seg[x[i]];
delay(400);
}
}
interrupt[TIMERA0_VECTOR] void Timer_A (void)
{
CCR0+=60000; //增加CCR0
s01=s01+1; //0.1秒加1
if(s01==10)
{s01=0;
dot^=1; //求反,小数点是否显示(秒闪烁)
y3=y3+1; //10个0.1秒为1秒,秒加1
}
if(y3==60)
{
y3=0;
y2=y2+1; //60秒为1分,分加1
if(y2==60)
{
y2=0;
y1=y1+1; //60分为1小时,小时加1
if(y1==24)
{y1=0 ; //24小时再清零
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -