麻烦哪位大神看一下下面关于DS1302和1602液晶显示器的程序,为啥仿真显示的星期总是后一天的呀,比如今天星期三,就显示成星期四
下面是的DS1302的程序
#include
#include
//#define uchar unsigned char
//#define uint unsigned int
/*复位脚*/
#define RST_CLR PORTB&=~(1< #define RST_SET PORTB|=(1 #define RST_IN DDRB&=~(1 #define RST_OUT DDRB|=(1 /*双向数据*/
#define IO_CLR PORTB&=~(1 #define IO_SET PORTB|=(1 #define IO_R PINB&(1 #define IO_IN DDRB&=~(1 #define IO_OUT DDRB|=(1 /*时钟信号*/
#define SCK_CLR PORTB&=~(1 #define SCK_SET PORTB|=(1 #define SCK_IN DDRB&=~(1 #define SCK_OUT DDRB|=(1 /*函数声明*/
void Delay_us(uint us);
void write_byte(uchar inbyte);
uchar read_byte(void);
void write_ds1302(uchar cmd,uchar indata);
uchar read_ds1302(uchar addr);
void set_ds1302(uchar addr,uchar *p,uchar n);
void init_ds1302(void);
/*us延时函数*/
void Delay_us(uint us)
{
uint i;
us=us*5/4;
for(i=0;i }
/*从ds1302中读一字节数据*/
uchar read_byte(void)
{
uchar i,dat=0;
IO_IN;
IO_CLR;
for(i=0;i {
SCK_SET;
Delay_us(10);
SCK_CLR;
Delay_us(10);
if(IO_R)
{dat=dat|0x80;}
else
{dat=dat&0x7f;}
SCK_SET;
dat=dat>>1;
}
IO_OUT;
return dat;
}
/*向ds1302中写入一字节数据*/
void write_byte(uchar dat)
{
uchar i;
for(i=0;i {
SCK_CLR;
if(dat&0x01)
{
IO_SET;
}
else
{
IO_CLR;
}
Delay_us(10);
SCK_SET;
dat>>=1;
}
}
/*从ds1302的指定地址读一字节数据*/
uchar read_ds1302(uchar addr)
{
char data;
RST_CLR;
SCK_CLR;
Delay_us(10);
RST_SET;
Delay_us(10);
write_byte(addr);
Delay_us(10);
data=read_byte();
Delay_us(10);
SCK_CLR;
RST_CLR;
return data;
}
void write_ds1302(uchar addr,uchar data)
{
RST_CLR;
SCK_CLR;
Delay_us(10);
RST_SET;
Delay_us(10);
write_byte(addr);
Delay_us(10);
SCK_CLR;
Delay_us(10);
write_byte(data);
SCK_CLR;
Delay_us(10);
RST_CLR;
}
/*设置初始时间函数*/
void set_ds1302(uchar addr,uchar *p,uchar n)
{
write_ds1302(0x8e,0x00);
for(;n>0;n--)
{
write_ds1302(addr,*p);
p++;
addr=addr+2;
}
write_ds1302(0x8e,0x80);
}
/*初始化ds1302*/
void init_ds1302()
{
RST_CLR;
SCK_CLR;
//RST_OUT;
//SCK_OUT;
write_ds1302(0x80,0x00);
write_ds1302(0x90,0xab);
write_ds1302(0x8e,0x80);
}
下面是1602的程序
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define RS_0 PORTC&=~(1<<PC0)
#define RS_1 PORTC|=(1<<PC0)
#define RW_0 PORTC&=~(1<<PC1)
#define RW_1 PORTC|=(1<<PC1)
#define EN_0 PORTC&=~(1<<PC2)
#define EN_1 PORTC|=(1<<PC2)
/*函数声明*/
void delay_us(uint n);
void Delay_ms(uint xms);
uchar lcd_busy(void);
void lcd_wcmd(uchar cmd);
void lcd_wdat(uchar dat);
void lcd_clr(void);
void lcd_init(void);
void LocateXY(uchar x,uchar y);
void LCD_write_char(uchar x,uchar y,uchar data);
void LCD_write_str(uchar x,uchar y,uchar s);
/*us延时函数/
void delay_us(uint n)
{
if(n==0)
return;
while(n--);
}
/*ms延时函数*/
void Delay_ms(uint xms)
{
int i,j;
for(i=0;i<xms;i++)
{
for(j=0;j<1140;j++);
}
}
/*LCD忙碌检测函数*/
uchar lcd_busy()
{
uchar result;
DDRA=0X00;
RS_0;
RW_1;
EN_1;
delay_us(40);
result=PINA&0X80;
EN_0;
return result;
}
/*写指令寄存器IR函数*/
void lcd_wcmd(uchar cmd)
{
DDRA=0xff;
RS_0;
RW_0;
EN_0;
PORTA=cmd;
EN_1;
delay_us(40);
EN_0;
}
/*写寄存器DR函数*/
void lcd_wdat(uchar dat)
{
DDRA=0XFF;
RS_1;
RW_0;
EN_0;
PORTA=dat;
delay_us(40);
EN_1;
delay_us(40);
EN_0;
}
/**LCD清屏程序*/
void lcd_clr()
{
lcd_wcmd(0x01);
Delay_ms(5);
}
/*lcd初始化函数*/
void lcd_init()
{
Delay_ms(15);
while(lcd_busy());
lcd_wcmd(0x38);
Delay_ms(10);
while(lcd_busy());
lcd_wcmd(0x38);
Delay_ms(10);
while(lcd_busy());
lcd_wcmd(0x38);
Delay_ms(10);
while(lcd_busy());
lcd_wcmd(0x0c);
Delay_ms(10);
while(lcd_busy());
lcd_wcmd(0x06);
Delay_ms(10);
while(lcd_busy());
lcd_wcmd(0x10);
Delay_ms(10);
}
/*光标定位函数*/
void LocateXY(uchar x,uchar y)
{
if(y==0)
{
lcd_wcmd(0x80+x);
}
else
{
lcd_wcmd(0xc0+x);
}
}
/*显示屏字符串写入函数*/
void LCD_write_str(uchar x,uchar y,uchar s)
{
LocateXY(x,y);
while(*s)
{
lcd_wdat(*s);
s++;
}
}
/显示屏单字符写入函数*/
void LCD_write_char(uchar x,uchar y,uchar data)
{
LocateXY(x,y);
lcd_wdat(data);
}
首先看看ds1302的星期一是从0开始还是从1开始,感觉能显示正常程序应该没问题
这里是一个用数码管显示的时钟,你可以借用里面的ds1302程序,然后用液晶显示
# include <reg51.h>
# define uchar unsigned char
# define uint unsigned int
sbit DS1302_CLK=P1^1;
sbit DS1302_RST=P1^0;
sbit DS1302_IO=P1^2;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
sbit duan=P3^0;
sbit wei=P3^1;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar code shuju[]={
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59};
typedef struct __SYSTEMTIME__
{
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char Week;
unsigned char Day;
unsigned char Month;
unsigned char Year;
unsigned char DateString[11];
unsigned char TimeString[9];
}SYSTEMTIME; //定义的时间类型
SYSTEMTIME CurrentTime;
#define AM(X) X
#define PM(X) (X+12) // 转成24小时制
#define DS1302_SECOND 0x80 //时钟芯片的寄存器位置,存放时间
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8A
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8C
void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数)
{
unsigned char i;
ACC = d;
for(i=8; i>0; i--)
{
DS1302_IO = ACC0; //相当于汇编中的 RRC
DS1302_CLK = 1;
DS1302_CLK = 0;
ACC = ACC >> 1;
}
}
unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数)
{
unsigned char i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; //相当于汇编中的 RRC
ACC7 = DS1302_IO;
DS1302_CLK = 1;
DS1302_CLK = 0;
}
return(ACC);
}
void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr); // 地址,命令
DS1302InputByte(ucDa); // 写1Byte数据
DS1302_CLK = 1;
DS1302_RST = 0;
}
unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据
{
unsigned char ucData;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr|0x01); // 地址,命令
ucData = DS1302OutputByte(); // 读1Byte数据
DS1302_CLK = 1;
DS1302_RST = 0;
return(ucData);
}
void DS1302_GetTime(SYSTEMTIME *Time) //获取时钟芯片的时钟数据到自定义的结构型数组
{
unsigned char ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ////把十六进制转化成十进制
ReadValue = Read1302(DS1302_MINUTE);
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_HOUR);
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_DAY);
Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_WEEK);
Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_MONTH);
Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_YEAR);
Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
}
void Initial_DS1302(void) //时钟芯片初始化
{
unsigned char Second=Read1302(DS1302_SECOND);
if(Second&0x80) //判断时钟芯片是否关闭
{
Write1302(0x8e,0x00); //写入允许
Write1302(DS1302_YEAR,0x11); //以下写入初始化时间 日期:11/07/25.星期: 3. 时间: 23:59:55
Write1302(DS1302_MONTH,0x07);
Write1302(DS1302_DAY,0x25);
Write1302(DS1302_WEEK,0x03);
Write1302(DS1302_HOUR,0x23);
Write1302(DS1302_MINUTE,0x14);
Write1302(DS1302_SECOND,0x55);
Write1302(0x8e,0x80); //禁止写入
}
}
void Delay1ms(unsigned int count)
{
unsigned int i,j;
for(i=0;i<count;i++)
for(j=0;j<120;j++);
}
void display(uchar shu)
{
uchar shi,ge;
shi=shu/10;
ge=shu%10;
wei=1;
P2=0xef;
wei=0;
duan=1;
P2=table[shi];
Delay1ms(5);
duan=0;
wei=1;
P2=0xdf;
wei=0;
duan=1;
P2=table[ge];
Delay1ms(5);
duan=0;
}
void main()
{
Initial_DS1302();
Write1302(DS1302_MINUTE, shuju[24]) ;
while(1)
{
DS1302_GetTime(&CurrentTime);
display(CurrentTime.Second);
}
}