📄 clock.c
字号:
//
//
// MSP430F4XX
// +---------------+
// | | +----------------------+
// |A0+ S0-S23|--->| SoftBaugh SBLCDA4 |
// |A0- COM0-COM3|--->| 9 Digit,4-Mux LCD |
// |P2.0 | +----------------------+
// |P2.1 |
// |VRef R03-R33|<---LCD Voltage Ladder Rs
// | |
// | XIN/XOUT|<---32.768KHz Watch Crystal
// | P1.0|<---Button ADD (low-active)
// | P1.1|<---Button SEL (low-active)
// +---------------+
#include "msp430x42x.h"
// LCD segment definitions.
#define d 0x01 // AAAA
#define g 0x02 // F B
#define b 0x04 // F B
#define a 0x08 // GGGG
#define DOT 0x10 // E C
#define e 0x20 // E C
#define f 0x40 // DDDD
#define c 0x80
const char LCD_Tab[] = {
a + b + c + d + e + f, // Displays "0"
b + c, // Displays "1"
a + b + d + e + g, // Displays "2"
a + b + c + d + g, // Displays "3"
b + c + f + g, // Displays "4"
a + c + d + f +g, // Displays "5"
a + c + d + e + f + g, // Displays "6"
a + b + c, // Displays "7"
a + b + c + d + e + f + g, // Displays "8"
a + b + c + d + f + g, // Displays "9"
a + b + c + e + f + g, // Displays "A"
b + c + d + e + g, // Displays "D"
b + c + e + f + g, // Displays "H"
a + d + e + f, // Displays "C"
d + e + f, // Displays "L"
g , // Displays "-"
0x00, // Displays Blank
0x00 // Displays Blank
};
#define DD 11
#define BR 15
#define BL 16 //非数字字符定义再用,改动方便
#undef a
#undef b
#undef c
#undef d
#undef e
#undef f
#undef g
/*
Digital Number
左8+ 7654321右
*/
unsigned char Time[7]={5,1,1,12,0,0,0};
#define YEAR Time[0]
#define MONTH Time[1]
#define DATE Time[2]
#define HOUR Time[3]
#define MINUTE Time[4]
#define SECOND Time[5]
#define DSEC Time[6]
unsigned char const MONTH_Table[12]={31,28,31,30,31,30,31,31,30,31,30,31};
unsigned char BlinkMask[4]={0xff,0xff,0xff,0xff};//闪烁位置 0~2 分别控制三个显示内容 3控制间隔点闪烁Mask
unsigned char BlinkEnable[3];//闪烁允许标志
#define Enable 1
#define Disable 0
unsigned char DISP_MODE; //当前显示模式
#define DISP_MODE_TIME 0 //时间
#define DISP_MODE_DATE 2 //日期
#define DISP_MODE_SECOND 1 //秒钟显示
#define END_DISP_MODE 3 //设置完成
#define KEY_SEL (BIT5)
#define KEY_ADD (BIT6) //2个按钮
#define PUSH_BUTTON (KEY_SEL+KEY_ADD)
unsigned char SET_MODE; //当前设置内容
#define NORMAL 0 //无(正常走时)
#define SET_HOUR 1 //设置时间
#define SET_MINUTE 2 //设置分钟
#define SET_SECOND 3 //设置秒钟
#define SET_YEAR 4 //设置年
#define SET_MONTH 5 //设置月
#define SET_DATE 6 //设置日
#define END_SET_MODE 7 //设置完成
InitSystem()
{
int i;
char *pLCD = (char *)&LCDM1;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
FLL_CTL0 &=~XTS_FLL;
FLL_CTL0 |= XCAP18PF; // Set load capacitance for xtal
SCFQCTL = 99;
FLL_CTL0 |=DCOPLUS;
SCFI0 |=FLL_DIV_2+FN_4;
for (i = 0; i < 10; i++) // Clear LCD memory
*pLCD++ = 0;
IFG1&=(~OFIFG);
LCDCTL = LCDSG0_1 + LCD4MUX + LCDON; // 4mux LCD, segs0-15
//P5SEL = 0xFC; // set Rxx and COM pins for LCD
BTCTL = BT_fLCD_DIV64+BTDIV+BT_fCLK2_DIV32; // 0.25s BT Int, Set LCD freq
IE2 |= BTIE; // Enable Basic Timer interrupt
P1DIR &=(~PUSH_BUTTON) ; // All pins but button to output
P1IES = PUSH_BUTTON; // Button int on falling edge
P1IFG = 0;
P1IE = PUSH_BUTTON; // Enable button interrupt
P1OUT=0;P2OUT=0;
P1DIR |=(BIT0+BIT1+BIT2+BIT3+BIT4);
P2DIR |=(BIT0+BIT1+BIT2+BIT3);
_EINT();
}
void Display_Time()
{ //显示当前时间 受闪烁控制位控制
LCDM8=0;
LCDM7=LCD_Tab[HOUR/10]&BlinkMask[0];
LCDM6=LCD_Tab[HOUR%10]&BlinkMask[0];
LCDM5=LCD_Tab[BR]&BlinkMask[3];
LCDM4=LCD_Tab[MINUTE/10]&BlinkMask[1];
LCDM3=LCD_Tab[MINUTE%10]&BlinkMask[1];
LCDM2=0;
LCDM1=0;
}
void Display_Second()
{ //显示当前时间 受闪烁控制位控制
LCDM7=LCD_Tab[HOUR/10]&BlinkMask[0];
LCDM6=LCD_Tab[HOUR%10]&BlinkMask[0];
LCDM5=LCD_Tab[BR]&BlinkMask[3];
LCDM4=LCD_Tab[MINUTE/10]&BlinkMask[1];
LCDM3=LCD_Tab[MINUTE%10]&BlinkMask[1];
LCDM3|=(DOT&BlinkMask[3]);
LCDM2=LCD_Tab[SECOND/10]&BlinkMask[2];
LCDM1=LCD_Tab[SECOND%10]&BlinkMask[2];
}
void Display_Date()
{//显示当前日期 受闪烁控制位控制
unsigned char TempBCD;
if(YEAR>=10) LCDM8=0xA0; // 1
else LCDM8=0;
LCDM7=LCD_Tab[YEAR%10]&BlinkMask[0];
LCDM6=LCD_Tab[BR];
TempBCD=MONTH/10;
if(TempBCD==0) TempBCD=BL; //消隐月份第一个0
LCDM5=LCD_Tab[TempBCD]&BlinkMask[1];
LCDM4=LCD_Tab[MONTH%10]&BlinkMask[1];
LCDM3=LCD_Tab[BR];
TempBCD=DATE/10;
if(TempBCD==0) TempBCD=BL; //消隐日期第一个0
LCDM2=LCD_Tab[TempBCD]&BlinkMask[2];
LCDM1=LCD_Tab[DATE%10]&BlinkMask[2];
}
#pragma vector = BASICTIMER_VECTOR
__interrupt void BT_ISR(void) //1/4秒一次中断(由BasicTimer所产生)
{ unsigned char i,Days;
DSEC++;
if(DSEC >=4) {SECOND++;DSEC=0;} //1秒一次
if(SECOND>=60) {MINUTE++;SECOND=0;} //60秒一次
if(MINUTE>=60) {HOUR++;MINUTE=0;} //60分一次
if(HOUR >=24) {DATE++;HOUR=0;} //24小时一次
if(MONTH==2) //处理润年2月份问题
{
if(YEAR%4==0) Days=29; //逢4润
else Days=28;
if(YEAR%400==0) Days=28; //逢400不润
}
else Days=MONTH_Table[MONTH-1]; //正常月份,查表得到当月天数
if(DATE >Days) {MONTH++;DATE=1;} //一个月一次
if(MONTH >12) {YEAR++;MONTH=1;} //一年一次
if(YEAR>=100) {YEAR=0;} //100年一次
for(i=0;i<3;i++)
{
if(BlinkEnable[i]==Enable) BlinkMask[i]^=255;
else BlinkMask[i] =255;
}
if(DSEC%2==0){ BlinkMask[3]^=255; } //0.5秒一次,间隔点闪烁
if(DISP_MODE==DISP_MODE_TIME) Display_Time();
if(DISP_MODE==DISP_MODE_SECOND) Display_Second();
if(DISP_MODE==DISP_MODE_DATE) Display_Date(); //屏幕显示
}
void SetValue()
{unsigned char Days;
switch (SET_MODE)
{
case NORMAL:
{
DISP_MODE++; //在正常显示模式按下
if(DISP_MODE==END_DISP_MODE) DISP_MODE=0; //调整键用于切换时间模式和日期模式
break;
}
case SET_HOUR:
{
HOUR++;
if(HOUR>=24) HOUR=0; //时间设置模式时,调整键用于设置时间
break;
}
case SET_MINUTE:
{
MINUTE++;
if(MINUTE>=60) MINUTE=0; //分钟设置模式时,调整键用于设置分钟
break;
}
case SET_SECOND:
{
SECOND++;
if(SECOND>=60) SECOND=0; //秒钟设置模式时,调整键用于设置秒钟
break;
}
case SET_YEAR:
{
YEAR++;
if(YEAR>=20) YEAR=0; //年份设置模式时,调整键用于设置年份
break;
}
case SET_MONTH:
{
MONTH++;
if(MONTH>12) MONTH=1; //月份设置模式时,调整键用于设置月份
break;
}
case SET_DATE:
{ //日期设置模式时,调整键用于设置日期
DATE++;
if(MONTH==2) //处理润年2月份问题
{
if(YEAR%4==0) Days=29;
else Days=28;
if(YEAR%400==0) Days=28;
}
else Days=MONTH_Table[MONTH-1];//正常月份,查表得到当月天数
if(DATE>Days) DATE=1;
break;
}
default: break;
}; //end switch
}
#pragma vector = PORT1_VECTOR
__interrupt void PORT1_ISR(void) //键盘中断
{ unsigned int T,T2;
unsigned char PUSHKEY;
_BIC_SR(SCG0); //从LPM3唤醒需要人工清除SCG0标志位才能得到稳定时钟
PUSHKEY=P1IFG & PUSH_BUTTON;
for(T=0;T<2000;T++){}; //抗抖动
//P1IFG=0;
if((P1IN&PUSHKEY)==PUSHKEY) //检测是否由于松键抖动造成的中断
{
P1IFG=0;
return; //无效按键,返回
}
if(PUSHKEY==KEY_SEL) //选择建按下
{
SET_MODE++;
if(SET_MODE==END_SET_MODE) SET_MODE=0; //切换设置内容
/////
switch (SET_MODE)
{
case NORMAL:
{ DISP_MODE=DISP_MODE_TIME;
BlinkEnable[0]=Disable;
BlinkEnable[1]=Disable;
BlinkEnable[2]=Disable; //正常模式,正常显示
break;
}
case SET_HOUR:
{
BlinkEnable[0]=Enable; //时间设置时,小时闪烁
break;
}
case SET_MINUTE:
{
BlinkEnable[0]=Disable;
BlinkEnable[1]=Enable; //分钟设置时,分钟闪烁
break;
}
case SET_SECOND:
{ DISP_MODE=DISP_MODE_SECOND;
BlinkEnable[1]=Disable;
BlinkEnable[2]=Enable; //秒钟设置时,秒钟闪烁
break;
}
case SET_YEAR:
{
DISP_MODE=DISP_MODE_DATE;//年份设置时,切换到日期模式
BlinkEnable[2]=Disable;
BlinkEnable[0]=Enable; //年份闪烁
break;
}
case SET_MONTH:
{
BlinkEnable[0]=Disable;
BlinkEnable[1]=Enable; //月份设置时,月份闪烁
break;
}
case SET_DATE:
{
BlinkEnable[1]=Disable;
BlinkEnable[2]=Enable; //日期设置时,日期闪烁
break;
}
default: break;
};
}
if(PUSHKEY==KEY_ADD) //调整键按下
{
SetValue();
for(T=10;T!=0;T--)
{
for(T2=0x3fff;T2!=0;T2--)
{
if((P1IN&PUSHKEY)==PUSHKEY) goto END_KEY;//松键
}
BlinkMask[0]=255;
BlinkMask[1]=255;
BlinkMask[2]=255;
BlinkMask[3]=255;
if(DISP_MODE==DISP_MODE_TIME) Display_Time();
if(DISP_MODE==DISP_MODE_SECOND) Display_Second();
if(DISP_MODE==DISP_MODE_DATE) Display_Date(); //屏幕显示
}
while((P1IN&PUSHKEY)!=PUSHKEY)
{
SetValue();
BlinkMask[0]=255;
BlinkMask[1]=255;
BlinkMask[2]=255;
BlinkMask[3]=255;
if(DISP_MODE==DISP_MODE_TIME) Display_Time();
if(DISP_MODE==DISP_MODE_SECOND) Display_Second();
if(DISP_MODE==DISP_MODE_DATE) Display_Date(); //屏幕显示
for(T=2;T!=0;T--) {for(T2=0x3fff;T2!=0;T2--);}
}
} //end if
END_KEY:
P1IFG=0;
}
void main()
{
InitSystem(); //初始化系统
while(1)
{
LPM3;//休眠,所有任务在中断内完成
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -