每次仿真时日期和星期都不对,有时直接出现乱码,哪位单片机大佬可以帮忙改改吗,不胜感激。
#include <AT89X52.h>
#include <stdio.h>
bit bclassFlg = 0;
sbit FMQ = P3 ^ 7;
unsigned char stringtemp[10]="";
struct time
{
unsigned char second;
unsigned char minute;
unsigned char hour;
unsigned char day;
unsigned char weekday;
unsigned char month;
unsigned int year;
} time;
sbit tim_sda=P2^6;
sbit tim_scl=P2^7;
sbit lcd16rs = P2^0;
sbit lcd16rw = P2^1;
sbit lcd16en = P2^2;
unsigned char lcd16_1[16];
unsigned char lcd16_2[16] = {"welcome"};
bit tim_ack; // i2c slave ack.
bit tim_err;
unsigned char tim_rd_buffer[16];
unsigned char tim_wr_buffer[16];
/*****************11us延时函数*************************/
void delay11us(unsigned char t)
{
for (;t>0;t--);
}
void delay(unsigned int x)
{
unsigned int a,b;
for(a=x;a>5;a--);
for(b=10;b>0;b--);
}
//写指令
void write_com(unsigned char com)
{
P1=com;// 将指令值写到数据线上
lcd16rs=0;//写指令
lcd16en=0;//给一个LCD 使能脉冲
delay(10);
lcd16en=1;
delay(10);
lcd16en=0;
}
//写数据
void write_date(unsigned char date)
{
P1=date; //将数据写到数据线上
lcd16rs=1; //写数据
lcd16en=0; //给一个LCD 使能脉冲
delay(10);
lcd16en=1;
delay(10);
lcd16en=0;
}
//初始化LCD
void lcd_init()
{
lcd16rw = 0;
write_com(0x38);//显示模式设置
delay(20);
write_com(0x0f);//开显示,显示光标、光标闪烁
delay(20);
write_com(0x06);//光标和显示指针加一,屏幕不移动
delay(20);
write_com(0x01);//清显示屏
delay(20);
}
//在第N行显示第M个字
void lcd16_n_line_n_byte(unsigned char n_line,unsigned char n_byte)
{
unsigned char j;
unsigned char com;
unsigned char *dat1;
unsigned char *dat2;
dat1 = lcd16_1;
dat2 = lcd16_2;
if(n_line==0) //显示第一行。
{
for(j=0;j<n_byte;j++)
{
com = 0x80+j;
write_com(com);
write_date(*dat1);
dat1++;
}
}
if(n_line==1) //显示第二行。
{
for(j=0;j<n_byte;j++)
{
com = 0xc0+j;
write_com(com);
write_date(*dat2);
dat2++;
}
}
}
// i2c start.
void PCF8563_start() //start flag is when tim_scl 1, tim_sdafrom 1 to 0.
{
tim_sda = 1;
delay11us(1);
tim_scl = 1;
delay11us(1);
tim_sda = 0;
delay11us(1);
}
// i2c stop.
void PCF8563_stop() //start flag is when tim_scl 1, tim_sdafrom 0 to 1.
{
tim_sda = 0;
delay11us(1);
tim_scl = 1;
delay11us(1);
tim_sda = 0;
}
//i2c slave respons.
void PCF8563_respons()
{
unsigned char i;
tim_scl = 1;
delay11us(1);
while((tim_sda)&&(i<250)) i++;
if(!tim_sda)
tim_ack = 1;
else
tim_ack = 0;
tim_scl = 0;
delay11us(1);
}
// i2c master respons.
void PCF8563_master_respons(bit master_ack)
{
tim_scl = 0;
delay11us(1);
tim_sda = ~master_ack;
delay11us(1);
tim_scl = 1;
delay11us(1);
tim_scl = 0;
delay11us(1);
}
//i2c init.
void PCF8563_init()
{
tim_sda = 1;
delay11us(1);
tim_scl = 1;
delay11us(1);
}
// i2c write n byte.
void PCF8563_wr_byte(unsigned char dat)
{
unsigned char i , temp;
temp = dat;
for(i=0;i<8;i++)
{
tim_scl = 0;
delay11us(1);
if(temp&0x80)
tim_sda = 1;
else
tim_sda = 0;
temp = temp<<1;
delay11us(1);
tim_scl = 1;
delay11us(1);
}
tim_scl = 0;
delay11us(1);
tim_sda = 1;
delay11us(1);
}
unsigned char PCF8563_rd_byte()
{
unsigned char i,k;
tim_scl = 0;
delay11us(1);
tim_sda = 1;
delay11us(1);
for(i=0;i<8;i++)
{
tim_scl = 1;
delay11us(1);
k = (k<<1)|tim_sda;
tim_scl = 0;
delay11us(1);
}
return k;
}
void PCF8563_write_n_byte(unsigned char add,unsigned char com,unsigned char *dat,unsigned char n_byte) //
{
unsigned char i = 0;
unsigned char temp;
temp = *dat; // send to begin address to 'temp'.
add = add<<1;
add = 0xa0+add+0x00;
PCF8563_start();
PCF8563_wr_byte(add); //send EEPROM address, bit 0 = 0 is write.
PCF8563_respons();
if(!tim_ack) //if i2c respons.
{
tim_err = 1;
return;
}
PCF8563_wr_byte(com); //send EEPROM beginning address.
PCF8563_respons();
if(!tim_ack) //if i2c respons.
{
tim_err = 1;
return;
}
while(n_byte) //write n byte.
{
PCF8563_wr_byte(temp);
PCF8563_respons();
if(!tim_ack)
{
tim_err = 1;
PCF8563_stop();
return;
}
temp++;
n_byte--;
}
PCF8563_stop();
}
void PCF8563_read_n_byte(unsigned char add,unsigned char com,unsigned char n_byte)
{
unsigned char *temp;
temp = tim_rd_buffer;
add = add<<1;
add = 0xa0+add+0x00;
PCF8563_start();
PCF8563_wr_byte(add); //send address + wr.
PCF8563_respons();
PCF8563_wr_byte(com); // first byte address.
PCF8563_respons();
add = add+0x01;
PCF8563_start();
PCF8563_wr_byte(add); //send address + rd.
PCF8563_respons();
while(n_byte) // rd n byte .
{
*temp = PCF8563_rd_byte();
if(n_byte != 1) //if i2c respons.
{
PCF8563_master_respons(1); //if the number is not the last one, master send a ack bit.
}
temp++;
n_byte--;
}
PCF8563_stop();
}
void PCF8563_wr_time()
{
tim_wr_buffer[0] = 0x00; //second
tim_wr_buffer[1] = 0x11; //minute
tim_wr_buffer[2] = 0x22; //hour
tim_wr_buffer[3] = 0x10; //day
tim_wr_buffer[4] = 0x03; //weekday
tim_wr_buffer[5] = 0x06; //month
tim_wr_buffer[6] = 0x15; //year
PCF8563_write_n_byte(1,2,tim_wr_buffer,8);
}
//延时眼熟
void DelayFM(unsigned int x)
{
unsigned char t;
while(x--)
{
for(t=0;t<120;t++);
}
}
//蜂鸣器驱动函数,参数为发声声调
void FM(unsigned char x)
{
unsigned char i;
for(i=0;i<100;i++)
{
FMQ = ~FMQ;
DelayFM(x);
}
FMQ = 0;
}
void PCF8563_rd_time()
{
unsigned char temp;
PCF8563_read_n_byte(1,2,9);
time.second = ((tim_rd_buffer[1]&0x70)>>4)*10 + (tim_rd_buffer[1]&0x0f); //second
time.minute = ((tim_rd_buffer[2]&0x70)>>4)*10 + (tim_rd_buffer[2]&0x0f); //minute
time.hour = ((tim_rd_buffer[3]&0x30)>>4)*10 + (tim_rd_buffer[3]&0x0f); //hour
time.day = ((tim_rd_buffer[4]&0x30)>>4)*10 + (tim_rd_buffer[4]&0x0f); //day
time.weekday = tim_rd_buffer[5]&0x07; //weekday
time.month = ((tim_rd_buffer[6]&0x10)>>4)*10 + (tim_rd_buffer[6]&0x0f); //month
if(time.second == 0)
{
if(bclassFlg == 0 )
{
sprintf(stringtemp,"%x%x",time.hour,time.minute);
// printf("%s\n",stringtemp);
printf("it's time to have class\n"); //上课
bclassFlg = 1;
FM(3);
}
}
else if(time.second == 45) //如果到了45分钟,开始下课铃
{
if(bclassFlg == 1)
{
sprintf(stringtemp,"%x%x",time.hour,time.minute);
// printf("%s\n",stringtemp);
printf("it's time to finish class\n");
bclassFlg = 0;
FM(7);
}
}
else
{
}
temp = (tim_rd_buffer[4]&0x80)>>7;
time.year = (temp+20)*100+((tim_rd_buffer[7]&0x70)>>4)*10 + (tim_rd_buffer[7]&0x0f); //year
lcd16_1[0] = time.hour/10+0x30; //hour
lcd16_1[1] = time.hour%10+0x30;
lcd16_1[2] = '-';
lcd16_1[3] = time.minute/10+0x30; //minute
lcd16_1[4] = time.minute%10+0x30;
lcd16_1[5] = '-';
lcd16_1[6] = time.second/10+0x30; //second
lcd16_1[7] = time.second%10+0x30;
lcd16_2[0] = time.year/1000+0x30; //year
lcd16_2[1] = (time.year%1000)/100+0x30;
lcd16_2[2] = (time.year%100)/10+0x30;
lcd16_2[3] = time.year%10+0x30;
lcd16_2[4] = '-';
lcd16_2[5] = time.month/10+0x30; //mon
lcd16_2[6] = time.month%10+0x30;
lcd16_2[7] = '-';
lcd16_2[8] = time.day/10+0x30; //day
lcd16_2[9] = time.day%10+0x30;
lcd16_2[10] = 'w';
lcd16_2[11] = 'e';
lcd16_2[12] = 'e';
lcd16_2[13] = 'k';
lcd16_2[14] = ':';
lcd16_2[15] = time.weekday+0x30;
lcd16_n_line_n_byte(0,16);
lcd16_n_line_n_byte(1,16);
}
void DelayMS(unsigned int ms)
{
unsigned char i;
while(ms--)
{
for(i=0;i<120;i++);
}
}
void InitUart(void)
{
SCON = 0x50; //工作方式1
TMOD = 0x21;
PCON = 0x00;
TH1 = 0xfd; //使用T1作为波特率发生器
TL1 = 0xfd;
TI = 1;
TR1 = 1; //启动T1 //启动T1
}
void main()
{
PCF8563_init();
// PCF8563_wr_time();
lcd_init();
InitUart();
while(1)
{
PCF8563_rd_time();
DelayMS(250);
}
}
|