三、功能描述
3.1 基本功能描述
1)通过读取DS1302 RTC芯片,获取时间数据;
2)通过EEPROM实现数据记录功能;
3)通过LED指示灯完成试题要求的状态指示功能;
4)通过数码管、按键完成试题要求的数据显示和界面切换功能。
3.2 显示功能
1)时间界面
时间界面如图2所示,显示内容包括时、分、秒数据和间隔符“-” 时、分、秒数据固定占 2 位显示宽度,不足 2 位补 0。
图2 时间界面
2)输入界面
输入界面如图3所示,由标识符(C)和一个4位数据组成,4位数据通过4位数码管显示,每输入一位数据,数码管显示向左移动一位,直到完成4位数据的输入。
图3 输入界面
每次重新进入输入界面时,默认显示4位数据的4位数码管处于熄灭状态。
3)记录界面
记录界面如图4所示,由标识符(E)和输入4位数据的起始时和分数据以及时、分数据的间隔符(-)。
图4 记录界面
4)显示要求
按照题目要求的界面格式和切换方式进行设计。
数码管显示无重影、闪烁、过暗、亮度不均匀等严重影响显示效果的缺陷。
3.3 按键功能
1)功能说明
① S4:定义为“切换”,按下S4按键,切换“时间界面”、“输入界面”和“记录界面”。
图5 界面切换顺序
② S5:定义为“清除”,在输入界面下,按下S5,清除当前输入的数据,显示输入数据的4位数码管全部熄灭。
③ S6、S10、S14、S18、S9、S13、S17、S8、S12、S16分别对应数值“0-9”,在“输入界面”下,按下对应按键,实现一位对应数据的输入,显示格式及要求如图3所。若当前4位数据输入完成,按键继续输入不影响当前已输入完成的4位数据。
2)按键要求
按键应做好消抖处理,避免出现一次按键动作导致功能多次触发。
按键动作不影响数码管显示等其他功能。
按键 S5、S6、S10、S14、S18、S9、S13、S17、S8、S12、S16仅在“输入界面”有效。
3.4 记录功能
每次进入记录界面时,将4位数据和输入数据的起始时间保存到E2PROM,存储位置要求如下:
输入数据起始时间(时):E2PROM内部地址0;
输入数据起始时间(分):E2PROM内部地址1;
输入数据(高字节):E2PROM内部地址2;
输入数据(低字节):E2PROM内部地址3;
注意:
E2PROM写入操作发生在切换到记录界面时,其它时间不写入。
输入数据以HEX编码写入E2PROM,例如数据数据为1234,E2PROM内部地址2中应保存04H, 内部地址3中保存D2H。
3.5 LED指示灯功能
1、界面指示灯
1)时间界面下,指示灯 L1 点亮,否则指示灯 L1 熄灭。
2)输入界面下,指示灯 L2 点亮,否则指示灯 L2 熄灭。
3)记录界面下,指示灯 L3 点亮,否则指示灯 L3 熄灭。
2、记录指示灯
若本次记录的4位数据较上一次记录的4位数据大,则指示灯L4点亮,否则指示灯熄灭。
3.6 初始状态
请严格按照以下要求设计作品的上电初始状态。
1)处于时间界面
2)指示灯L1点亮,其余指示灯熄灭。
代码如下,功能运行正常,通过4T测评
#include#include "ds1302.h" #include "iic.h" #include "intrins.h" sbit h1 = P3^1; sbit h2 = P3^2; sbit h3 = P3^3; sbit s1 = P4^4; sbit s2 = P4^2; sbit s3 = P3^5; sbit s4 = P3^4; unsigned char stat_my4 = 0;//防止stat_4一直为四,影响Led4 unsigned char stat_4 = 0;//四位数据输入完成标志 unsigned char stat_data = 0;//得到第一个旧数据标志 unsigned int old_value = 0;//旧的数据 unsigned char stat_led = 0xff; unsigned int num_value = 0;//四位数值大小 unsigned char jilu_h = 0; unsigned char jilu_m = 0; unsigned char count_4 = 0; unsigned char value_4[4] = {0};//键盘获取的四位数值分别存入数组中 unsigned char UI = 0;//0-时间界面 1-输入界面 2—记录界面 unsigned char t_h = 0; unsigned char t_m = 0; unsigned char t_s = 0; unsigned char stat_jilu = 0; unsigned char code SMG_NoDot[18]={0xc0,0xf9, 0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f}; unsigned char code read_addre[7] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; unsigned char code write_addre[7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; unsigned char Intimer[7] = {0x59,0x09,0x23,0x03,0x03,0x07,0x24}; void Delay5ms() //@12.000MHz { unsigned char i, j; i = 59; j = 90; do { while (--j); } while (--i); } void Delay20ms() //@12.000MHz { unsigned char i, j, k; _nop_(); _nop_(); i = 1; j = 234; k = 113; do { do { while (--k); } while (--j); } while (--i); } void Init_mytimer() { unsigned char i = 0; Write_Ds1302_Byte(0x8e,0x00); for(i = 0;i < 7;i++) { Write_Ds1302_Byte(write_addre[i],Intimer[i]); } Write_Ds1302_Byte(0x8e,0x80); } void read_mytimer() { t_h = Read_Ds1302_Byte(0x85); t_m = Read_Ds1302_Byte(0x83); t_s = Read_Ds1302_Byte(0x81); } unsigned char read_eeprom(unsigned char addre) { unsigned char epr_value = 0; I2CStart(); I2CSendByte(0xa0); I2CWaitAck(); I2CSendByte(addre); I2CWaitAck(); // I2CStop(); I2CStart(); I2CSendByte(0xa1); I2CWaitAck(); epr_value = I2CReceiveByte(); I2CSendAck(1); I2CStop(); return epr_value; } void write_eeprom(unsigned char addre,unsigned char w_value) { I2CStart(); I2CSendByte(0xa0); I2CWaitAck(); I2CSendByte(addre); I2CWaitAck(); I2CSendByte(w_value); I2CWaitAck(); I2CStop(); } void SelectHC573(unsigned char channel,unsigned char dat) { P2 = (P2 & 0x1f) | 0x00; P0 = dat; switch(channel) { case 4: P2 = (P2 & 0x1f) | 0x80; break; case 5: P2 = (P2 & 0x1f) | 0xa0; break; case 6: P2 = (P2 & 0x1f) | 0xc0; break; case 7: P2 = (P2 & 0x1f) | 0xe0; break; case 0: P2 = (P2 & 0x1f) | 0x00; break; } P2 = (P2 & 0x1f) | 0x00; } void DelaySMG(unsigned int t) { while(t--); } void DisplaySMG_Bit(unsigned char pos,unsigned char value) { SelectHC573(6,0x01 << pos); SelectHC573(7,value); DelaySMG(500); SelectHC573(6,0x01 << pos); SelectHC573(7,0xff); } void DisplaySMG_All(unsigned char value) { SelectHC573(6,0xff); SelectHC573(7,value); } void DisplaySMG_Info() { switch(UI) { case 0: DisplaySMG_Bit(0,SMG_NoDot[t_h >> 4]); DisplaySMG_Bit(1,SMG_NoDot[t_h & 0x0f]); DisplaySMG_Bit(2,SMG_NoDot[16]); DisplaySMG_Bit(3,SMG_NoDot[t_m >> 4]); DisplaySMG_Bit(4,SMG_NoDot[t_m & 0x0f]); DisplaySMG_Bit(5,SMG_NoDot[16]); DisplaySMG_Bit(6,SMG_NoDot[(t_s >> 4) & 0x07]); DisplaySMG_Bit(7,SMG_NoDot[t_s & 0x0f]); break; case 1: DisplaySMG_Bit(0,0xc6); if(count_4 == 1) { DisplaySMG_Bit(7,SMG_NoDot[value_4[0]]); } else if(count_4 == 2) { DisplaySMG_Bit(6,SMG_NoDot[value_4[0]]); DisplaySMG_Bit(7,SMG_NoDot[value_4[1]]); } else if(count_4 == 3) { DisplaySMG_Bit(5,SMG_NoDot[value_4[0]]); DisplaySMG_Bit(6,SMG_NoDot[value_4[1]]); DisplaySMG_Bit(7,SMG_NoDot[value_4[2]]); } else if(count_4 == 4) { DisplaySMG_Bit(4,SMG_NoDot[value_4[0]]); DisplaySMG_Bit(5,SMG_NoDot[value_4[1]]); DisplaySMG_Bit(6,SMG_NoDot[value_4[2]]); DisplaySMG_Bit(7,SMG_NoDot[value_4[3]]); } break; case 2: DisplaySMG_Bit(0,0x86); DisplaySMG_Bit(3,SMG_NoDot[jilu_h >> 4]); DisplaySMG_Bit(4,SMG_NoDot[jilu_h & 0x0f]); DisplaySMG_Bit(5,SMG_NoDot[16]); DisplaySMG_Bit(6,SMG_NoDot[jilu_m >> 4]); DisplaySMG_Bit(7,SMG_NoDot[jilu_m & 0x0f]); break; } } void scan_key() { h1 = 0; h2 = h3 = s1 = s2 = s3 = s4 = 1; if(s1 == 0)//6->0 { Delay20ms(); if(s1 == 0) { if(count_4 < 4) { value_4[count_4] = 0; count_4++; } while(s1 == 0) { DisplaySMG_Info(); } } } else if(s2 == 0 && UI == 1)//10->1 { Delay20ms(); if(s2 == 0) { if(count_4 < 4) { value_4[count_4] = 1; count_4++; } while(s2 == 0) { DisplaySMG_Info(); } } } else if(s3 == 0 && UI == 1)//14->2 { Delay20ms(); if(s3 == 0) { if(count_4 < 4) { value_4[count_4] = 2; count_4++; } while(s3 == 0) { DisplaySMG_Info(); } } } else if(s4 == 0 && UI == 1)//18->3 { Delay20ms(); if(s4 == 0) { if(count_4 < 4) { value_4[count_4] = 3; count_4++; } while(s4 == 0) { DisplaySMG_Info(); } } } h2 = 0; h1 = h3 = s1 = s2 = s3 = s4 = 1; if(s1 == 0)//5 { Delay20ms(); if(s1 == 0) { if(UI == 1) { count_4 = 0; value_4[0] = value_4[1] = value_4[2] = value_4[3] = 0; stat_jilu = 0; stat_my4 = 0; } while(s1 == 0) { DisplaySMG_Info(); } } } else if(s2 == 0 && UI == 1)//9->4 { Delay20ms(); if(s2 == 0) { if(count_4 < 4) { value_4[count_4] = 4; count_4++; } while(s2 == 0) { DisplaySMG_Info(); } } } else if(s3 == 0 && UI == 1)//13->5 { Delay20ms(); if(s3 == 0) { if(count_4 < 4) { value_4[count_4] = 5; count_4++; } while(s3 == 0) { DisplaySMG_Info(); } } } else if(s4 == 0 && UI == 1)//17->6 { Delay20ms(); if(s4 == 0) { if(count_4 < 4) { value_4[count_4] = 6; count_4++; } while(s4 == 0) { DisplaySMG_Info(); } } } h3 = 0; h2 = h1 = s1 = s2 = s3 = s4 = 1; if(s1 == 0)//4 { Delay20ms(); if(s1 == 0) { if(UI == 0) { UI = 1; count_4 = 0; stat_jilu = 0; stat_my4 = 0; } else if(UI == 1) { UI = 2; write_eeprom(0x00,(jilu_h/16)*10 + jilu_h%16); Delay5ms(); write_eeprom(0x01,(jilu_m/16)*10 + jilu_m%16); Delay5ms(); write_eeprom(0x02,num_value >> 8); Delay5ms(); write_eeprom(0x03,num_value & 0x00ff); Delay5ms(); } else { UI = 0; } while(s1 == 0) { DisplaySMG_Info(); } } } else if(s2 == 0 && UI == 1)//8->7 { Delay20ms(); if(s2 == 0) { if(count_4 < 4) { value_4[count_4] = 7; count_4++; } while(s2 == 0) { DisplaySMG_Info(); } } } else if(s3 == 0 && UI == 1)//12->8 { Delay20ms(); if(s3 == 0) { if(count_4 < 4) { value_4[count_4] = 8; count_4++; } while(s3 == 0) { DisplaySMG_Info(); } } } else if(s4 == 0 && UI == 1)//16->9 { Delay20ms(); if(s4 == 0) { if(count_4 < 4) { value_4[count_4] = 9; count_4++; } while(s4 == 0) { DisplaySMG_Info(); } } } if(count_4 == 1) { if(stat_jilu == 0) { jilu_h = Read_Ds1302_Byte(0x85); jilu_m = Read_Ds1302_Byte(0x83); stat_jilu = 1; } } if(count_4 == 4) { num_value = (value_4[0] * 1000) + (value_4[1] * 100) + (value_4[2] * 10) + value_4[3]; if(stat_my4 == 0) { stat_4 = 1; stat_my4 = 1; } } } void led_control() { if(UI == 0) { stat_led = stat_led | 0x04; stat_led = stat_led & 0xfe; SelectHC573(4,stat_led); } else if(UI == 1) { stat_led = stat_led | 0x01; stat_led = stat_led & 0xfd; SelectHC573(4,stat_led); } else if(UI == 2) { stat_led = stat_led | 0x02; stat_led = stat_led & 0xfb; SelectHC573(4,stat_led); } if(stat_data == 0 && stat_4 == 1) { old_value = num_value; stat_data = 1; stat_4 = 0; } if(stat_4 == 1) { if(old_value < num_value) { stat_led = stat_led & 0xf7; SelectHC573(4,stat_led); } else { stat_led = stat_led | 0x08; SelectHC573(4,stat_led); } stat_4 = 0; old_value = num_value; } } void main() { Init_mytimer(); DisplaySMG_All(0xff); SelectHC573(4,0xff); SelectHC573(5,0x00); while(1) { scan_key(); read_mytimer(); DisplaySMG_Info(); led_control(); } }