版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、完整程序#include#include intrins.h#define uchar unsigned char#define uint unsigned intunsigned char hour, min, sec, year, month, day; / 当前时间、日期unsigned char Tab_Num = 0xc0, 0xf9, 0xa4, 0xb0, 0x99,0x92, 0x82, 0xf8, 0x80, 0x90; / 0-9数字主要用于数码管的显示uchar show_status; / LED 显示状态标志/ 0:设置闹钟数据/ 1:显示当前日期及星期/ 2:显示当
2、前时间/ 3:设置当前日期/ 4:设置当前时间structunsigned char h_b; / 小时设置开始的时间unsigned char m_b; / 分钟设置开始的时间unsigned char h_s; / 小时设置停止的时间unsigned char m_s; / 分钟设置停止的时间alarm18; / 用于设置六路闹钟的十八个闹钟开始时间结构体定义 /char sound; / 闹钟开启标志高电平有效uchar cur_alarm_set; / 当前设置的闹钟项uchar alarm_k, alarm_g; / 闹钟开关时间设置标志 为1时有效bit new_alarm_inf
3、o; / 闹钟项内容已修改标志unsigned char attr; / 八个数码管的闪烁控制字节,当为0时,对应数码管闪 /sbit out_alarm1 = P3 2; / 用于输出各自对应的闹钟sbit out_alarm2 = P3 3;sbit out_alarm3 = P3 4;sbit out_alarm4 = P3 5;sbit out_alarm5 = P3 6;sbit out_alarm6 = P3 7; / 六路闹钟位定义sbit DSSCLK = P0 5; / 时间引脚采用分时复用sbit clock_dat = P0 6;sbit clock_rst = P0 7
4、; / ds1302管脚定义sbit SDA_PIN = P0 4; / EEPROM24CO8串行数据线端口 sbit a0 = ACC 0;sbit a1 = ACC 1;sbit a2 = ACC 2;sbit a3 = ACC 3;sbit a4 = ACC 4;sbit a5 = ACC 5;sbit a6 = ACC 6;sbit a7 = ACC 7; / 为了编程方便定义的ds1302寄存器的位变量voiddelay(int num) / 延时函数while (num-);/* +ds1302操作的时序与读写*+*/voidclock_write(unsigned char d
5、d) / 写入一个字节,DS1302时序,这里不用循环移位写入方法,而是直接用变量来产生写入的时钟ACC = dd;DSSCLK = 0;clock_dat = a0;DSSCLK = 1;DSSCLK = 0;clock_dat = a1;DSSCLK = 1;DSSCLK = 0;clock_dat = a2;DSSCLK = 1;DSSCLK = 0;clock_dat = a3;DSSCLK = 1;DSSCLK = 0;clock_dat = a4;DSSCLK = 1;DSSCLK = 0;clock_dat = a5;DSSCLK = 1; DSSCLK = 0; clock_d
6、at = a6; DSSCLK = 1; DSSCLK = 0; clock_dat = a7; DSSCLK = 1; unsigned charclock_read(void) DSSCLK = 1; DSSCLK = 0; a0 = clock_dat; DSSCLK = 1; DSSCLK = 0; a1 = clock_dat; DSSCLK = 1; DSSCLK = 0; a2 = clock_dat; DSSCLK = 1; DSSCLK = 0; a3 = clock_dat; DSSCLK = 1; DSSCLK = 0; a4 = clock_dat; DSSCLK =
7、1; DSSCLK = 0; a5 = clock_dat; DSSCLK = 1; DSSCLK = 0; a6 = clock_dat; DSSCLK = 1; DSSCLK = 0; a7 = clock_dat; return (ACC); unsigned charread_clock(unsigned char reg1) unsigned char dd = 0; / 读出一个字节,DS1302时序 / 从reg1寄存器读数据DSSCLK = 0;clock_rst = 0;clock_rst = 1;clock_write(reg1); / 首先发送要读的地址dd = cloc
8、k_read(); / 读出该地址的数据clock_rst = 0;return (dd); / 将读出的数据反回voidwrite_clock(unsigned char reg2, unsigned char date) / 向reg2写入date数据 /DSSCLK = 0;clock_rst = 0;clock_rst = 1;clock_write(reg2);clock_write(date);clock_rst = 0;/*24C08使用I2C操作函数*/voidI2cDelay() / EEPROM操作时需要的延时函数_nop_();_nop_();_nop_();_nop_(
9、);_nop_();_nop_();voidDelayX1ms(unsigned char count) / 延迟函数,参数为毫秒数unsigned char i, j;for (i = 0; i count; i+)for (j = 0; j 240; j+);voidStart() / I2C启动,24C08使用I2C方式SDA_PIN = 1;I2cDelay();DSSCLK = 1;I2cDelay(); / 时钟线在高电平状态下,数据线从高到低的跳变 /SDA_PIN = 0;I2cDelay(); / 保持时钟线为低表示i2c在启动状态中 DSSCLK = 0;voidStop(
10、) / I2C停止I2cDelay();SDA_PIN = 0; / 时钟线在高电平I2cDelay();DSSCLK = 1;I2cDelay();SDA_PIN = 1;I2cDelay();bitSendByte(unsigned char value) / 发送1字节数据给EEPROMunsigned char i;bit no_ack = 0; / 定义应答信号for (i = 0; i 8; i+) / 发送8位数据I2cDelay();if (value & 0x80)SDA_PIN = 1;elseSDA_PIN = 0; / 将数据一位一位的送写入先写高位value = va
11、lue 1;I2cDelay();DSSCLK = 1;I2cDelay();I2cDelay();DSSCLK = 0; / 产生8个时钟脉冲I2cDelay(); SDA_PIN = 1; / 确认脉冲周期,等待EEPROM的确认 I2cDelay(); DSSCLK = 1; / 第九个脉冲周期,产生应答信号 I2cDelay();if (SDA_PIN = 1)no_ack = 1; / 表示无应答,数据传送不成功I2cDelay();DSSCLK = 0;return no_ack;voidmywrite(unsigned char address, unsigned char va
12、lue) / 向EEPROM写1字节 /Start();SendByte(0xa0); / 写命令SendByte(address); / 写地址SendByte(value); / 写数据Stop();DelayX1ms(10);unsigned charReadByte() / 从EEPROM接收1字节unsigned char i, bval;bval = 0;for (i = 0; i 8; i+) / 接收8位数据I2cDelay();SDA_PIN = 1; / 从P1输入数据时,先往P1输入1 I2cDelay();DSSCLK = 1;I2cDelay();bval = bva
13、l 4; / 将该值右移四位e = e & 0x0f; / 将高4位全置0剩下秒的数据P2 = Tab_Nume; / 段选送秒个位P1 = 0xfb; / 位选选中秒个位delay(250);P1 = 0xff; / 关数码管一小会P2 = Tab_Numd; / 秒十位P1 = 0xf7; / 段选送秒的十位delay(250);P1 = 0xff; / 关数码管一小会d = read_clock(0x83); / 读分钟e = d;d = d 4;e = e & 0x0f;P2 = Tab_Nume; / 分个位P1 = 0xef;delay(250);P1 = 0xff; / 关数码管
14、一小会P2 = Tab_Numd; / 分十位P1 = 0xdf;delay(250);P1 = 0xff; / 关数码管一小会d = read_clock(0x85); / 读小时e = d;d = d 4;e = e & 0x0f;P2 = Tab_Nume; / 小时各位P1 = 0xbf;delay(250);P1 = 0xff;P2 = Tab_Numd; / 小时十位P1 = 0x7f;delay(250);P1 = 0xff;else / 设置时间状态if (attr = 0x01 | attr = 0x08) / 因为时间只用六位数码管所以有两人状态相同/for (i = 0;
15、 i 4; e = e & 0x0f; P2 = Tab_Nume; / 小时各位P1 = 0xbf;delay(250);P1 = 0xff;P2 = Tab_Numd; / 小时十位P1 = 0x7f;delay(250);P1 = 0xff;delay(20000); / 先动态显示然后判断一产生闪烁效果 / 均为调整时间的小时位,此时这两个数码管闪烁 /if (attr = 0x02) / 数码管的三四两位闪烁for (i = 0; i 4;e = e & 0x0f;P2 = Tab_Nume; / 分个位P1 = 0xef;delay(250);P1 = 0xff; / 关数码管一小
16、会P2 = Tab_Numd; / 分十位P1 = 0xdf;delay(250);P1 = 0xff; / 关数码管一小会delay(20000); / 先动态显示然后判断一产生闪烁效果if (attr = 0x04) / 数码管的三四两位闪烁for (i = 0; i 4;e = e & 0x0f;P2 = Tab_Nume;P1 = 0xfb;delay(250);P1 = 0xff; / 关数码管一小会P2 = Tab_Numd; / 秒十位P1 = 0xf7; / 段选送秒的十位delay(250);P1 = 0xff; / 关数码管一小会delay(20000); / 先动态显示然
17、后判断一产生闪烁效果if (show_status = 1 | show_status = 3) / 表示此状态为显示8位的日期,年,月,日 /if (show_status = 1)d = read_clock(0x87); / 读日期的日e = d; / 将函数返回的值赋给变量d = d 4; / 将该值右移四位e = e & 0x0f;P2 = Tab_Nume; / 段选送天的个位P1 = 0xfe; / 位选选中秒个位 delay(250); P1 = 0xff; / 关数码管一小会 P2 = Tab_Numd; / 天的十位P1 = 0xfd;delay(250);P1 = 0xf
18、f; / 关数码管一小会d = read_clock(0x89); / 读月e = d;d = d 4;e = e & 0x0f;P2 = Tab_Nume; / 月的个位P1 = 0xfb;delay(250);P1 = 0xff; / 关数码管一小会P2 = Tab_Numd;P1 = 0xf7;delay(250);P1 = 0xff; / 关数码管一小会d = read_clock(0x8b); / 读年e = d;d = d 4;e = e & 0x0f;P2 = Tab_Nume;P1 = 0xef; delay(250); P1 = 0xff; P2 = Tab_Numd;P1
19、= 0xdf;delay(250);P1 = 0xff;P2 = Tab_Num0; / 年的百位与千位从20开始P1 = 0xbf;delay(250);P1 = 0xff;P2 = Tab_Num2;P1 = 0x7f;delay(250);P1 = 0xff;elseif (attr = 0x01 | attr = 0x02) / 因为日期的前两位数码管显示固定为“20” /for (i = 0; i 4; e = e & 0x0f; P2 = Tab_Nume;P1 = 0xef;delay(250);P1 = 0xff;P2 = Tab_Numd;P1 = 0xdf;delay(25
20、0);P1 = 0xff;delay(20000); / 这里直接从第三四个数码管开始闪烁 if (attr = 0x03)for (i = 0; i 4;e = e & 0x0f;P2 = Tab_Nume; / 月的个位P1 = 0xfb;delay(250);P1 = 0xff; / 关数码管一小会delay(20000); / 日期的五六位开始闪烁if (attr = 0x04)for (i = 0; i 4; / 将该值右移四位e = e & 0x0f;P2 = Tab_Nume; / 段选送天的个位P1 = 0xfe; / 位选选中秒个位 P2 = Tab_Numd; P1 = 0
21、xf7; delay(250); P1 = 0xff; / 关数码管一小会delay(250);P1 = 0xff; / 关数码管一小会P2 = Tab_Numd; / 天的十位P1 = 0xfd;delay(250);P1 = 0xff; / 关数码管一小会delay(20000); / 使其闪烁关数码管一小会 / 日期显示的最后两人数码管开始闪烁if (show_status = 0) / 表示当前状态为设置闹钟if (alarm_k = 1 & alarm_g = 0) / 当前显示的是设闹钟的开始时间 /sshi = (alarmcur_alarm_set.h_b) / 10;sge
22、= (alarmcur_alarm_set.h_b) % 10;fshi = (alarmcur_alarm_set.m_b) / 10;fge = (alarmcur_alarm_set.m_b) % 10; / 首先分离出当前设置闹钟的时的分的个位与十位便于显示/lu_s = cur_alarm_set / 10;lu_g = cur_alarm_set % 10; / 用于显示当前正在设置的闹钟的路数 /if (attr = 0x01) / 在闹钟设置时只有四位数码管会产生闪烁当闪烁标志为此时/ 闹钟的小时两位闪烁for (i = 0; i 20; i+)P2 = Tab_Numsshi
23、;P1 = 0x7f;delay(250);P1 = 0xff;P2 = Tab_Numsge;P1 = 0xbf;delay(250);P1 = 0xff;P2 = Tab_Numlu_s;P1 = 0x7f;delay(250);数友管的路数 P1 = 0xfd; P2 = Tab_Numlu_g; P1 = 0xfe; delay(250); P1 = 0xff; / 在闹钟设置时用数码管的最后两位显示当前所设置的/ / 动态显示delay(20000); / 数码管关一会,产生闪烁的效果if (attr = 0x02) / 当闪烁标志为此值时闹钟的分钟开始闪 for (i = 0; i
24、 20; i+)P2 = Tab_Numfshi;P1 = 0xdb;delay(250);P1 = 0xff;P2 = Tab_Numfge;P1 = 0xef;delay(250); P1 = 0xff; P2 = Tab_Numlu_s; P1 = 0x7f;delay(250);P1 = 0xfd;数友管的路数 P2 = Tab_Numlu_g; P1 = 0xfe; delay(250); P1 = 0xff; / 在闹钟设置时用数码管的最后两位显示当前所设置的/delay(20000);if (alarm_k = 0 & alarm_g = 1) / 当前显示的是设闹钟的结束时间
25、/sshi = (alarmcur_alarm_set.h_s) / 10;sge = (alarmcur_alarm_set.h_s) % 10;fshi = (alarmcur_alarm_set.m_s) / 10;fge = (alarmcur_alarm_set.m_s) % 10; / 首先分离出当前设置闹钟的时的分的个位与十位便于显示/lu_s = cur_alarm_set / 10;lu_g = cur_alarm_set % 10; / 用于显示当前正在设置的闹钟的路数 /if (attr = 0x01) / 在闹钟设置时只有四位数码管会产生闪烁当闪烁标志为此时/ 闹钟的小
26、时两位闪烁for (i = 0; i 20; i+)P2 = Tab_Numsshi;P1 = 0x7f;delay(250);P1 = 0xff;P2 = Tab_Numsge;P1 = 0xbf;delay(250);P1 = 0xff;P2 = Tab_Numlu_s;P1 = 0x7f;delay(250);P1 = 0xfd;数友管的路数 P2 = Tab_Numlu_g; P1 = 0xfe; delay(250); P1 = 0xff; / 在闹钟设置时用数码管的最后两位显示当前所设置的/ / 动态显示delay(20000); / 数码管关一会,产生闪烁的效果if (attr
27、= 0x02 | attr = 0x04) / 当闪烁标志为此值时闹钟的分钟开始闪 /for (i = 0; i 31)day = 1;write_clock(0x86, day); / 将校正写回到寄存器/return;if (keytmp = 4) / 第三个按钮switch (attr) / 8个数码管的闪烁控制字节来判断按该键前的状态/case 0xff:if (show_status = 1 | show_status = 2) / 如果无闪烁状态/show_status = 0;cur_alarm_set = 0;attr = 0x01;alarm_k = 0;alarm_g =
28、1; / 直接进入设置十八路闹钟的关时间break;case 0x01: / 数码管的前两位已在闪烁if (show_status = 0) / 当前为闹钟设置状态if (alarm_k = 1 & alarm_g = 0)alarmcur_alarm_set.h_b = (alarmcur_alarm_set.h_b -1); / 当前开闹钟时减一/if (alarmcur_alarm_set.h_b = 0)alarmcur_alarm_set.h_b = 24;new_alarm_info = 1; / 表示闹钟项已修改/if (alarm_k = 0 & alarm_g = 1)ala
29、rmcur_alarm_set.h_s = (alarmcur_alarm_set.h_s -1); / 当前关闹钟时减一/if (alarmcur_alarm_set.h_s = 0)alarmcur_alarm_set.h_s = 24;new_alarm_info = 1; / 表示闹钟项已修改/else if (show_status = 4) / 当前显示状态为时间较正/hour = read_clock(0x85); / 读小时hour = (hour - 1); / 当前时间的时减一if (hour = 0)hour = 24;write_clock(0x84, hour); /
30、 将校正写回到寄存器/break;case 0x02: / 数码管三四位闪烁if (show_status = 0) / 将当前闹钟的分加一if (alarm_k = 1 & alarm_g = 0)alarmcur_alarm_set.m_b = (alarmcur_alarm_set.m_b -1); / 当前开闹钟的分减/if (alarmcur_alarm_set.m_b)alarmcur_alarm_set.m_b = 60;new_alarm_info = 1;if (alarm_k = 0 & alarm_g = 1)alarmcur_alarm_set.m_s = (alarm
31、cur_alarm_set.m_s -1); / 当前关闹钟的分减一/if (alarmcur_alarm_set.m_s)alarmcur_alarm_set.m_s = 60;new_alarm_info = 1; / 表示闹钟项已修改 /else if (show_status = 3)year = read_clock(0x8d); / 读年year = year - 1; / 当前日期的年减 一if (year = 0)year = 99;write_clock(0x8c, year); / 将校正写回到寄存器 /else if (show_status = 4)min = read
32、_clock(0x83); / 读分min = (min - 1); / 当前时间的 分减一if (min = 0)min = 60;write_clock(0x82, min); / 将校正写回到寄存器 /break;case 0x03: / 数码的五六位正闪烁if (show_status = 3)month = read_clock(0x89); / 读月;month = month - 1; /if (month = 0)month = 12;write_clock(0x88, month); / 将校正的年写回到寄存器 /else if (show_status = 4)sec =
33、read_clock(0x81); / 读出当前的秒sec = (sec - 1);if (sec = 0)sec = 60;write_clock(0x82, sec); / 将校正写回到寄存器 /break;case 0x04: / 第七八个数码管闪烁只用于设置日期 if (show_status = 3) / 当前状态为日期设置 day = read_clock(0x87); / 读日day = day - 1; / 天加一if (day = 0)day = 31;write_clock(0x86, day); / 将校正写回到寄存器 /return;if (keytmp = 8) /
34、第四个按钮,仅当数码管打开时有效 /switch (attr)case 0xff:if (show_status = 1) / 如果当前显示日期show_status = 3; / 切换到调准日期状态 else if (show_status = 2) / 如果当前显示时间 /show_status = 4; / 切换到调准时间状态 attr = 0x01;break; / 第一、二个数码管闪烁case 0x01:attr = 0x02;break; / 第三、四个数码管闪烁case 0x02:attr = 0x03;break; / 第五、六个数码管闪烁case 0x03:attr = 0x
35、04;break; / 第七八个数码管闪烁case 0x04:if (show_status = 0)if (attr = 0x03)cur_alarm_set += 1; / 转到下一路闹钟进行设置 /if (cur_alarm_set = 18)cur_alarm_set = 0;attr = 0x01; / 第一、二个数码管闪烁/*闹钟被触发相应操作子程序*/voidalarm_act()char temp;hour = read_clock(0x85); / 读时min = read_clock(0x83); / 读分for (temp = 0; temp = 18; temp+) /
36、 首先判断十八路路闹钟是否有被/ 触发的if (alarmtemp.h_b = hour & alarmtemp.m_b = min) / 比较是否有闹钟被触发/sound = 1;if (temp = 0 | temp = 1 | temp = 2)out_alarm1 = 0; / 启动第一路闹钟if (temp = 3 | temp = 4 | temp = 5)out_alarm2 = 0; / 启动第二路闹钟if (temp = 6 | temp = 7 | temp = 8)out_alarm3 = 0;if (temp = 9 | temp = 10 | temp = 11)out_alarm4 = 0;if (temp = 12 | temp = 13 | temp = 14)out_alarm5 = 0;if (temp = 15 | temp = 16 | temp
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024至2030年中国钢塑料复合管数据监测研究报告
- 2024至2030年中国电容式电子吊秤数据监测研究报告
- 2024至2030年中国水晶工艺品摆件行业投资前景及策略咨询研究报告
- 东海航空协议维修外站B737-8飞机放行人员考试复习试题含答案
- 江苏省扬州市江都区2024-2025学年高二上学期期中考试历史试题 含解析
- 零售店铺销售提升策略
- 印刷厂安全工作标准
- 品牌挂靠管理指南
- 5G通信合同审计教案
- 核桃苗木采购合同模板
- 2024年国网公司企业文化与职业道德试考试题库(含答案)
- 2024年度亚马逊FBA货物海运合同
- 2024年家庭教育新趋势:安全教育家长会
- 建筑装饰的室内装修工艺与施工技术考核试卷
- 网络攻击应急预案演练总结报告
- 交通运输行业火灾安全预案
- 厂中厂承租方对出租方日常安全检查记录表
- 2024-2025学年高三上学期期中家长会 课件
- 第十二届广东省安全知识竞赛暨粤港澳安全知识竞赛决赛备赛试题库(含答案)
- 完整2024年国有企业管理人员处分条例专题课件
- 安全生产治本攻坚三年行动实施方案(2024-2026年) - 副本
评论
0/150
提交评论