main.c
上传用户:lhdljz
上传日期:2021-11-17
资源大小:4k
文件大小:28k
- /**************************************************
- ** 版权: 杭州利尔达科技有限公司
- ** 文件名: DD
- ** 工作环境: IAR 3.42A
- ** 作者: 谷丰
- ** 生成日期: 2008.08.25
- ** 功能: 实现软件万年历功能,并自动识别闰年
- A屏每显示5秒种就自动切换到B屏,
- B屏再显示5秒种就自动切换到C屏,
- C屏再显示5秒种就自动切换到A屏
- 通过按键在A屏、B屏和C屏之间切换
- 可通过按键手动设定和调整时间,当调整时对应调整位要有闪烁功能
- 有闹钟功能,可设置几点几分闹钟,当前时间等于闹钟时间时,
- 用点亮LED指示,直到某个键(自定义)被按下时,熄灭LED灯
- ** 相关文件:
- ** 修改日志:
- ***************************************************/
- /**************************************************
- 包含头文件
- ***************************************************/
- #include <msp430x44x.h>
- /**************************************************
- 定义全局变量
- ***************************************************/
- unsigned char cnt; // 计数器
- unsigned char tian; // 天寄存器
- unsigned char key_code; // 按键值
- unsigned char flag; // 换屏标志位
- unsigned char twinkle_num; // 闪烁标志位
- unsigned char function_flag; // 加减功能标志位
- unsigned char function_ping1,function_ping2,function_ping3; // 每屏闪烁位
- unsigned char change_num; // 闪屏时间定时
- unsigned char change_ping; // 三屏计数位
- unsigned char clock_flag; // 闹钟标志位
- unsigned char ping_flag; // 按键跟踪闪屏标志位
- unsigned char num_flag; // 按键计数闪屏标志位
- unsigned char tian_flag; // 天判断标志位
- unsigned char run_flag; // 闰年判断标志位
- unsigned int key_num = 150; // 按键消逗延时时间
- unsigned int year = 2008; // 年
- unsigned char month = 2; // 月
- unsigned char day = 28; // 日
- unsigned char hour = 23; // 小时
- unsigned char min = 59; // 分
- unsigned char sec = 57; // 秒
- unsigned char nao_hour = 0; // 闹钟时
- unsigned char nao_min = 0; // 闹钟分
- unsigned char nao_sec = 0; // 闹钟秒
- const unsigned char tianshu[13] =
- {0,31,28,31,30,31,30,31,31,30,31,30,31}; // 每月天数表
- char digit[12] = // 液晶显示段码表
- {
- 0x7b,
- 0x12,
- 0x4f,
- 0x1f,
- 0x36,
- 0x3d,
- 0x7d,
- 0x13,
- 0x7f,
- 0x3F,
- 0x00
- };
- /**************************************************
- 定义子函数
- ***************************************************/
- void init_clk(void); // 初始化时钟
- void key_scan(void); // 按键扫描
- void key_value(void); // 按键值确定
- void rtc(void); // 时钟扫描函数
- void rtc_show(void); // rtc扫描函数
- void leap_year(void); // 闰年判定函数
- /**************************************************
- ** 函数名称:系统主函数
- ** 工作环境: IAR 3.42A
- ** 作者: 谷丰
- ** 生成日期: 2008.08.25
- ** 相关文件:
- ** 修改日志:
- ***************************************************/
- void main(void)
- {
- init_clk(); // 时钟初始化
- while(1)
- {
- key_scan(); // 按键扫描
- key_value(); // 键值确定
- rtc_show(); // RTC显示
- leap_year(); // 闰年判定
- if((sec == nao_sec) && (min == nao_min) && (hour == nao_hour)) // 闹钟判定
- {
- clock_flag = 1; // 闹钟标志位置一
- }
- }
- }
- /**************************************************
- ** 函数名称:系统初始化函数
- ** 工作环境: IAR 3.42A
- ** 作者: 谷丰
- ** 生成日期: 2008.08.20
- ** 功能:相关寄存器初始化
- ** 相关文件:
- ** 修改日志:
- ***************************************************/
- void init_clk(void)
- {
- unsigned char i;
- WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗
- FLL_CTL0 |= XCAP14PF; // 选择14PF电容
- IE2 |= BTIE; // 开启基本定时器中断
- BTCTL = BT_ADLY_250 + BTFRFQ1; // 250ms 16分频
- LCDCTL = LCDON + LCD4MUX + LCDP2; // STK LCD 4Mux, S0-S14
- P5SEL = 0xFC; // 选择P5口第二功能
- P1DIR |= 0x01; // P1.0选择输出
- _EINT(); // 开总中断
- for (i=0; i<19; i++)
- {
- LCDMEM[i] = 0; //清LCD缓冲区
- }
- }
- /**************************************************
- ** 函数名称:按键扫描函数
- ** 工作环境: IAR 3.42A
- ** 作者: 谷丰
- ** 生成日期: 2008.08.20
- ** 功能:按键扫描,键值确定
- ** 相关文件:
- ** 修改日志:
- ***************************************************/
- void key_scan(void)
- {
- static unsigned int num; // 按键消抖计数器
- if((P1IN&0x0e) != 0x0e) // 如果不等于表示有键按下
- {
- num++; // 消逗计数器加
- key_code = 0; // 键值清零
- }
- else
- {
- num = 0; // 按键抖动,键值清零
- key_code = 0; // 键值清零
- }
- if(num == key_num ) // 键值确定
- {
- num = 0; // 消逗寄存器清零
- twinkle_num = 0; // 闪烁清零
- key_code = ((P1IN&0x0e)>>1)^0x07; // 键值转换
- }
- }
- /**************************************************
- ** 函数名称:键值功能函数
- ** 工作环境: IAR 3.42A
- ** 作者: 谷丰
- ** 生成日期: 2008.08.20
- ** 功能:按键功能确定
- P1.1 闪烁、清除闹钟
- P1.2 + P1.1 加、清除闹钟
- P1.3 + P1.1 减、清除闹钟
- P1.2 闪屏、清除闹钟
- P1.3 清除闹钟
- ** 相关文件:
- ** 修改日志:
- ***************************************************/
- void key_value(void)
- {
- if(key_code == 0x01) // 第一个键被按下
- {
- function_flag = 1; // 功能键标志位置一
- clock_flag = 2; // 关闭闹钟
- if(change_ping == 0) // 第一屏
- {
- function_ping1 ++; // 数值闪烁加
- if(function_ping1 == 4) // 闪烁到第三位
- {
- if(tian_flag == 1)
- {
- function_ping1 = 1; //
- }
- else
- {
- function_ping1 = 0; // 清零
- function_flag = 0; // 功能键清零
- }
- }
- change_num = 0; // 换屏计数器
- }
- if(change_ping == 1) // 第二屏
- {
- function_ping2++; // 数值闪烁加
- if(function_ping2 == 4)
- {
- function_ping2 = 0;
- function_flag = 0; // 清零 // 功能标志位清零
- }
- change_num = 20; // 换屏时间计数器
- }
- if(change_ping == 2) // 第三屏
- {
- function_ping3++; // 数值闪烁加
- if(function_ping3 == 4)
- {
- function_ping3 = 0; // 清零
- function_flag = 0; // 功能标志位清零
- }
- change_num = 40; // 换屏计数器
- }
- }
- if((key_code == 0x02) && (function_flag == 1)) // 加法
- {
- clock_flag = 2; // 关闭闹钟
- if(function_ping2 == 1) // 秒闪烁
- {
- sec++; // 秒加
- if(sec == 60) // 秒是否等于60
- sec = 0; // 秒数清零
- }
- if(function_ping2 == 2) // 分闪烁
- {
- min++; // 分加
- if(min == 60) // 分是否等于60
- min = 0; // 分清零
- }
- if(function_ping2 == 3) // 小时闪烁
- {
- hour++; // 小时加
- if(hour == 24) // 小时是否等于24
- hour = 0; // 小时清零
- }
- if(function_ping1 == 1) // 日闪烁
- {
- day++; // 日加加
- if(day > tian) // 日是否大于天
- day = 1; // 日等于1
- }
- if(function_ping1 == 2) // 月闪烁
- {
- month++; // 月加加
- tian = tianshu[month];
- if(day > tian)
- {
- tian_flag = 1;
- }
- else
- tian_flag = 0;
- if(month == 13) // 月是否等于13
- month = 1; // 月等于1
- }
- if(function_ping1 == 3) // 年闪烁
- {
- year++; // 年加加
- if((year%4 != 0)||(year%100 != 0) || (year%400 == 0))
- {
- tian = tianshu[month];
- if(day > tian)
- {
- tian_flag = 1;
- }
- else
- tian_flag = 0;
- }
- if(year == 2100) // 年是否等于2100
- year = 2000; // 年到2000
- }
- if(function_ping3 == 1) // 闹钟秒闪烁
- {
- nao_sec++; // 闹钟秒加加
- if(nao_sec == 60) // 闹钟秒是否等于60
- nao_sec = 0; // 闹钟秒清零
- }
- if(function_ping3 == 2) // 闹钟分闪烁
- {
- nao_min++; // 闹钟分加加
- if(nao_min == 60) // 闹钟分是否等于60
- nao_min = 0; // 闹钟分清零
- }
- if(function_ping3 == 3) // 闹钟小时闪烁
- {
- nao_hour++; // 闹钟小时加加
- if(nao_hour == 24) // 闹钟小时是否等于24
- nao_hour = 0; // 闹钟小时清零
- }
- }
- if((key_code == 0x04) && (function_flag == 1)) // 减法
- {
- clock_flag = 2; // 清除闹钟标志位
- if(function_ping2 == 1)
- {
- sec--; // 秒减减
- if(sec == 0xff) // 秒是否等于0
- sec = 59; // 秒等于60
- }
- if(function_ping2 == 2)
- {
- min--; // 分减减
- if(min == 0xff) // 分是否等于0
- min = 59; // 分等于60
- }
- if(function_ping2 == 3)
- {
- hour--; // 小时减减
- if(hour == 0xff) // 小时是否等于0
- hour = 23; // 小时等于24
- }
- if(function_ping1 == 1)
- {
- day--; // 天减减
- if(day == 0) // 天是否等于0
- day = tian; // 天等于30/31/28/29
- }
- if(function_ping1 == 2)
- {
- month--; // 月减减
- if(month == 0) // 月是否等于0
- month = 12; // 月等于13
- tian = tianshu[month];
- if(day > tian)
- tian_flag = 1;
- else
- tian_flag = 0;
- }
- if(function_ping1 == 3)
- {
- year--; // 年减减
- if(year ==1999) // 年是否等于1999
- year = 2100; // 年等于2100
- if((year%4 != 0)||(year%100 != 0) || (year%400 == 0))
- {
- tian = tianshu[month];
- if(day > tian)
- {
- tian_flag = 1;
- }
- else
- tian_flag = 0;
- }
- }
- if(function_ping3 == 1)
- {
- nao_sec--; // 闹钟秒减减
- if(nao_sec == 0xff) // 闹钟秒是否等于0
- nao_sec = 59; // 闹钟秒等于60
- }
- if(function_ping3 == 2)
- {
- nao_min--; // 闹钟分减减
- if(nao_min == 0xff) // 闹钟分是否等于0
- nao_min = 59; // 闹钟分等于60
- }
- if(function_ping3 == 3)
- {
- nao_hour--; // 闹钟小时减减
- if(nao_hour == 0xff) // 闹钟小时是否等于0
- nao_hour = 23; // 闹钟小时等于24
- }
- }
- if((key_code == 0x02) && (function_flag == 0)) // 没有功能键按下时
- {
- clock_flag = 2; // 清除闹钟标志位
- flag = 1; // 换屏标志位被按下
- if(num_flag == 1) // 换屏位1
- ping_flag = 1;
- if(num_flag == 2) // 换屏位2
- ping_flag = 2;
- if(num_flag == 3) // 换屏位3
- ping_flag = 3;
- }
- if((key_code == 0x04) && (function_flag == 0))
- {
- clock_flag = 2; // 清除闹钟标志位
- }
- key_code = 0; // 键值清零
- }
- /**************************************************
- ** 函数名称:闰年判断函数
- ** 工作环境: IAR 3.42A
- ** 作者: 谷丰
- ** 生成日期: 2008.08.20
- ** 功能:判断年是否是闰年
- ** 相关文件:
- ** 修改日志:
- ***************************************************/
- void leap_year(void)
- {
- tian = tianshu[month]; // 读出每月天数表
- if(day < tian)
- tian_flag = 0;
- if(month == 2)
- {
- if((year%4 == 0)&&(year%100 != 0) || (year%400 == 0)) // 判断是否是闰年
- {
- tian = 29; // 闰年2月天数修正
- }
- else
- {
- tian = 28; // 闰年2月天数修正
- }
- }
- }
- /**************************************************
- ** 函数名称:时分秒加函数
- ** 工作环境: IAR 3.42A
- ** 作者: 谷丰
- ** 生成日期: 2008.08.20
- ** 功能:时分秒、年月日加
- ** 相关文件:
- ** 修改日志:
- ***************************************************/
- void rtc()
- {
- if(++sec < 60) // 秒加一
- return;
- sec = 0;
- if(++min < 60) // 分加一
- return;
- min = 0;
- if(++hour < 24) // 小时加一
- return;
- hour = 0;
- if(++day <= tian) // 天数加一
- return;
- day = 1; // 月加一
- if(++month <= 12)
- return;
- month = 1;
- if(++year < 2100) // 年加一
- return;
- year = 2000;
- }
- /**************************************************
- ** 函数名称:LCD显示函数
- ** 工作环境: IAR 3.42A
- ** 作者: 谷丰
- ** 生成日期: 2008.08.20
- ** 功能:LCD显示、闪烁、换屏
- ** 相关文件:
- ** 修改日志:
- ***************************************************/
- void rtc_show(void)
- {
- if((function_ping1 != 0) && (function_ping2 == 0) && (function_ping3 == 0))
- {
- change_ping = 0; // 第一屏
- }
- else if((function_ping1 == 0) && (function_ping2 != 0) && (function_ping3 == 0))
- {
- change_ping = 1; // 第二屏
- }
- else if((function_ping1 == 0) && (function_ping2 == 0) && (function_ping3 != 0))
- {
- change_ping = 2; // 第三屏
- }
- if(change_ping == 1)
- {
- if(function_ping2 == 0) // 正常显示
- {
- LCDMEM[0] = digit[sec%10];
- LCDMEM[1] = digit[sec/10];
- LCDMEM[2] = digit[min%10];
- LCDMEM[3] = digit[min/10];
- LCDMEM[4] = digit[hour%10];
- LCDMEM[5] = digit[hour/10];
- }
- if(function_ping2 == 1) // 秒闪烁
- {
- if(twinkle_num == 0) // 闪烁标志位
- {
- LCDMEM[0] = digit[sec%10];
- LCDMEM[1] = digit[sec/10];
- }
- else
- {
- LCDMEM[0] = 0;
- LCDMEM[1] = 0;
- }
- LCDMEM[2] = digit[min%10];
- LCDMEM[3] = digit[min/10];
- LCDMEM[4] = digit[hour%10];
- LCDMEM[5] = digit[hour/10];
- }
- if(function_ping2 == 2) // 分闪烁
- {
- if(twinkle_num == 0)
- {
- LCDMEM[2] = digit[min%10];
- LCDMEM[3] = digit[min/10];
- }
- else
- {
- LCDMEM[2] = 0;
- LCDMEM[3] = 0;
- }
- LCDMEM[0] = digit[sec%10];
- LCDMEM[1] = digit[sec/10];
- LCDMEM[4] = digit[hour%10];
- LCDMEM[5] = digit[hour/10];
- }
- if(function_ping2 == 3) // 小时闪烁
- {
- if(twinkle_num == 0)
- {
- LCDMEM[4] = digit[hour%10];
- LCDMEM[5] = digit[hour/10];
- }
- else
- {
- LCDMEM[4] = 0;
- LCDMEM[5] = 0;
- }
- LCDMEM[0] = digit[sec%10];
- LCDMEM[1] = digit[sec/10];
- LCDMEM[2] = digit[min%10];
- LCDMEM[3] = digit[min/10];
- }
- }
- if(change_ping == 0)
- {
- if(function_ping1 == 0) // 正常显示
- {
- LCDMEM[0] = digit[(day)%10];
- LCDMEM[1] = digit[(day)/10];
- LCDMEM[2] = digit[(month)%10];
- LCDMEM[3] = digit[(month)/10];
- LCDMEM[4] = digit[year%10];
- LCDMEM[5] = digit[(year/10)%10];
- }
- if(function_ping1 == 1) // 天闪烁
- {
- if(twinkle_num == 0)
- {
- LCDMEM[0] = digit[day%10];
- LCDMEM[1] = digit[day/10];
- }
- else
- {
- LCDMEM[0] = 0;
- LCDMEM[1] = 0;
- }
- LCDMEM[2] = digit[(month)%10];
- LCDMEM[3] = digit[(month)/10];
- LCDMEM[4] = digit[year%10];
- LCDMEM[5] = digit[(year/10)%10];
- }
- if(function_ping1 == 2) // 月闪烁
- {
- if(twinkle_num == 0)
- {
- LCDMEM[2] = digit[(month)%10];
- LCDMEM[3] = digit[(month)/10];
- }
- else
- {
- LCDMEM[2] = 0;
- LCDMEM[3] = 0;
- }
- LCDMEM[0] = digit[day%10];
- LCDMEM[1] = digit[day/10];
- LCDMEM[4] = digit[year%10];
- LCDMEM[5] = digit[(year/10)%10];
- }
- if(function_ping1 == 3) // 年闪烁
- {
- if(twinkle_num == 0)
- {
- LCDMEM[4] = digit[year%10];
- LCDMEM[5] = digit[(year/10)%10];
- }
- else
- {
- LCDMEM[4] = 0;
- LCDMEM[5] = 0;
- }
- LCDMEM[0] = digit[(day)%10];
- LCDMEM[1] = digit[(day)/10];
- LCDMEM[2] = digit[(month)%10];
- LCDMEM[3] = digit[(month)/10];
- }
- }
- if(change_ping == 2)
- {
- if(function_ping3 == 0) // 正常显示
- {
- LCDMEM[0] = digit[nao_sec%10];
- LCDMEM[1] = digit[nao_sec/10];
- LCDMEM[2] = digit[nao_min%10];
- LCDMEM[3] = digit[nao_min/10];
- LCDMEM[4] = digit[nao_hour%10];
- LCDMEM[5] = digit[nao_hour/10];
- }
- if(function_ping3 == 1) // 闹钟秒闪烁
- {
- if(twinkle_num == 0)
- {
- LCDMEM[0] = digit[nao_sec%10];
- LCDMEM[1] = digit[nao_sec/10];
- }
- else
- {
- LCDMEM[0] = 0;
- LCDMEM[1] = 0;
- }
- LCDMEM[2] = digit[nao_min%10];
- LCDMEM[3] = digit[nao_min/10];
- LCDMEM[4] = digit[nao_hour%10];
- LCDMEM[5] = digit[nao_hour/10];
- }
- if(function_ping3 == 2) // 闹钟分闪烁
- {
- if(twinkle_num == 0)
- {
- LCDMEM[2] = digit[nao_min%10];
- LCDMEM[3] = digit[nao_min/10];
- }
- else
- {
- LCDMEM[2] = 0;
- LCDMEM[3] = 0;
- }
- LCDMEM[0] = digit[nao_sec%10];
- LCDMEM[1] = digit[nao_sec/10];
- LCDMEM[4] = digit[nao_hour%10];
- LCDMEM[5] = digit[nao_hour/10];
- }
- if(function_ping3 == 3) // 闹钟小时闪烁
- {
- if(twinkle_num == 0)
- {
- LCDMEM[4] = digit[nao_hour%10];
- LCDMEM[5] = digit[nao_hour/10];
- }
- else
- {
- LCDMEM[4] = 0;
- LCDMEM[5] = 0;
- }
- LCDMEM[0] = digit[nao_sec%10];
- LCDMEM[1] = digit[nao_sec/10];
- LCDMEM[2] = digit[nao_min%10];
- LCDMEM[3] = digit[nao_min/10];
- }
- }
- }
- /**************************************************
- ** 函数名称:基本定时器中断函数
- ** 工作环境: IAR 3.42A
- ** 作者: 谷丰
- ** 生成日期: 2008.08.20
- ** 功能:秒+,5s换屏,闹钟闪烁,修改闪烁
- ** 相关文件:
- ** 修改日志:
- ***************************************************/
- #pragma vector=BASICTIMER_VECTOR
- __interrupt void basic_timer (void)
- {
- if(clock_flag == 1) // 闹钟存在
- P1OUT ^= BIT0; // LED闪烁
- if(clock_flag == 2) // 闹钟清除
- P1OUT &= ~BIT0; // 关闭LED
- cnt++; // 1s计数器加
- if(cnt == 4) // 是否等于4
- {
- rtc(); // 秒加一
- cnt = 0; // 清零
- }
- change_num++; // 换屏计数器
- twinkle_num = ~twinkle_num; // 闪烁标志位
- if(change_num == 60) // 屏幕切换计数器到时复位
- {
- change_num = 0; //
- }
- if(((change_num > 0) && (change_num < 20) || (change_num == 0)) || ((ping_flag == 1) && (flag == 1)))
- {
- if((ping_flag == 1) && (flag == 1)) // 按键时在第一屏
- {
- change_num = 20; // 切换到第二屏
- flag = 0; // 按键标志位清零
- }
- change_ping = 0; // 第一屏
- num_flag = 1; // 屏切换标志位1
- }
- if(((change_num > 20) && (change_num < 40) || (change_num == 20)) || ((ping_flag == 2) && (flag == 1)))
- {
- if((ping_flag == 2) && (flag == 1)) // 按键时在第二屏
- {
- change_num = 40; // 切换到第三屏
- flag = 0;
- }
- change_ping = 1; // 第二屏
- num_flag = 2; // 屏切换标志位2
- }
- if(((change_num > 40) && (change_num < 60) || (change_num == 40)) || ((ping_flag == 3) && (flag == 1)))
- {
- if((ping_flag == 3) && (flag == 1)) // 按键时在第二屏
- {
- change_num = 0; // 切换到第1屏
- flag = 0;
- }
- change_ping = 2; // 第三屏
- num_flag = 3; // 屏切换标志位3
- }
- }