在仿真上可以顯示并可調,但是在單片機板子上不能實現,用的是不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;
- }
復制代碼
|