|
0.png (37.81 KB, 下載次數: 123)
下載附件
2016-9-9 01:08 上傳
單片機源程序如下:
- #include<reg51.h>
- #include<string.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit SDA=P1^0; //1302的IO口
- sbit CLK=P1^1; //1302的時鐘線
- sbit RST=P1^2; //1302的復位線
- sbit RS=P2^0; //1602寄存器選擇
- sbit RW=P2^1; //1602讀寫控制
- sbit E=P2^2; //1602的啟動
- sbit K1=P3^4; //調時選擇
- sbit K2=P3^5; //加
- sbit K3=P3^6; //減
- sbit K4=P3^7; //確定
- uchar tcount=0;
- uchar monthsdays[]={0,31,0,31,30,31,30,31,31,30,31,30,31};
- uchar*week[]={"SUN","MON","TUS","WEN","THU","FRI","SAT"};
- uchar LCD_buffer1[]={"DATE 00-00-00 "};
- uchar LCD_buffer2[]={"TIME 00-00-00 "};
- uchar datetime[7];
- char adjust_index=-1;
- uchar change_flag[]="-MHDM-Y";
- void delay(uint z);
- void set_ds1302();
- void gettime();
- uchar read_date(uchar addr);
- void write_ds1302(uchar addr,uchar dat);
- void write_a_byte_to_ds1302(uchar x);
- uchar get_a_byte_from_ds1302();
- uchar read1602state();
- void busy_wait();
- void write_date(uchar dat);
- void write_com(uchar cmd);
- void init_lcd1602();
- void set_weizhi(uchar p);
- void display_string(uchar p,uchar*s);
- void format_datetime(uchar d,uchar*a);
- uchar runnian(uint y);
- void refresh_week_day();
- void datetime_adjust(char x);
- /////////主程序
- void main()
- {
- init_lcd1602();
- IE=0x83;
- IP=0x01;
- IT0=1;
- TMOD=0X01;
- TH0=5000/256;
- TL0=5000%256;
- TR0=1;
- while(1)
- {
- if(adjust_index==-1)
- gettime();
- }
- }
- /////////////////延時
- void delay(uint z)
- {
- uchar i;
- while(z--)
- for(i=0;i<120;i++);
- }
- ////////////設置時間
- void set_ds1302()
- {
- uchar i;
- write_ds1302(0x8e,0x00);
- for(i=1;i<7;i++)
- {
- write_ds1302(0x80+2*i,(datetime[i]/10<<4)|(datetime[i]%10));
- }
- write_ds1302(0x8e,0x80);
- }
- /////////////讀取當前日期時間
- void gettime()
- {
- uchar i;
- for(i=0;i<7;i++)
- {
- datetime[i]=read_date(0x81+2*i);
- }
- }
- /////////////從1302指定位置讀數
- uchar read_date(uchar addr)
- {
- uchar dat;
- RST=0;
- CLK=0;
- RST=1;
- write_a_byte_to_ds1302(addr);
- dat=get_a_byte_from_ds1302();
- CLK=1;
- RST=0;
- return dat;
- }
- //////////////向1302某地址寫數據
- void write_ds1302(uchar addr,uchar dat)
- {
- CLK=0;
- RST=1;
- write_a_byte_to_ds1302(addr);
- write_a_byte_to_ds1302(dat);
- CLK=0;
- RST=0;
- }
- /////////////向1302寫入一個字節
- void write_a_byte_to_ds1302(uchar x)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- SDA=x&0X01;
- CLK=1;
- CLK=0;
- x>>=1;
- }
- }
- /////////從1302中讀取一個字節
- uchar get_a_byte_from_ds1302()
- {
- uchar i,b=0x00;
- for(i=0;i<8;i++)
- {
- b=_crol_((uchar)SDA,i);
- CLK=1;
- CLK=0;
- }
- return b/16*10+b%16;
- }
- /////////讀1602狀態
- uchar read1602state()
- {
- uchar state;
- RS=0;
- RW=1;
- E=1;
- delay(1);
- state=P0;
- E=0;
- delay(1);
- return state;
- }
- //1602忙等待
- void busy_wait()
- {
- while((read1602state()&0x80)==0x80);
- delay(5);
- }
- //向1602寫數據
- void write_date(uchar dat)
- {
- busy_wait();
- RS=1;
- RW=0;
- E=0;
- P0=dat;
- E=1;
- delay(1);
- E=0;
- }
- //////向1602寫指令
- void write_com(uchar cmd)
- {
- busy_wait();
- RS=0;
- RW=0;
- E=0;
- P0=cmd;
- delay(1);
- E=0;
- }
- ///1602初始化
- void init_lcd1602()
- {
- write_com(0x38);
- delay(1);
- write_com(0x01);
- delay(1);
- write_com(0x06);
- delay(1);
- write_com(0x0c);
- delay(1);
- }
- //設置1602顯示位置
- void set_weizhi(uchar p)
- {
- write_com(p|0x80);
- }
- void display_string(uchar p,uchar*s)
- {
- uchar i;
- set_weizhi(p);
- for(i=0;i<16;i++)
- {
- write_date(s[i]);
- delay(1);
- }
- }
- //日期 時間值轉化為數字字符
- void format_datetime(uchar d,uchar*a)
- {
- a[0]=d/10+'0';
- a[1]=d%10+'0';
- }
- ///判斷閏年
- uchar runnian(uint y)
- {
- return(y%4==0&&y%100!=0||(y%400==0));
- }
- ///////求2000 1.1開始任何一天是星期幾
- //////////求總天數后 再求星期幾
- void refresh_week_day()
- {
- uint i,d,w=5;
- for(i=2000;i<2000+datetime[6];i++)
- {
- d=runnian(i)?366:365;
- w=(w+d)%7;
- }
- d=0;
- for(i=1;i<datetime[4];i++)
- d+=monthsdays[i];
- d+=datetime[3];
- datetime[5]=(w+d)%7+1;
- }
- ///調整處理
- void EX_INT0() interrupt 0
- {
- if(K1==0)
- {
- while(K1==0);
- if(adjust_index==-1||adjust_index==1)
- adjust_index=7;
- adjust_index--;
- if(adjust_index==5)adjust_index=4;
- LCD_buffer2[13]='[';
- LCD_buffer2[14]=change_flag[adjust_index];
- LCD_buffer2[15]=']';
- }
- else
- if(K2==0)
- {
- while(K2==0);
- datetime_adjust(1);
- }
- else
- if(K3==0)
- {
- while(K3==0);
- datetime_adjust(-1);
- }
- else
- if(K4==0)
- {
- while(K4==0);
- set_ds1302();
- LCD_buffer2[13]=' ';
- LCD_buffer2[14]=' ';
- LCD_buffer2[15]=' ';
- adjust_index=-1;
- }
- }
- //分時日月年 加減
- void datetime_adjust(char x)
- {
- switch(adjust_index)
- {
- case 6:
- if(x==1&&datetime[6]<99)datetime[6]++;
- if(x==-1&&datetime[6]>0)datetime[6]--;
- monthsdays[2]=runnian(2000+datetime[6]?29:28);
- if(datetime[3]>monthsdays[datetime[4]])
- datetime[3]=monthsdays[datetime[4]];
- refresh_week_day();
- break;
- case 4:
- if(x==1&&datetime[4]<12)
- datetime[4]++;
- if(x==-1&&datetime[4]>1)
- datetime[4]--;
- monthsdays[2]=runnian(2000+datetime[6])?29:28;
- if(datetime[3]>monthsdays[datetime[4]])
- datetime[3]=monthsdays[datetime[4]];
- refresh_week_day();
- break;
- case 3:
- monthsdays[2]=runnian(2000+datetime[6])?29:28;
- if(x==1&&datetime[3]<monthsdays[datetime[4]])
- datetime[3]++;
- if(x==-1&&datetime[3]>0)
- datetime[3]--;
- refresh_week_day();
- break;
- case 2:
- if(x==1&&datetime[2]<23)
- datetime[2]++;
- if(x==-1&&datetime[2]>0)
- datetime[2]--;
- break;
- case 1:
- if(x==1&&datetime[1]<59)
- datetime[1]++;
- if(x==-1&&datetime[1]>0)
- datetime[1]--;
- break;
- }
- }
- void T0_INT() interrupt 1
- {
- TH0=5000/256;
- TL0=5000%256;
- if(++tcount!=2)return;
- tcount=0;
- format_datetime(datetime[6],LCD_buffer1+5);
- format_datetime(datetime[4],LCD_buffer1+8);
- format_datetime(datetime[3],LCD_buffer1+11);
- strcpy(LCD_buffer1+13,week[datetime[5]-1]);
- format_datetime(datetime[2],LCD_buffer2+5);
- format_datetime(datetime[1],LCD_buffer2+8);
- format_datetime(datetime[0],LCD_buffer2+11);
- display_string(0x00,LCD_buffer1);
- display_string(0x40,LCD_buffer2);
- }
復制代碼 程序無法編譯,仿真也不顯示字符怎么辦?如何找錯誤,求大神幫助
下載:
|
評分
-
查看全部評分
|