#include #define uchar unsigned char #define uint unsigned int sbit buzzer = P1^0; sbit led_green = P1^1; //green sbit led_yellow = P1^2; //yellow sbit led_red = P1^3; ///red sbit led6 = P1^6; sbit led7 = P1^7; //程序运行指示灯 sbit key1 = P3^2; //值班人按下的复位键 sbit key2 = P3^3; //时钟设置键:按下一下,分+1 sbit key3 = P3^4; //时钟设置键:按下一次,时+1 sbit key4 = P3^5; //时钟复位键 sbit MOSIO=P2^2; //74HC5956移位寄存器的数据线端 sbit R_CLKa=P2^3; //输出存储器锁存时钟线 sbit S_CLKa=P2^4; //数据输入时钟线 //***lcd部分**** sbit WR_lcd = P2^5; //lcd写允许管脚 sbit RS_lcd = P2^6; //lcd寄存器选择管脚 sbit EN_lcd = P2^7; //lcd使能端 void init_lcd(void); //lcd初始化函数 void write_com(unsigned char); //lcd写指令函数 void write_data(unsigned char); //lcd写数据函数 void lcdshow(void); char ctable[]={"record:"}; uchar counter = 0; //定时器步进 uchar hour = 0,minute = 0,second ,m; uchar r_hour[10],r_min[10],r_sec[10],record; //用于保存记录值 unsigned char r=0; //记录按键次数 uchar clearFlag; //标志是否已按下复位键 uchar keyRC; //矩阵键盘按下的按键 unsigned int i=0; uchar timer0h,timer0l,time; unsigned int tiptime =0; //提示时间 void init(void); void delay500(void); void delay1ms(unsigned int ); void showtime(void); //数码管显示时间 void sdata(void); //数据到寄存器 void out(void); //数码管输出 void bcon(void); //矩阵键盘 //数码管显示表 unsigned char code fseg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; unsigned char code segbit[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; unsigned char disbuf[8]={0,0,0,0,0,0,0,0}; void main(void) { uchar j; delay1ms(2); //等待硬件完成启动 init(); init_lcd(); //初始化lcd while(1) {showtime(); if(tiptime%20 == 0&&tiptime!=0) //每20s提示响铃,绿灯亮D2 { led_green = 0; for(i=0;i<20;i++) { buzzer = ~buzzer;delay1ms(1); } clearFlag = 1; //置响铃标志 } if(clearFlag ==1) { if(tiptime%21 == 0) //每21s后响鸣,黄灯闪烁D3 { for(i=0;i<20;i++) { for(j=0;j<50;j++) { buzzer = ~buzzer;delay500(); } led_yellow =~led_yellow; delay1ms(50);} led_yellow = 0; } else if(tiptime%60 == 0) //60s后急促警鸣,红灯闪烁D4 { r_hour[record] = hour; r_min[record] = minute; r_sec[record] = second; for(i=0;i<20;i++) { for(j=0;j<20;j++) { buzzer = ~buzzer; delay500(); } led_red = ~led_red; delay1ms(50); } led_red = 0; record ++; if(record==10) { record =0;} } } led7 = ~led7; //程序运行指示灯D8 } } void init(void) { TMOD = 0x10; //定时器T1工作方式1 TH1 = 0xd8; TL1 = 0xf0; //初值10ms ET1 = 1; EA = 1; //系统中断 TR1 = 1; //启动定时器 } //数码管显示时间 void showtime() { bcon(); sdata(); out(); } /*** 函数功能:键盘控制*/ void bcon(void) {uchar row =0,column =0,temp,tempR,tempC =0; tempR = 0x10; delay500(); P3 = 0x0f; //行为高电平,列为低电平 temp = P3; temp = temp & 0x0f; if(temp != 0x0f) //有按键按下 {delay500(); //延时约1ms P3 = 0x0f; temp = P3; temp = temp & 0x0f; tempR =temp; P3 = 0xf7; //第四行,1111 0111 temp = P3; temp = temp & 0xf0; if(temp != 0xf0) //有按键按下 { delay1ms(1); P3 = 0xf7; temp = P3; temp = temp & 0xf0; //获得temp的高四位 if(temp != 0xf0) { keyRC =temp | 0x07; } //加上低四位,表示出来按键 }else {P3 = 0xfb; //第三行 temp = P3; temp = temp & 0xf0; if(temp != 0xf0) //有按键按下 { delay1ms(1); P3 = 0xfb; temp = P3; temp = temp & 0xf0; if(temp != 0xf0) { keyRC =temp | 0x0b; } } else {P3 = 0xfd; //第二行 temp = P3; temp = temp & 0xf0; if(temp != 0xf0) //有按键按下 { delay1ms(1); P3 = 0xfd; temp = P3; temp = temp & 0xf0; if(temp != 0xf0) { keyRC =temp | 0x0d; } } else{P3 = 0xfe; //第一行 temp = P3; temp = temp & 0xf0; if(temp != 0xf0) //有按键按下 { delay1ms(1); P3 = 0xfe; temp = P3; temp = temp & 0xf0; if(temp != 0xf0) {keyRC =temp | 0x0e;} } } } } } //按下键后的操作 if(keyRC == 0xed) //值班人按下复位键,键5,1110 1101 { keyRC =0; //按键清零 tiptime = 0; //计时复位 clearFlag = 0; //清楚响铃标志 led_green = 1; led_red = 1; led_yellow = 1; while((P3 & 0xf0) != 0xf0);//按键按着不放 } else if(keyRC == 0xdd) //键6 { keyRC =0; //按键清零 minute ++; //分累加1 if(minute==60) { minute=0; } while((P3 & 0xf0) != 0xf0);//按键按着不放 } else if(keyRC == 0xbd) //键7 {keyRC =0; //按键清零 hour ++; //时累加1 if(hour == 24) { hour=0; } while((P3 & 0xf0) != 0xf0); } else if(keyRC == 0x7d) //数码管时钟清零,键8 {keyRC =0; //按键清零 second = 0; //清零 minute = 0; hour =0 ; while((P3 & 0xf0) != 0xf0); } else if(keyRC == 0xeb) //键9,查看记录 { keyRC =0; //按键清零 lcdshow(); while((P3 & 0xf0) != 0xf0); } disbuf[0]=second%10; disbuf[1]=second/10; disbuf[3]=minute%10; disbuf[4]=minute/10; disbuf[6]=hour%10; disbuf[7]=hour/10; } /**** 函数名称 : sdata(void) 函数功能 : 数据传输*/ void sdata(void) { unsigned char b,c,num; if(b==0) //传位码 { b++; num=segbit[m]; //位数码管的选择 for(c=0;c<8;c++) {S_CLKa=0; //移位控制器控制引脚置为低 MOSIO=num&0x80; //取数据最高位 num<<=1; //将数据次高位移到最高位 S_CLKa=1; } //移位时钟上升沿,数据寄存器数据移位 } if(b==1) //传段码 { b--; if(m==2||m==5) {num=0xbf;} //2和5显示'-' else {num=fseg[disbuf[m]];} //数码管显示的值 for(c=0;c<8;c++) { S_CLKa=0; MOSIO=num&0x80; num<<=1; S_CLKa=1; } } m++; if(m==8) {m=0;} } /********函数名称 : out(void) 函数功能 : 数据输出********/ void out(void) { R_CLKa=0; //输出存储器锁存时钟线 delay1ms(1); R_CLKa=1; } //定时器1定时10ms,晶振11.0592MHz void timer1(void) interrupt 3 { EA = 0; TR1 = 0; TH1 = 0xD8; TL1 = 0xF0; counter ++; if(counter == 100) //1秒钟 { counter = 0; second ++; tiptime ++; } else if(second == 60) //1分钟 { second = 0; minute ++; } else if(minute == 60) //1小时 { minute = 0; hour ++; } else if(hour == 24) { hour = 0;} TR1 = 1; EA = 1; } void lcdshow() //lcd显示 { unsigned char k =0; for(k=0;k<7;k++) {write_com(0x80+k); //AC第一行 write_data(ctable[k]); //字符表 } if(r < record) {k=0; write_com(0x80+0x40+k); //AC第二行 write_data(r+1+0x30); k++;//编号并转为ASCII码值 write_com(0x80+0x40+k); write_data(':'); k++; write_com(0x80+0x40+k); write_data(r_hour[r]/10 + 0x30); k++;//显示时 write_com(0x80+0x40+k); write_data(r_hour[r]%10 + 0x30); k++; write_com(0x80+0x40+k); write_data(':'); k++; write_com(0x80+0x40+k); write_data(r_min[r]/10 + 0x30); k++; //显示分 write_com(0x80+0x40+k); write_data(r_min[r]%10 + 0x30); k++; write_com(0x80+0x40+k); write_data(':'); k++; write_com(0x80+0x40+k); write_data(r_sec[r]/10 + 0x30);k++; //显示秒 write_com(0x80+0x40+k); write_data(r_sec[r]%10 + 0x30); r++; if(r == record){ r =0; } } } void init_lcd(void) //lcd初始化函数 { WR_lcd = 0; //本程序只写数据或命令 write_com(0x06); //输入方式,AC++、画面不移动 write_com(0x0c); //显示设置,显示开、光标关、不闪烁 write_com(0x38); //功能设置,8位、2行、5*7 } void write_com(unsigned char com) //lcd写命令函数 { RS_lcd = 0; //写命令寄存器 P0 = com; delay500(); EN_lcd = 1; delay500(); EN_lcd = 0; } void write_data(unsigned char lcd_data ) //lcd写数据函数 { RS_lcd = 1; P0 = lcd_data; delay500(); EN_lcd =1; delay500(); EN_lcd =0; delay500(); } void delay500(void) /***** 500us延时函数 晶振:11.0592MHz*****/ { uchar i; for(i=230;i>0;i--); } void delay1ms (unsigned int z) { unsigned int x,y; for(y=0;y