在仿真上可以显示并可调,但是在单片机板子上不能实现,用的是不b104 的板子,用了按键调时间,闹钟这是程序
是不是在lcd1602上需要用ascii码值,但是我不知道该怎样改驱动里面的数据转换呀- #include<reg51.h>
- #include<lcd1602.c>
- #include<display.c>
- #include<ds1302.c>
- #include<key.c>
- void timer0_isr()interrupt 1
- {
- TL0= (65536-2000)%256;
- TH0= (65536-2000)/256;
- cp++;
-
- if(cp>=250) //半秒的时间
- {
- cp=0;
- cp1++;
- cp2++;
- P0= 0xff;
-
- }
-
- if(cp1>= 2)
- {
- cp1= 0;
- flash= ~flash;
- if(key_flag> 8 || key_flag <= 0)
- {
- display();
- }
- else
- display_key_scan();
- P0= 0xff;
- //FL1602_clear();
- }
- if(time[6]== hour && time[7] == min) //响闹钟的时间
- {
- buzzer= 0;
- if(cp3>= 5000) //十秒钟后自动关闭
- {
- cp3= 0;
- buzzer= 1;
- cp4++;
- }
- if(cp4>= 3) //30秒后自动开启
- {
- cp4= 0;
- buzzer= 0;
- }
- }
- elsebuzzer = 1;
- }
- void timer0_init()
- {
- TMOD= 0x01;
- TL0= (65536-2000)%256;
- TH0= (65536-2000)/256;
- EA= 1;
- ET0= 1;
- TR0= 1;
- }
- void main(void)
- {
- init_ds1302();
- FL1602_init();
- timer0_init();
- FL1602_clear();
- while(1)
- {
- buzzer= 0;
- key_scan();
- get_ds1302_time();
- }
- }
- ///////////////////////////////////////////////////////////////
- 这是ds1302
- #include<reg51.h>
- /*********************************************************************************/
- //ds1302驱动
- //2011年5月
- /*********************************************************************************/
- #define uchar unsigned char /*宏定义用uchar 代替unsignedchar*/
- #define uint unsigned int /*宏定义用uint 代替 unsignedint*/
- sbit ret = P3^7;
- sbit scl = P3^6;
- sbit sd = P3^4;
- //uchar sec, min, hour, date, month, year,week;
- void ds1302_init(void)
- {
- ret= 0;
- scl= 0;
- ret= 1;
- }
- /*********************************对DS1302写1字节函数*****************************/
- void write_ds1302_onebyte(uchar dat)
- {
- uchari;
- for(i= 0;i < 8;i++)
- {
- sd= dat & 0x01;
- scl= 0;
- scl= 1;
- dat= dat >> 1;
- }
- }
- /*********************************从DS1302读一字节函数*****************************/
- uchar read_ds1302_onebyte(void)
- {
- uchari,dat;
- for(i= 0;i < 8;i++)
- {
- scl= 1;
- dat= dat >> 1;
- scl= 0;
- if(sd)dat= dat | 0x80;
- }
- return(dat);
- }
- /*****************************对DS1302的某一地址写一字节函数***********************/
- void write_ds1302_add_dat(uchar add,uchardat)
- {
- ds1302_init();
- write_ds1302_onebyte(add);
- write_ds1302_onebyte(dat);
- scl= 1;
- ret= 0;
- }
- /*****************************从DS1302的某一地址读一字节函数***********************/
- uchar read_ds1302_add_dat(uchar add) /*读1302数据*/
- {
- uchardat_temp;
- ds1302_init();
- write_ds1302_onebyte(add);
- dat_temp= read_ds1302_onebyte();
- scl= 1;
- ret= 0;
- return(dat_temp);
- }
- /********************************8421BCD码到十进制转换*****************************/
- uchar BCD_DEC_conv(uchar x)
- {
- uchardec;
- dec= 0x0f & x;
- x= x >> 4;
- dec = dec + x * 10;
- return(dec);
- }
- /********************************十进制到8421BCD码转换*****************************/
- uchar DEC_BCD_conv(uchar x)
- {
- ucharbcd;
- bcd= x % 10;
- x= x / 10;
- x= x << 4;
- bcd = bcd | x ;
- return(bcd);
- }
- /*******************从ds1302中获得时间函数函数**********************/
- void get_ds1302_time(void) //获取1302的时间数据(时、分、秒),存入time1数组中
- {
- uchard;
- d= read_ds1302_add_dat(0x81); //读秒
- sec= BCD_DEC_conv(d); //得到秒
- d= read_ds1302_add_dat(0x83); //读分
- min= BCD_DEC_conv(d); //得到分
- d= read_ds1302_add_dat(0x85); //读小时
- hour= BCD_DEC_conv(d); //得到小时
- d= read_ds1302_add_dat(0x8b); //读周
- week= BCD_DEC_conv(d); //得到周
- d= read_ds1302_add_dat(0x87); //读日
- date= BCD_DEC_conv(d); //得到日
- d = read_ds1302_add_dat(0x89); //读月
- month= BCD_DEC_conv(d); //得到月
- d = read_ds1302_add_dat(0x8d); //读年
- year= BCD_DEC_conv(d); //得到年
- }
- /*******************DS1302初始化函数hanshu*********************/
- void init_ds1302(void)
- {
- write_ds1302_add_dat(0x8e,0x00); //写允许
- write_ds1302_add_dat(0x80,DEC_BCD_conv(19)); //写年
- write_ds1302_add_dat(0x84,DEC_BCD_conv(4)); //写月
- write_ds1302_add_dat(0x82,DEC_BCD_conv(23)); //写日
- write_ds1302_add_dat(0x80,DEC_BCD_conv(3)); //写星期
- write_ds1302_add_dat(0x84,DEC_BCD_conv(10)); //写时
- write_ds1302_add_dat(0x82,DEC_BCD_conv(12)); //写分
- write_ds1302_add_dat(0x80,DEC_BCD_conv(16)); //写秒
- write_ds1302_add_dat(0x8e, 0x80); //写保护
- }
- //////////////////////////////////////////////////////////
- 显示函数
- #include<reg51.h>
- //#include"key.c"
- uchari,year,month,date,hour,week,min,sec,flash,cp1,key_flag,cp,cp2,cp3,cp4;
- char time[9];
- sbit buzzer = P3^2;
- void display(void)
- {
- goto_row_column(1,4);//第一行
- // display_string("20");//显示2
- display_num(year);
- display_string("/");
- display_num(month);
- display_string("/");
- display_num(date);
- goto_row_column(2,4);
- display_num(hour);
- if(flash)display_string(":"); else display_string(" ");
- display_num(min);
- if(flash)display_string(":"); else display_string(" ");
- display_num(sec);
- // delay(50000);
- // // FL1602_clear();
- // goto_row_column(1,4);
- // display_string("20"); //显示2
- // display_num(year);
- // display_string("/"); //显示字母及符号的方式
- // display_num(month);
- // display_string("/");
- // display_num(date);
- // delay(50000);delay(50000);delay(50000);
- // goto_row_column(2,4);
- // display_num(hour);
- // if(flash== 1) display_string("");
- // else display_string(":");//冒号闪烁0x00if(flash== 0xff) 0x00 if(flash == 0xff )
- // display_num(min);
- // if(flash== 1 )display_string(" ");
- // elsedisplay_string(":");//冒号闪烁
- // display_num(sec);
- // delay(50000);delay(50000);delay(50000);//delay(50000);
- //
- // i++;
- // if(i> 100)i = 0;
- }
- void display_key_scan(void) //显示调整时的时间
- {
- if(key_flag > 6)
- {
- goto_row_column(1,0);
- display_string("****ding nao****");
- goto_row_column(2,4);
- if(key_flag == 7) //调整时的小时
- {
- if(flash)
- display_num(time[6]);
- else
- display_string(" ");
- }
- else
- display_num(time[6]);
- if(flash==0x00) //
- display_string(":");
- else
- display_string("");
- if(key_flag == 8) //
- {
- if(flash)
- display_num(time[7]);
- else
- display_string(" ");
- }
- else
- display_num(time[7]);
- display_string(" ");
-
- }
- else //调整显示状态下的时分秒
- {
- goto_row_column(1,4);//第一行
- if(key_flag== 1) //显示年的调整值并闪烁
- {
- if(flash)
- display_num(time[0]);
- else
- display_string(" ");
- }
- else
- display_num(time[0]);
- display_string("/");
- if(key_flag== 2) //显示月的调整值并闪烁
- {
- if(flash)
- display_num(time[1]);
- else
- display_string(" ");
- }
- else
- display_num(time[1]);
- display_string("/");
-
- if(key_flag== 3) //显示日的调整值并闪烁
- {
- if(flash)
- display_num(time[2]);
- else
- display_string(" ");
- }
- else
- display_num(time[2]);
- goto_row_column(2,4);
-
- if(key_flag== 4) //显示时的调整值并闪烁
- {
- if(flash)
- display_num(time[3]);
- else
- display_string(" ");
- }
- else
- display_num(time[3]);
-
- if(flash) //冒号的显示并闪烁 == 0x00
- display_string(":");
- else
- display_string("");
-
- if(key_flag== 5) //显示分的调整值并闪烁
- {
- if(flash)
- display_num(time[4]);
- else
- display_string(" ");
- }
- else
- display_num(time[4]);
-
- if(flash) //冒号的显示并闪烁==0x00
- display_string(":");
- else
- display_string("");
-
- if(key_flag== 6) //显示秒的调整值并闪烁
- {
- if(flash)
- display_num(time[5]);
- else
- display_string(" ");
- }
- else
- display_num(time[5]);
- }
- // FL1602_clear();
- }
- //////////////////////////////////////////
- Lcd1602
- #include<reg51.h> //这两个驱动均是正确的
- #define uchar unsigned char
- #define uint unsigned int
- uchar num[] = "0123456789";
- sbit RS = P1^7;
- sbit RW = P1^6;
- sbit E = P1^5;
- void delay(uint x)
- {
- while(x--);
- }
- void write_command(uchar command) /*写指令函数*/
- {
- RW= 0;
- RS= 0;
- P0= command;
- E= 1;
- delay(100);
- E= 0;
- RW= 1;
- }
- void write_dat(uchar dat) /*写数据函数*/
- {
- RW= 0;
- RS= 1;
- P0= dat;
- E= 1;
- delay(100);
- E= 0;
- RW= 1;
- }
- void display_string(char *p) /*字符串函数*/
- {
- while(*p)
- {
- write_dat(*p);
- p++;
- }
- }
- void display_num(uchar x) //向lcd1602写数字变量
- {
- write_dat(num[x/ 10]);
- write_dat(num[x% 10]);
- }
- void goto_row_column(uchar row, ucharcolumn) /*行列控制函数*/
- {
- if(row== 1)
- {
- write_command(0x80+ column);
- delay(100);
- }
- elseif(row == 2)
- write_command(0xc0 + column); // 0xC0
- }
- void FL1602_init(void) /*初始化函数*/
- {
- write_command(0x38); /*设置两行,每行16个字符,每个字符5*7点阵,8位数据接口*/
- write_command(0x0f);
- delay(100);
- write_command(0x0c); /*设置开显示*/
- write_command(0x06); /*设置当读或写一个字节后,地址指针加1,且光标加1*/
- }
- void FL1602_clear(void) /*清屏函数*/
- { /*设置清屏指令,单片机向1602的数据端口写入0x01后,1602自动将本身DDRAM的内容全部填入“空白”
- 的ASCII码20H,并将地址计数器AC的值设为0,同时光标归位,即将光标撤回液晶显示屏的左上方
- ,此时显示器无显示。*/
- write_command(0x01);
- write_command(0x02);
-
- }
- //////////////////////////////////////////////////////////////
- 按键部分
- #include<reg51.h>
- unsigned char seven_seg[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
- unsigned char key_flag,i,j,year,month,date,hour,min,sec; //用一变量记载13按键按下的次数
- code uchar key_scan_row[] ={0x7f,0xbf,0xdf,0xef};
- code uchar key_value[] = {
- 0xee,0xed,0xeb,0xe7,
- 0xde,0xdd,0xdb,0xd7,
- 0xbe,0xbd,0xbb,0xb7,
- 0x7e,0x7d,0x7b,0x77
- };
- char time[9] ;
- uchar key_mode; /*为了避免每次调整完一个数据后不再从ds1302中读取数据,即LCD1602上显示的数据位当前的调整值*/
- void key_scan(void) //让键盘行线输出扫描数据
- {
- P2= key_scan_row[ i];
- [ i]
- if(P2!= key_scan_row[ i]) //[ i]如果有按键按下,P2口不是原来的扫描数据;
- [ i]
- {
- delay(200);
- for(j= 0;j < 16;j ++)
- {
- if(j == 13) //切换键&& key_flag >= 1
- {
- if(P2== key_value[j] )
- {
- delay(200);
- key_flag++;
- if(key_flag> 8) key_flag = 0;
- key_mode++;
- if(key_mode== 1)
- {
- time[0]= year;
- time[1]= month;
- time[2]= date;
- time[3]= hour;
- time[4]= min;
- time[5]= sec;
- }
- }
- }
- if(j== 14)
- {
- if(P2== key_value[j] ) //加键
- {
- delay(200);
- if(key_flag == 1) time[0] ++;if(time[0] >=100) time[0] = 0; //年
- if(key_flag == 2) time[1] ++;if(time[1] >=13) time[1] = 1; //月
- if(key_flag == 3) time[2] ++;if(time[2] >=31) time[2] = 1; //日
- if(key_flag == 4) time[3] ++;if(time[3] >=24) time[3] = 0; //时
- if(key_flag == 5) time[4] ++;if(time[4] >=60) time[4] = 0; //分
- if(key_flag == 6) time[5] ++;if(time[5] >=60) time[5] = 0; //秒
- if(key_flag == 7) time[6] ++;if(time[5] >=24) time[6] = 0; // 定时
- if(key_flag == 8) time[7] ++;if(time[5] >=60) time[7] = 0; // 定分
- }
- }
- if(j== 15)
- {
- if(P2== key_value[j] ) //减键
- {
- delay(200);
- if(key_flag == 1) time[0] --;if(time[0] <0) time[0] = 99; //年
- if(key_flag == 2) time[1] --;if(time[1] <1) time[1] = 12; //月
- if(key_flag == 3) time[2] --;if(time[2] <1) time[2] = 31; //日
- if(key_flag == 4) time[3] --;if(time[3] <0) time[3] = 23; //时
- if(key_flag == 5) time[4] --;if(time[4] <0) time[4] = 59; //分
- if(key_flag == 6) time[5] --;if(time[5] <0) time[5] = 59; //秒
- if(key_flag == 7) time[6] --;if(time[5]<0) time[7] = 23; // 定时
- if(key_flag == 8) time[7] --;if(time[5]<0) time[8] = 59; // 定分
- }
- }
- if(j== 12) //退出键,退出模式
- {
- if(P2== key_value[j] )
- {
- delay(200);
- key_flag= 0;
- key_mode= 0;
- write_ds1302_add_dat(0x8e,0x00); //写允许
- write_ds1302_add_dat(0x8c,DEC_BCD_conv(time[0])); //写年
- write_ds1302_add_dat(0x88,DEC_BCD_conv(time[1])); //写月
- write_ds1302_add_dat(0x86,DEC_BCD_conv(time[2])); //写日
- // write_ds1302_add_dat(0x8a,DEC_BCD_conv(time[3])); //写周
- write_ds1302_add_dat(0x84,DEC_BCD_conv(time[3])); //写时
- write_ds1302_add_dat(0x82,DEC_BCD_conv(time[4])); //写分
- write_ds1302_add_dat(0x80,DEC_BCD_conv(time[5])); //写秒
- write_ds1302_add_dat(0x8e,0x80); //写保护
- }
- }
- if(j== 11) //直接调到定闹模式
- {
- if(P2== key_value[j] )
- {
- delay(200);
- key_flag = 7;
- if(key_flag > 8 )key_flag = 0;
- }
- }
- if(j== 10) //关闭闹钟按键
- {
- if(P2== key_value[j] )
- {
- delay(200);
- buzzer= 1;
- }
- }
- }
- while(P2!= key_scan_row[ i]);
- [ i]
- }
- i++;
- if(i>= 4)i = 0;
- }
复制代码
|