#pragma small #include #include #include // 包含了_nop_() //************************************************************************* //以下为常量定义 //************************************************************************* //键值列表 #define Key1 0xE7 #define Key2 0xEB #define Key3 0xED #define Key4 0xEE #define Key5 0xD7 #define Key6 0xDB #define Key7 0xDD #define Key8 0xDE #define Key9 0xB7 #define Key10 0xBB #define Key11 0xBD #define Key12 0xBE #define Key13 0x77 #define Key14 0x7B #define Key15 0x7D #define Key16 0x7E //************************************************************************* //以下为函数声明 //************************************************************************* void key_scan(void); void clock24(void); void clock12(void); void disp_h(void); void disp_m(void); //************************************************************************* //以下为变量等定义 //************************************************************************* //代码(MOVC结构) code unsigned char led_seg[] ={ //LED 显示段码 0xc0,0xf9,0xa4,0xb0,0x99, 0x92,0x82,0xf8,0x80,0x90, 0x40,0x79,0x24,0x30,0x19, 0x12,0x02,0x78,0x00,0x10, 0x88,0x8c}; //A&P code unsigned char led_seg_fan[]={ //LED 显示段码_反 0xc0,0xf9,0x64,0x70,0x59, 0x52,0x42,0xf8,0x40,0x50, 0x80,0xb9,0x24,0x30,0x19, 0x12,0x02,0xb8,0x00,0x10}; code unsigned char led_loc[] ={ //LED 显示位码 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; unsigned char alARM_m[16]={ // 闹钟时间点 99,99,99,99,99,99,99,99, 99,99,99,99,99,99,99,99}; unsigned char alarm_h[16]={ 99,99,99,99,99,99,99,99, 99,99,99,99,99,99,99,99}; //------------------------------------------------------------------------ //变量定义 unsigned char disp_buf[8]; // 显示缓存第0位为最低位 unsigned char disp_cnt; // 显示刷新位置计数,0~8 unsigned char cnt_2500us,cnt_100ms,cnt_500ms; unsigned int cnt_1s,cnt_800ms;cnt_5s; // 定时器计数单元 unsigned char s_buf; // 秒寄存器 unsigned char m_buf; // 分寄存器 unsigned char h_buf; // 小时寄存器 unsigned char m_tmp; // 分暂存器 unsigned char h_tmp; // 小时暂存器 unsigned char key_buf; // 键值缓存 unsigned char status; // 状态字 unsigned char status_buf; //------------------------------------------------------------------------ //位操作标志定义 bdata unsigned char flag1; // 为标志集合1 ***it flag_2500us = flag1^0; //2500us 定时器标志 ***it flag_100ms = flag1^1; //100ms 定时器标志(键延迟) ***it flag_500ms = flag1^2; //500ms 定时器标志 ***it flag_1s = flag1^3; //1s 定时器标志 ***it key_press = flag1^4; // 键已被按下标志 ***it key_acpt = flag1^5; // 键值已接受标志 ***it a = flag1^6; // 交替标志 ***it flag_800ms = flag1^7; ***it P3_7 = P3^7; bdata unsigned char flag2; ***it b = flag2^0; ***it flag_5s = flag2^1; //************************************************************************* //以下为子程序模块 //************************************************************************* void time_0(void) interrupt 1 //T0 中断(定时中断) { if(++cnt_2500us>8) //2.5ms 基础定时器 { cnt_2500us=0; P0 =0x00; P2 =disp_buf[disp_cnt&0x07]; P0 =led_loc[disp_cnt&0x07]; disp_cnt++; //------------------------------------------------------------------------ if(!flag_100ms) //100ms 定时器 { if(++cnt_100ms>39) { cnt_100ms=0; flag_100ms=1; } } //------------------------------------------------------------------------ if(!flag_500ms) //500ms 定时器 { if(++cnt_500ms>199) { cnt_500ms=0; flag_500ms=1; } } //----------------------------------------------------------------------- if(!flag_800ms) //500ms 定时器 { if(++cnt_800ms>319) { cnt_800ms=0; flag_800ms=1; } } //----------------------------------------------------------------------- if(!flag_5s) { if(++cnt_5s>1999) { cnt_5s=0; flag_5s=1; } } //----------------------------------------------------------------------- if(!flag_1s) //1s 定时器 { if(++cnt_1s>399) { cnt_1s=0; flag_1s=1; } } } //2.5ms 基础定时器结束 } //************************************************************************* //键扫描子程序 void key_scan(void) { P1 =0x0f; // 读键 if((P1|0xf0)==0xff) // 是否有键按下 { // 无键按下 key_press=0; // 清键已被按下标志 key_acpt=0; // 清键值已接受标志 } else { // 有键按下 if(!key_press) // 是否已置键已被按下标志 { key_press=1; // 置键已被按下标志 flag_100ms=0; // 置100ms键延迟标志 } else { if(flag_100ms) //100ms 键延迟是否到 { if(!key_acpt) // 键值是否被接受 { key_buf =P1&0x0f; // 读低4位 P1 =0xf0; // 读高4位 key_buf=(P1&0xf0)|key_buf; // 接受键值 key_acpt=1; // 置键值已接受标志 } } } } } //************************************************************************* //时钟子程序 void clock24(void) { if(flag_1s) { flag_1s=0; if(s_buf<59) s_buf++; else { s_buf=0; if(m_buf<59) { m_buf++; } else { m_buf=0; if(h_buf<23) h_buf++; else h_buf=0; } } } if(flag_500ms) { flag_500ms=0; if(a==0) { disp_buf[1]=led_seg[h_buf%10+10]; disp_buf[2]=led_seg_fan[m_buf/10+10]; a=1; } else { disp_buf[1]=led_seg[h_buf%10]; disp_buf[2]=led_seg_fan[m_buf/10]; a=0; } } if(h_buf/10) disp_buf[0]=led_seg[h_buf/10]; else disp_buf[0]=0xff; disp_buf[3]=led_seg[m_buf%10]; disp_buf[4]=led_seg[s_buf/10]; disp_buf[5]=led_seg[s_buf%10]; disp_buf[6]=0xff; } void clock12(void) { if(flag_1s) { flag_1s=0; if(s_buf<59) s_buf++; else { s_buf=0; if(m_buf<59) { m_buf++; } else { m_buf=0; if(h_buf<23) h_buf++; else h_buf=0; } } } if(flag_500ms) { flag_500ms=0; if(a==0) { if(h_buf%12==0) disp_buf[1]=led_seg[12]; else disp_buf[1]=led_seg[h_buf%12%10+10]; disp_buf[2]=led_seg_fan[m_buf/10+10]; a=1; } else { if(h_buf%12==0) disp_buf[1]=led_seg[2]; else disp_buf[1]=led_seg[h_buf%12%10]; disp_buf[2]=led_seg_fan[m_buf/10]; a=0; } } if(h_buf%12/10==1||h_buf%12==0) disp_buf[0]=led_seg[1]; else disp_buf[0]=0xff; disp_buf[3]=led_seg[m_buf%10]; disp_buf[4]=led_seg[s_buf/10]; disp_buf[5]=led_seg[s_buf%10]; if(h_buf>11) disp_buf[6]=led_seg[21]; else disp_buf[6]=led_seg[20]; } //************************************************************************* //小时,分钟显示 void disp_h(void) { if(status_buf==0) { if(h_buf/10) disp_buf[0]=led_seg[h_buf/10]; else disp_buf[0]=0xff; disp_buf[1]=led_seg[h_buf%10]; } else if(status_buf==1) { if(h_buf%12/10==1||h_buf%12==0) disp_buf[0]=led_seg[1]; else disp_buf[0]=0xff; if(h_buf%12==0) disp_buf[1]=led_seg[2]; else disp_buf[1]=led_seg[h_buf%12%10]; if(h_buf>11) disp_buf[6]=led_seg[21]; else disp_buf[6]=led_seg[20]; } } void disp_m(void) { disp_buf[2]=led_seg_fan[m_buf/10]; disp_buf[3]=led_seg[m_buf%10]; } //************************************************************************* //以下为主程序 //************************************************************************* void main(void) { unsigned char i; unsigned char j; //------------------------------------------------------------------------- //程序初始化 PCON=0x00; IE=0x00; // 禁止全部中断 IP=0x00; // 默认优先级 TH1=0xFD; // 主频11.0592MHz,波特率=9600 TL1=0xFD; TH0=0x00; // 主频11.0592MHz,定时器0每秒3600次中断 TL0=0x00; // SCON=0x50; //UART :9600/N/8/1 TMOD=0x22; // 设定时器0为8位自动重装载 TCON=0x50; // 启动定时器,INT0、INT1电平触发 EA=1; // 中断总允许控制位 // EX0=1; // 允许外部中断0 ET0=1; // 允许T0中断 // EX1=1; // 允许外部中断1 // ET1=1; // 允许T1中断 // ES=1; // 允许UART中断 // EX2=1; // 允许外部中断2 // TI=0; // RI=0; flag1=0x00; // 位标志集合1 flag2=0x00; key_buf=0; // 键值缓存 s_buf=0; m_buf=0; h_buf=0; status =0; // 起始状态字 a=0; P3_7=0; // disp_buf[0] =led_seg[status]; for(i=1;i<8;i++) // 开机显示缓存初始化 { disp_buf =0xff; } for(i=0;i<0xe8;i++) // 开机延迟 { for(j=0;j<0xff;j++) ; } i=0; j=0; //------------------------------------------------------------------- //主程序开始 while(1) { key_scan(); // 状态机处理: switch(status) // 状态处理 { case 0: //0 状态,24小时制时钟 { clock24(); b=1; if(h_buf==alarm_h[j]&&m_buf==alarm_m[j]) { status_buf=0; status=10; flag_5s=0; } else if(j==15) j=0; else j++; switch(key_buf) { case Key16: status=1; break; case Key3: { status_buf=0; status=2; } break; case Key5: { status_buf=0; status=8; h_tmp=h_buf; m_tmp=m_buf; } break; } key_buf |=0xff; // 清键值 } break; case 1: //1 状态,12小时制时钟 { clock12(); b=1; if(h_buf==alarm_h[j]&&m_buf==alarm_m[j]) { status_buf=1; status=10; flag_5s=0; } else if(j==15) j=0; else j++; switch(key_buf) { case Key16: status=0; break; case Key3: { status_buf=1; status=2; } break; case Key5: { status_buf=1; status=8; h_tmp=h_buf; m_tmp=m_buf; } break; } key_buf |=0xff; // 清键值 } break; case 2: //2 状态,调小时 { switch(key_buf) // 调整 { case Key1: { if(flag_800ms) status=4; else { if(h_buf<23) h_buf++; else h_buf=0; } } break; case Key2: { if(flag_800ms) status=5; else { if(h_buf>0) h_buf--; else h_buf=23; } } break; case Key3: status=3; break; case Key6: status=3; break; } if(flag_500ms) // 闪烁 { flag_500ms=0; if(a==0) { disp_buf[0]=0xff; disp_buf[1]=0xff; a=1; } else { disp_h(); a=0; } } key_buf |=0xff; // 清键值 } break; case 3: //3 状态,调分 { switch(key_buf) { case Key1: { if(flag_800ms) status=6; else { if(m_buf<59) m_buf++; else m_buf=0; } } break; case Key2: { if(flag_800ms) status=7; else { if(m_buf>0) m_buf--; else m_buf=59; } } break; case Key3: { status=status_buf; } break; case Key6: status=9; break; } if(flag_500ms) // 闪烁 { flag_500ms=0; if(a==0) { disp_buf[2]=0xff; disp_buf[3]=0xff; a=1; } else { disp_m(); a=0; } } key_buf |=0xff; // 清键值 } break; case 4: //4 状态,小时快加 { if(flag_100ms) { flag_100ms=0; if(h_buf<23) h_buf++; else h_buf=0; disp_h(); } if(!key_press) status=2; key_buf |=0xff; // 清键值 } break; case 5: //5 状态,小时快减 { if(flag_100ms) { flag_100ms=0; if(h_buf>0) h_buf--; else h_buf=23; disp_h(); } if(!key_press) status=2; key_buf|=0xff; } break; case 6: //6 状态,分快加 { if(flag_100ms) { flag_100ms=0; if(m_buf<59) m_buf++; else m_buf=0; disp_m(); } if(!key_press) status=3; key_buf|=0xff; } break; case 7: //7 状态,分快减 { if(flag_100ms) { flag_100ms=0; if(m_buf>0) m_buf--; else m_buf=59; disp_m(); } if(!key_press) status=3; key_buf|=0xff; } break; case 8: //8 状态,查询删除 { h_buf=alarm_h; m_buf=alarm_m; disp_h(); disp_m(); switch(key_buf) { case Key5: { if(i<15) i++; else i=0; status=8; } break; case Key6: status=2; break; case Key7: alarm_h=alarm_m=99; break; case Key8: { h_buf=h_tmp; m_buf=m_tmp; status=status_buf; } break; } key_buf|=0xff; } break; case 9: //9 状态,设置 { alarm_h=h_buf; alarm_m=m_buf; h_buf=h_tmp; m_buf=m_tmp; status=status_buf; key_buf|=0xff; } break; case 10: //10 状态,闹钟时间到 { if(flag_1s) { flag_1s=0; if(s_buf<59) s_buf++; else { s_buf=0; if(m_buf<59) { m_buf++; } else { m_buf=0; if(h_buf<23) h_buf++; else h_buf=0; } } } if(flag_500ms) // 闪烁 { flag_500ms=0; if(b==0) { disp_buf[0]=0xff; disp_buf[1]=0xff; disp_buf[2]=0xff; disp_buf[3]=0xff; b=1; } else { disp_h(); disp_m(); b=0; } } if(flag_5s) { status=status_buf; alarm_h[j]=99; alarm_m[j]=99; } P3_7=~b; key_buf|=0xff; } break; } } } //************************************************************************* 这是我们编的C语言程序,下面是项目要求:
题目一 多功能数字钟设计要求:利用 单片机的定时器等设计一款多功能时钟。要求:(1) 至少包含 2位小时、2位分钟和一个秒闪(2) 通过键盘来设定起始时间(3) 具有 12小时和24小时2种计时方式(4) 其它扩展功能(与时钟有关)
但是我们的材料是52单片机的,这段程序是51的,就是位选的程序不一样,是mini80E急需大神帮我们改改!!
0
|
|
|
|
|
|