2019-03-24 15:05发布
// | MSP430F449 |// VOUT <--|P3 |// 为1位选<--|P4.0 |// 为1段选<--|P4.1 |//功能选择键-->|P1.1 |// 加1键-->|P1.2 |// 减1键-->|P1.3 |////工作环境:IAR for MSP430 4.21
//显示方式:数码管动态扫描,共阴极数码管接有两个寄存器,故加P4.0、P4.1后可实现显示功能//实现功能:通过六位数码管显示时间,正常情况下显示日时分;按功能键1次,显示年月日// 按下2次后时钟停止计数,开始调整年,按下3次调整月,按下4次调整日// 按下5次调整时,按下6次调整分,按下7次退出至正常状态,依次循环// 被调整位闪烁显示,其它正常显示;// 调整状态时,可按加1键和减1减对时间进行调整;// MCU自动判断平闰年,校准当月最大天数;//计时方法:TA中断,TACCR0=32767,1s一次中断秒加1,RTC进行时间处理//按 键:采用查询方式,外接上拉电阻(以后可以尝试中断方式)#include "msp430x44x.h"//******定义子程序******void Init_Sys(void); //初始化子程序void LEAP(void); //判断闰年子程序void MAX(void); //天数判断子程序void DISPLY(void); //显示子程序void RTC(void); //实时时钟程序void DIS_BIT(void); //送显缓子程序void DLY_5ms(void); //延时子程序unsigned char KEY_SET(void); //返回按键标志0,1,2,3void DISPLY_Normal(void);void DISPLY_SETmin(void);void DISPLY_SEThour(void);void DISPLY_SETday(void);void DISPLY_SETmonth(void);void DISPLY_SETyear(void);//*****定义变量******** unsigned char max; //当月最大的天数unsigned char sec=0;unsigned char min=35; unsigned char hour=13;unsigned char day=10;unsigned char month=2;unsigned int year=2011;unsigned char leap; //闰年标志,1为闰年,0为平年unsigned char fct=0; //功能标志,0显示时钟,1显示年月,2~6分别调整分、时、日、月、年unsigned char led_bit[6]; //led显示缓存unsigned char key_flag; //按键是否按下标志,0为按下,1没有按下unsigned int dis_num; //显示循环次数// LED显示代码LEDconst unsigned char LED_TAB[]={ 0xd7,0x14,0xcd,0x5d,0x1e, //0,1,2,3,4, 0x5b,0xdb,0x15,0xdf,0x5f,0X00 //5,6,7,8,9,灭标志符};//******主程序**********void main( void ){ Init_Sys(); _EINT(); while(1) { RTC(); //时钟处理程序 KEY_SET(); //返回key_flag,0没有按下,1功能键,2加1键,3减1键 if(key_flag==1) { fct++; if (fct>=7)fct=0; } DIS_BIT(); //将需要显示的字符送入显示缓存dis_bit[] switch(fct) { case 0:DISPLY_Normal();break; //正常显示日时分 case 1:DISPLY_Normal();break; //正常显示年月 case 2:DISPLY_SETyear();break; // case 3:DISPLY_SETmonth();break; // case 4:DISPLY_SETday();break; // case 5:DISPLY_SEThour();break; // case 6:DISPLY_SETmin();break; //闪烁显示分,若key_flag=2,分加1,若=3,分减1 default: { fct=0; TACTL|=TAIE; //退出时间调整状态,开启TA中断 break; } } }}//======================//****定时器中断****//**********************#pragma vector=TIMERA1_VECTOR__interrupt void TimerA1(void){ TACTL&=~TAIFG; sec++; P1OUT^=BIT0;}//=====================//***实时时钟子程序****//*********************void RTC(void) { if(sec>=60) { min++; sec-=60; if(min>=60) { hour++; min=0; if(hour>=24) { day++; hour=0; MAX(); if(day>=max+1) { month++; day=1; if(month>=13) { year++; month=1; } } } } }} //=====================//***闰年判断子程序****//***闰年leap=1,平年leap=0//*********************void LEAP(void){ if(year%4==0) { if(year%100==0) { if(year%400==0) leap=1; else leap=0; } else leap=1; } else leap=0; }//========================//*****天数判断子程序*****//**功能:判断当月天数max**//************************void MAX(void){ LEAP(); if((month==4)||(month==6)||(month==9)||(month==11)) max=30; else if((month==2)) { if(leap==1) max=29; else max=28; } else max=31;} //=====================//****送显示位子程序***//*********************void DIS_BIT(void){ if ((fct==0)||(fct==4)||(fct==5)||(fct==6)) { led_bit[0]=min%10; led_bit[1]=min/10; led_bit[2]=hour%10; led_bit[3]=hour/10; led_bit[4]=day%10; led_bit[5]=day/10; } else { led_bit[0]=month%10; led_bit[1]=month/10; led_bit[2]=year%10; led_bit[3]=(year%100)/10; led_bit[4]=(year%1000)/100; led_bit[5]=year/1000; }}//=====================/******显示子程序*******//*********************/void DISPLY(void){ unsigned char idis=0; unsigned int wei=0x20; //0010 0000 while(idis<=5) { P3OUT=LED_TAB[led_bit[idis]]; P4OUT|=BIT1; //开启寄存器送显示字符码 P4OUT&=~BIT1; //禁止段选寄存器输入 P3OUT =~wei; //1101 1111 共阴极数码管 P4OUT|=BIT0; //开启寄存器送位选 P4OUT&=~BIT0; //禁止位选寄存器输入 wei>>=1; //位选左移1位 DLY_5ms(); /////消鬼影////// P3OUT =0xff; P4OUT|=BIT0; //开启寄存器送位选 P4OUT&=~BIT0; //禁止位选寄存器输入 idis++; }}//////1310*4/(32*32768)*1000约为5ms//////////for语句,判断为3个机周,减1为2个机周///void DLY_5ms(void){ unsigned int idly1; for(idly1=1000;idly1>=1;idly1--); }//////////////////unsigned char KEY_SET(void)////按下功能键,key_flag=1退出,按下加1键,key_flag=2退出,//按下减1键,key_flag=3退出,没有按下,则key_flag=0////////////{ if((P1IN&BIT1)==0) //扫描P1.1功能键是否按下,按下为0 { //DLY_5ms(); //延时消斗 if((P1IN&BIT1)==0) key_flag=1; } else if((P1IN&BIT2)==0) //扫描P1.2加1键是否按下,按下为0 { // DLY_5ms(); //延时消斗 if((P1IN&BIT2)==0) key_flag=2; } else if((P1IN&BIT3)==0) //扫描P1.3减1键是否按下,按下为0 { //DLY_5ms(); //延时消斗 if((P1IN&BIT3)==0) key_flag=3; } else key_flag=0; return key_flag;}//////////初始化/////////////void Init_Sys(void){ WDTCTL = WDTPW + WDTHOLD; //关闭看门狗 FLL_CTL0|=XCAP14PF; TACTL=MC_1+TASSEL_1+TAIE+TACLR; //Up模式,计数器中断使能,ACLK=32k TACCR0=32767; //定时1s P3OUT=LED_TAB[10]; P3DIR=0Xff; //IO口初始化 P4DIR|=BIT0+BIT1; P1DIR&=(~BIT1)+(~BIT2)+(~BIT3); //P1.1功能键,P1.2加1键,P1.3减1键 P1DIR|=BIT0; LEAP(); MAX();}////////////各种状态下的显示子程序////////////////////void DISPLY_Normal(void){ TACTL|=TAIE; P5DIR|=BIT1; dis_num=0; while(dis_num<=50) { DISPLY(); dis_num++; } //////////////// P5OUT^=BIT1; //测试频率 /////////////////////}///////分设置子程序///////////////闪烁间隔时间:5*6*16约为500ms///////////此处用30*20=600ms,及1.2s扫描一次按键////void DISPLY_SETmin(void){ KEY_SET(); if(key_flag==2) { min++; if(min==60)min=0; } else if(key_flag==3) { if(min==0)min=59; else min--; } led_bit[0]=min%10; led_bit[1]=min/10; for(dis_num=0;dis_num<=20;dis_num++) { DISPLY(); } led_bit[0]=10; led_bit[1]=10; for(dis_num=0;dis_num<=20;dis_num++) { DISPLY(); }}/////////////////////////////void DISPLY_SEThour(void){ KEY_SET(); if(key_flag==2) { hour++; if(hour>=24)hour=0; } else if(key_flag==3) { if(hour==0)hour=23; else hour--; } led_bit[2]=hour%10; led_bit[3]=hour/10; for(dis_num=0;dis_num<=20;dis_num++) { DISPLY(); } led_bit[2]=10; led_bit[3]=10; for(dis_num=0;dis_num<=20;dis_num++) { DISPLY(); }}//////////////////////////////void DISPLY_SETday(void){ MAX(); KEY_SET(); if(key_flag==2) { day++; if(day>max)day=1; } else if(key_flag==3) { if(day==1)day=max; else day--; } led_bit[4]=day%10; led_bit[5]=day/10; for(dis_num=0;dis_num<=20;dis_num++) { DISPLY(); } led_bit[4]=10; led_bit[5]=10; for(dis_num=0;dis_num<=20;dis_num++) { DISPLY(); }}/////////////////////////////void DISPLY_SETmonth(void){ KEY_SET(); if(key_flag==2) { month++; if(month>12)min=1; } else if(key_flag==3) { if(month==1)month=12; else month--; } led_bit[0]=month%10; led_bit[1]=month/10; for(dis_num=0;dis_num<=20;dis_num++) { DISPLY(); } led_bit[0]=10; led_bit[1]=10; for(dis_num=0;dis_num<=20;dis_num++) { DISPLY(); }}////////////////////////////void DISPLY_SETyear(void){ TACTL&=(~TAIE); //进入时间调整状态,关闭TA中断 KEY_SET(); if(key_flag==2) { year++; } else if(key_flag==3) { year--; } led_bit[2]=year%10; led_bit[3]=(year%100)/10; led_bit[4]=(year%1000)/100; led_bit[5]=year/1000; for(dis_num=0;dis_num<=20;dis_num++) { DISPLY(); } led_bit[2]=10; led_bit[3]=10; led_bit[4]=10; led_bit[5]=10; for(dis_num=0;dis_num<=20;dis_num++) { DISPLY(); } }
最多设置5个标签!
// | MSP430F449 |
// VOUT <--|P3 |
// 为1位选<--|P4.0 |
// 为1段选<--|P4.1 |
//功能选择键-->|P1.1 |
// 加1键-->|P1.2 |
// 减1键-->|P1.3 |
//
//工作环境:IAR for MSP430 4.21
//显示方式:数码管动态扫描,共阴极数码管接有两个寄存器,故加P4.0、P4.1后可实现显示功能
//实现功能:通过六位数码管显示时间,正常情况下显示日时分;按功能键1次,显示年月日
// 按下2次后时钟停止计数,开始调整年,按下3次调整月,按下4次调整日
// 按下5次调整时,按下6次调整分,按下7次退出至正常状态,依次循环
// 被调整位闪烁显示,其它正常显示;
// 调整状态时,可按加1键和减1减对时间进行调整;
// MCU自动判断平闰年,校准当月最大天数;
//计时方法:TA中断,TACCR0=32767,1s一次中断秒加1,RTC进行时间处理
//按 键:采用查询方式,外接上拉电阻(以后可以尝试中断方式)
#include "msp430x44x.h"
//******定义子程序******
void Init_Sys(void); //初始化子程序
void LEAP(void); //判断闰年子程序
void MAX(void); //天数判断子程序
void DISPLY(void); //显示子程序
void RTC(void); //实时时钟程序
void DIS_BIT(void); //送显缓子程序
void DLY_5ms(void); //延时子程序
unsigned char KEY_SET(void); //返回按键标志0,1,2,3
void DISPLY_Normal(void);
void DISPLY_SETmin(void);
void DISPLY_SEThour(void);
void DISPLY_SETday(void);
void DISPLY_SETmonth(void);
void DISPLY_SETyear(void);
//*****定义变量********
unsigned char max; //当月最大的天数
unsigned char sec=0;
unsigned char min=35;
unsigned char hour=13;
unsigned char day=10;
unsigned char month=2;
unsigned int year=2011;
unsigned char leap; //闰年标志,1为闰年,0为平年
unsigned char fct=0; //功能标志,0显示时钟,1显示年月,2~6分别调整分、时、日、月、年
unsigned char led_bit[6]; //led显示缓存
unsigned char key_flag; //按键是否按下标志,0为按下,1没有按下
unsigned int dis_num; //显示循环次数
// LED显示代码LED
const unsigned char LED_TAB[]=
{
0xd7,0x14,0xcd,0x5d,0x1e, //0,1,2,3,4,
0x5b,0xdb,0x15,0xdf,0x5f,0X00 //5,6,7,8,9,灭标志符
};
//******主程序**********
void main( void )
{
Init_Sys();
_EINT();
while(1)
{
RTC(); //时钟处理程序
KEY_SET(); //返回key_flag,0没有按下,1功能键,2加1键,3减1键
if(key_flag==1)
{
fct++;
if (fct>=7)fct=0;
}
DIS_BIT(); //将需要显示的字符送入显示缓存dis_bit[]
switch(fct)
{
case 0:DISPLY_Normal();break; //正常显示日时分
case 1:DISPLY_Normal();break; //正常显示年月
case 2:DISPLY_SETyear();break; //
case 3:DISPLY_SETmonth();break; //
case 4:DISPLY_SETday();break; //
case 5:DISPLY_SEThour();break; //
case 6:DISPLY_SETmin();break; //闪烁显示分,若key_flag=2,分加1,若=3,分减1
default:
{
fct=0;
TACTL|=TAIE; //退出时间调整状态,开启TA中断
break;
}
}
}
}
//======================
//****定时器中断****
//**********************
#pragma vector=TIMERA1_VECTOR
__interrupt void TimerA1(void)
{
TACTL&=~TAIFG;
sec++;
P1OUT^=BIT0;
}
//=====================
//***实时时钟子程序****
//*********************
void RTC(void)
{
if(sec>=60)
{
min++;
sec-=60;
if(min>=60)
{
hour++;
min=0;
if(hour>=24)
{
day++;
hour=0;
MAX();
if(day>=max+1)
{
month++;
day=1;
if(month>=13)
{
year++;
month=1;
}
}
}
}
}
}
//=====================
//***闰年判断子程序****
//***闰年leap=1,平年leap=0
//*********************
void LEAP(void)
{
if(year%4==0)
{
if(year%100==0)
{
if(year%400==0)
leap=1;
else
leap=0;
}
else
leap=1;
}
else
leap=0;
}
//========================
//*****天数判断子程序*****
//**功能:判断当月天数max**
//************************
void MAX(void)
{
LEAP();
if((month==4)||(month==6)||(month==9)||(month==11))
max=30;
else if((month==2))
{
if(leap==1)
max=29;
else
max=28;
}
else
max=31;
}
//=====================
//****送显示位子程序***
//*********************
void DIS_BIT(void)
{
if ((fct==0)||(fct==4)||(fct==5)||(fct==6))
{
led_bit[0]=min%10;
led_bit[1]=min/10;
led_bit[2]=hour%10;
led_bit[3]=hour/10;
led_bit[4]=day%10;
led_bit[5]=day/10;
}
else
{
led_bit[0]=month%10;
led_bit[1]=month/10;
led_bit[2]=year%10;
led_bit[3]=(year%100)/10;
led_bit[4]=(year%1000)/100;
led_bit[5]=year/1000;
}
}
//=====================
/******显示子程序*******/
/*********************/
void DISPLY(void)
{
unsigned char idis=0;
unsigned int wei=0x20; //0010 0000
while(idis<=5)
{
P3OUT=LED_TAB[led_bit[idis]];
P4OUT|=BIT1; //开启寄存器送显示字符码
P4OUT&=~BIT1; //禁止段选寄存器输入
P3OUT =~wei; //1101 1111 共阴极数码管
P4OUT|=BIT0; //开启寄存器送位选
P4OUT&=~BIT0; //禁止位选寄存器输入
wei>>=1; //位选左移1位
DLY_5ms();
/////消鬼影//////
P3OUT =0xff;
P4OUT|=BIT0; //开启寄存器送位选
P4OUT&=~BIT0; //禁止位选寄存器输入
idis++;
}
}
//////1310*4/(32*32768)*1000约为5ms////////
//for语句,判断为3个机周,减1为2个机周///
void DLY_5ms(void)
{
unsigned int idly1;
for(idly1=1000;idly1>=1;idly1--);
}
//////////////////
unsigned char KEY_SET(void)
////按下功能键,key_flag=1退出,按下加1键,key_flag=2退出,
//按下减1键,key_flag=3退出,没有按下,则key_flag=0
////////////
{
if((P1IN&BIT1)==0) //扫描P1.1功能键是否按下,按下为0
{
//DLY_5ms(); //延时消斗
if((P1IN&BIT1)==0)
key_flag=1;
}
else if((P1IN&BIT2)==0) //扫描P1.2加1键是否按下,按下为0
{
// DLY_5ms(); //延时消斗
if((P1IN&BIT2)==0)
key_flag=2;
}
else if((P1IN&BIT3)==0) //扫描P1.3减1键是否按下,按下为0
{
//DLY_5ms(); //延时消斗
if((P1IN&BIT3)==0)
key_flag=3;
}
else key_flag=0;
return key_flag;
}
//////////初始化/////////////
void Init_Sys(void)
{
WDTCTL = WDTPW + WDTHOLD; //关闭看门狗
FLL_CTL0|=XCAP14PF;
TACTL=MC_1+TASSEL_1+TAIE+TACLR; //Up模式,计数器中断使能,ACLK=32k
TACCR0=32767; //定时1s
P3OUT=LED_TAB[10];
P3DIR=0Xff; //IO口初始化
P4DIR|=BIT0+BIT1;
P1DIR&=(~BIT1)+(~BIT2)+(~BIT3); //P1.1功能键,P1.2加1键,P1.3减1键
P1DIR|=BIT0;
LEAP();
MAX();
}
////////////各种状态下的显示子程序////////////////////
void DISPLY_Normal(void)
{
TACTL|=TAIE;
P5DIR|=BIT1;
dis_num=0;
while(dis_num<=50)
{
DISPLY();
dis_num++;
}
////////////////
P5OUT^=BIT1; //测试频率
/////////////////////
}
///////分设置子程序/////////
//////闪烁间隔时间:5*6*16约为500ms/////////
//此处用30*20=600ms,及1.2s扫描一次按键////
void DISPLY_SETmin(void)
{
KEY_SET();
if(key_flag==2)
{
min++;
if(min==60)min=0;
}
else if(key_flag==3)
{
if(min==0)min=59;
else min--;
}
led_bit[0]=min%10;
led_bit[1]=min/10;
for(dis_num=0;dis_num<=20;dis_num++)
{
DISPLY();
}
led_bit[0]=10;
led_bit[1]=10;
for(dis_num=0;dis_num<=20;dis_num++)
{
DISPLY();
}
}
/////////////////////////////
void DISPLY_SEThour(void)
{
KEY_SET();
if(key_flag==2)
{
hour++;
if(hour>=24)hour=0;
}
else if(key_flag==3)
{
if(hour==0)hour=23;
else hour--;
}
led_bit[2]=hour%10;
led_bit[3]=hour/10;
for(dis_num=0;dis_num<=20;dis_num++)
{
DISPLY();
}
led_bit[2]=10;
led_bit[3]=10;
for(dis_num=0;dis_num<=20;dis_num++)
{
DISPLY();
}
}
//////////////////////////////
void DISPLY_SETday(void)
{
MAX();
KEY_SET();
if(key_flag==2)
{
day++;
if(day>max)day=1;
}
else if(key_flag==3)
{
if(day==1)day=max;
else day--;
}
led_bit[4]=day%10;
led_bit[5]=day/10;
for(dis_num=0;dis_num<=20;dis_num++)
{
DISPLY();
}
led_bit[4]=10;
led_bit[5]=10;
for(dis_num=0;dis_num<=20;dis_num++)
{
DISPLY();
}
}
/////////////////////////////
void DISPLY_SETmonth(void)
{
KEY_SET();
if(key_flag==2)
{
month++;
if(month>12)min=1;
}
else if(key_flag==3)
{
if(month==1)month=12;
else month--;
}
led_bit[0]=month%10;
led_bit[1]=month/10;
for(dis_num=0;dis_num<=20;dis_num++)
{
DISPLY();
}
led_bit[0]=10;
led_bit[1]=10;
for(dis_num=0;dis_num<=20;dis_num++)
{
DISPLY();
}
}
////////////////////////////
void DISPLY_SETyear(void)
{
TACTL&=(~TAIE); //进入时间调整状态,关闭TA中断
KEY_SET();
if(key_flag==2)
{
year++;
}
else if(key_flag==3)
{
year--;
}
led_bit[2]=year%10;
led_bit[3]=(year%100)/10;
led_bit[4]=(year%1000)/100;
led_bit[5]=year/1000;
for(dis_num=0;dis_num<=20;dis_num++)
{
DISPLY();
}
led_bit[2]=10;
led_bit[3]=10;
led_bit[4]=10;
led_bit[5]=10;
for(dis_num=0;dis_num<=20;dis_num++)
{
DISPLY();
}
}
一周热门 更多>