【ACCESS精品源码栏目提醒】:网学会员在ACCESS精品源码频道为大家收集整理了“【精品】嵌入式时钟源代码 - 其它资料“提供大家参考,希望对大家有所帮助!
例题 18-5 程序代码 1选项字设置程序 onchip.asm(可参阅附录 E) OPT CSEG AT 0080H 地址定位在0080H单元 OPTION: DB 00H 0080H定义为00H,不使用看门狗定时器,可由软件停止内部低速振荡器 DB 00H 0081H定义为00H,选择1.59 V POC模式 DB 00H 0082H为保留区域 DB 00H 0083H为保留区域 DB 03H 0084H定义为03H,允许片上调试, END 2C 语言程序 pragma sfr //使用特殊功能寄存器 pragma access //使用绝对地址指令 pragma EI //使用开中断和关中断功能 pragma DI pragma interrupt INTKR inter RB1 //定义按键中断 inter pragma interrupt INTRTC half_sec_INTERRUPT //使用 INTRTC 中断功能,命名中断为 half_sec_INTERRUPT void freshddisplaybuffer //显示缓冲区刷新函数 void play4bit //显示函数 void d_c_inter //切换函数 void set_inter //调时函数 void set_hour //闹钟时显示函数 void set_minute //闹钟分显示函数 void hour_inter //闹钟调时函数 void minute_inter //闹钟调分函数 void delay //延时函数 void noise //闹钟响铃函数 unsigned int half_second0second0 //初始化使 0.5 秒单元0,秒单元0 unsigned int minute0hour0 //初始化使分单元0,小时单元0 unsigned int day1month1 //初始化使日单元1,月单元1 unsigned int year2001 //初始化使年单元2001 unsigned int hour10 //初始化闹钟时单元0 unsigned int minute10 //初始化闹钟分单元0 unsigned int temp //临时变量 unsigned intnumbercode100x070d0x06000x030e0x070a0x06030x050b0x050f0x07000x070f0x070b //数字quot0quot~quot9quot的显示码 unsigned char i0/显示转换标志,i0 显示年,i1 显示月,i2 显示月和日,i3 显示时,i4 显示时和分,i5 显示分和秒/ unsigned char j0 //定义 INTRTC 中断标志变量 j unsigned char KEY0 //定义全局变量 KEY unsigned int buffyear4 //年的数码显示缓存区 unsigned int buffm4 //月的数码显示缓存区 unsigned int buffmd4 //月和日的数码显示缓存区 unsigned int buffh4 //时的数码显示缓存区 unsigned int buffhm4 //时和分的数码显示缓存区 unsigned int buffms4 //分和秒的数码显示缓存区 unsigned int buffhm14 //闹钟的时和分数码显示缓冲区 //--------------------------------------------------------------------计算当前月中天数的函数 unsigned int m_daysunsigned int mmonthunsigned int days if mmonth4mmonth6mmonth9mmonth11 days30 //46911 月为 30 天 else if mmonth2 if year40 ampamp year 1000year4000 days29 //闰年 2 月为 29 天 else days28 //平年 2 月为 28 天 else days31 //135781012 月为 31 天 return days//-------------------------------------------------------------------显示函数void play4bitunsigned int dp0 // dp 为显示位数计数 unsigned int b4 //显示输出缓存区 unsigned int LCD_addr //定义 LCD 地址 LCD_addr0xFA46 //初始化 LCD 地址为 0xFA46 whiledplt4 //4 个 LED 显示器依次显示一遍 switchi case 0:bdpbuffyeardpbreak //若显示转换标志为 0,显示年 case 1:bdpbuffmdpbreak //若显示转换标志为 1,显示月 case 2:bdpbuffmddpbreak //若显示转换标志为 2,显示月和日 case 3:bdpbuffhdpbreak //若显示转换标志为 3,显示时 case 4:bdpbuffhmdpbreak //若显示转换标志为 4,显示时和分 case 5:bdpbuffmsdpbreak //若显示转换标志为 5,显示分和秒 pokew LCD_addrbdp //显示器位控制码送位控制存储单元 delay //延时函数 pokewLCD_addr0x0000 //关闭显示 LCD_addrLCD_addr-2 dp //显示位计数加 1 //--------------------------------------------------------------------闹钟时显示函数void set_hour unsigned int dp2 unsigned int a4 unsigned int LCD_addr LCD_addr0xFA42 buffhm13numbercodehour1/10 //时的显示码放入时和分的数码显示缓存 buffhm12numbercodehour110 buffhm12 0x0800 //在时的个位后显示一个点“” whiledplt4 //4 个 LED 显示器依次显示一遍 adpbuffhm1dp pokew LCD_addradp //显示器位控制码送位控制存储单元 delay //延时函数 pokewLCD_addr0x0000 LCD_addrLCD_addr-2 dp //显示计数器加 1 //--------------------------------------------------------------------闹钟秒显示函数void set_minute unsigned int dp0 unsigned int b4 unsigned int LCD_addr LCD_addr0xFA46 buffhm11numbercodeminute1/10 //时的显示码放入时和分的数码显示缓存 buffhm10numbercodeminute110 whiledplt2 //4 个 LED 显示器依次显示一遍 bdpbuffhm1dp pokew LCD_addrbdp //显示器位控制码送位控制存储单元 delay //延时函数 pokewLCD_addr0x0000 LCD_addrLCD_addr-2 dp //显示计数器加 1 //--------------------------------------------------------------------闹钟调时函数void hour_inter ifhour1lt23hour1 else hour10//---------------------------------------------------------------------闹钟调分函数void minute_inter ifminute1lt59minute1 else minute10//--------------------------------------------------------------------时间函数void time if j 0 //0.5 秒标志到了吗? j 0 half_second if half_second20 //判断到了 1 秒吗? second if secondgt60 //秒大于 60 时,分加 1 second0 minute if minutegt60 //分大于 60 时,时加 1 minute0 hour if hourgt24 //时大于 24 时,天加 1 hour0 day tempm_daysmonth //判断该月是多少天 if daygttemp //该月最后一天到时,月加 1 day1 month if monthgt13 //月大于 12 后年加 1 month1 year //------------------------------------------------------------------------按键中断处理函数 void inter DI //关中断 switchP4 amp 0x3F //判断那个按键按下 case 0x3e: KEY1 //按键 key1 按下 break case 0x3d: KEY2 //按键 key2 按下 break case 0x3b: KEY3 //按键 key3 按下 break case 0x37: KEY4 //按键 key4 按下 break case 0x2f: KEY5 //按键 key5 按下 break case 0x1f: KEY6 //按键 key6 按下 break default: break EI //开中断 //----------------------------------------------------------------------切换时间函数void d_c_inter DI //关中断 ifilt5 i //显示切换标志 i 小于 5,i 加 1 else i0 //显示切换标志 i 等于 5,i 清“0” EI //开中断//------------------------------------------------------------------------调整时间函数void set_interunsigned int xy DI //关中断 xyear1000 //取年的个位数到变量 x 中 yyear1000 //取年的个位数到变量 y 中 switchi case 0: ifxlt9 x //如果年的个位数小于 9,年加 1 else x0 //如果年的个位数等于 9,年的个位清“0” yearyear-yx break case 1: ifmonthlt12 month //月计数值小于 12,月值加 1 else month1 break //月计数值等于 12,月值清“0” case 2: tempm_daysmonth //判断该月是多少天 ifdaygttemp day1 //日计数值是该月最后一天时,day1 else day //日计数值不是该月最后一天时,day break case 3: ifhourlt23 hour //时计数值小于 23,时值加 1 else hour0 //时计数值等于 23,时值清“0” break case 4: ifminutelt59 minute //分计数值小于 59,分值加 1 else minute0 //分计数值等于 59,分值清“0” break case 5: ifsecondlt59 second //秒计数值小于 59,秒值加 1 else second0 //秒计数值等于 59,秒值清“0” break EI //开中断//---------------------------------------------------------------------闹钟响铃函数void noise ifhour1hourampampminute1minuteampampP3.41 CKS0X80 //打开蜂鸣器输出,输出频率为 7.81kHz 的音频 delay //延时 BZOE0 //关闭蜂鸣器 //-------------------------------------------------------------------延时函数void delay int i fori0ilt100i //---------------------------------------------------------------主函数void main PCC 0x00 // CPU 的时钟选择(5.0MHz)PFALL0x0F //所有接 LCD 引脚指定为 LCD 引脚LCDC00x45 //确定 LCD 的显示频率LCDMD0x10 // LCD 电源设置为 1/5VDDLCDM0xC0 //LCD 显示开 IPM4 0x3F //P4 的 6 个端口设置输入模式PU4 0x3F //接通上拉电阻KRM 0x3F //允许 6 个按键中断KRMK 0 P3.4 0 //LED 灯初始化为灭 PM3.40 //P3.3 和 P3.4 端口设置为输出模式P3.3 0 PM3.30RTCMK0 //允许产生中断OSCSELS 1 //启动副系统时钟 RTCCL 0 //实时计数器的输入时钟为副系统时钟 RTCC0 0x09 //停止计数器操作,禁止 RTC1HZ 引脚输出, //RTCCL 引脚输出选择 24 小时系统,选择 //0.5 秒一次固定周期中断RTCE 1 //启动计数器工作 EI //开中断 while1 switchKEY case 0: //如果没有按键 time //调用时间函数 noise //调用闹钟响铃函数 freshddisplaybuffer //调用显示缓冲区刷新函数 play4bit //调用显示函数 break case 1: //按键 key1 被按下 time //调用时间函数 d_c_inter //调用切换时间函数 freshddisplaybuffer //调用显示缓冲区刷新函数 play4bit //调用显示函数 KEY0 break case 2: time set_hour //调用闹钟时显示函数 set_minute //调用闹钟分显示函数 KEY7 break case 3: //按键 key3 被按下 time //调用时间函数 set_inter //调用时间调整函数 freshddisplaybuffer //调用显示缓冲区刷新函数 play4bit //调用显示函数 KEY0 break case 4: time //调用时间函数 P3.4P3.4 //切换 LED 灯亮灭情况 KEY0 break case 5: time; //调用时间函数 hour_inter //调用闹钟调时函数 set_hour //调用闹钟显示函数 KEY7 breakcase 6: time //调用时间函数 minute_inter //调用闹钟调分函数 set_minute //调用闹钟显示函数 KEY7 break case 7: time //调用时间函数 noise //调用闹钟响铃函数 set_hour //调用闹钟时显示函数 set_minute //调用闹钟分显示函数 break //-------------------------------------------------------------------实时计数器0.5s中断处理函数 void half_sec_INTERRUPT DI j1 //每隔 0.5s j 的值赋值 1 EI //---------------------------------------------------------------------显示缓冲区刷新函数 void freshddisplaybuffervoid buffyear3numbercodeyear/100/10 //年的显示码放入年的数码显示缓存区 buffyear2numbercodeyear/10010 buffyear1numbercodeyear100/10 buffyear0numbercodeyear10010 buffm30x070d //月的显示码放入年的数码显示缓存区 buffm20x070d buffm1numbercodemonth/10 buffm0numbercodemonth10 buffmd3numbercodemonth/10 //月和日的显示码放入年的数码显示缓存区 buffmd2numbercodemonth10 buffmd2 0x080.