本人菜鸟一个,做的万年历无法在LCD12864显示,求各位大神赐教
#define F_CPU 8000000L
#include <avr/io.h>
#include <avr/interrupt.h>
#include <u
til/delay.h>
#define uchar unsigned char
#define uint unsigned int
#include"LCD12864.h"
#include"DHT11.h"
#include"DS1302.h"
int a =0;
uchar time_buf[7]={0}; //星期、年、月、日、时、分、秒
uchar time_dis_buf[14]={0,6,1,2,0,7,2,3,1,7,0,4,3,0};
#define key2 (PINC&0X02)
#define key3 (PINC&0X04)
void port_init_LCD()
{
PORTC=0X0F;
DDRC=0X00;
PORTD=0XFF;
DDRD=0XFF;
}
void lcd_conv()
{
time_dis_buf[0]=time_buf[6]/10+0X30; //星期十位
time_dis_buf[1]=time_buf[6]%10+0X30; //星期个位
time_dis_buf[2]=time_buf[5]/10+0X30; //年十位
time_dis_buf[3]=time_buf[5]%10+0X30; //年个位
time_dis_buf[4]=time_buf[4]/10+0X30; //月十位
time_dis_buf[5]=time_buf[4]%10+0X30; //月个位
time_dis_buf[6]=time_buf[3]/10+0X30; //天十位
time_dis_buf[7]=time_buf[3]%10+0X30; //天个位
time_dis_buf[8]=time_buf[2]/10+0X30; //时十位
time_dis_buf[9]=time_buf[2]%10+0X30; //时个位
time_dis_buf[10]=time_buf[1]/10+0X30; //分十位
time_dis_buf[11]=time_buf[1]%10+0X30; //分个位
time_dis_buf[12]=time_buf[0]/10+0X30; //秒十位
time_dis_buf[13]=time_buf[0]%10+0X30; //秒个位
}
/**********************读取时间函数******-------------****************/
void get_time(void)
{
uchar sec,min,hour,year,mon,day,week;
write_ds1302(0X8E,0X00);
write_ds1302(0X90,0XAB);
sec=read_ds1302(0X81);
min=read_ds1302(0X83);
hour=read_ds1302(0X85);
year=read_ds1302(0X8D);
mon=read_ds1302(0X89);
day=read_ds1302(0X87);
week=read_ds1302(0X8B);
time_buf[0]=sec/16*10+sec%16;
time_buf[1]=min/16*10+min%16;
time_buf[2]=hour/16*10+hour%16;
time_buf[3]=day/16*10+day%16;
time_buf[4]=mon/16*10+mon%16;
time_buf[5]=year/16*10+year%16;
time_buf[6]=week/16*10+week%16-1;
}
/********************时间显示***********-----------*******************/
void time_display(void)
{
LocateXY(0,0);
write_data(2+0X30); //年位
write_data(0+0X30);
write_data(time_dis_buf[2]); //年十位
write_data(time_dis_buf[3]); //年个位
LocateXY(3,0);
write_data(time_dis_buf[4]); //月十位
write_data(time_dis_buf[5]); //月个位
LocateXY(5,0);
write_data(time_dis_buf[6]); //天十位
write_data(time_dis_buf[7]); //天个位
LocateXY(1,1);
write_data(time_dis_buf[8]); //时十位
write_data(time_dis_buf[9]); //时个位
LocateXY(3,1);
write_data(time_dis_buf[10]); //分十位
write_data(time_dis_buf[11]); //分个位
LocateXY(5,1);
write_data(time_dis_buf[12]); //秒十位
write_data(time_dis_buf[13]); //秒个位
}
ISR(INT0_vect)
{
a++;
}
void adjust_time()
{
uchar min1,hour1,year1,mon1,day1,week1;
if ((a==1)|(a==2)|(a==3)|(a==4)|(1==5)|(a==6))
{
write_ds1302(0x8e,0x00);//允许写
write_ds1302(0x80,0x80); //时钟停止
}
if(a==7)
{
a=0;
write_ds1302(0x80,0x00); //启动时钟
write_ds1302(0x8e,0x80);// 进制写(添加写保护)
}
if (key2==0)
{
_delay_ms(10);
if (key2==0)
{
switch(a)
{
case 1:
{
time_buf[5]=time_buf[5]+1;
if(time_buf[5]>=99)
time_buf[5]=0;
year1=time_buf[5]/10*16+time_buf[5]%10;
write_ds1302(0X8C,year1);
} break;
case 2:
{
time_buf[4]=time_buf[4]+1;
if(time_buf[4]>12)
time_buf[4]=1;
mon1=time_buf[4]/10*16+time_buf[4]%10;
write_ds1302(0X88,mon1);
} break;
case 3:
{
time_buf[3]=time_buf[3]+1;
if(time_buf[3]>=31)
time_buf[3]=0;
day1=time_buf[3]/10*16+time_buf[3]%10;
write_ds1302(0X86,day1);
} break;
case 4:
{
while(!(PINC&0X04));
time_buf[2]=time_buf[2]+1;
if(time_buf[6]>=7)
time_buf[6]=1;
week1=time_buf[6]%10;
write_ds1302(0X8A,week1);
} break;
case 5:
{
time_buf[1]=time_buf[1]+1;
if(time_buf[1]>=60)
time_buf[1]=0;
min1=time_buf[1]/10*16+time_buf[1]%10;
write_ds1302(0X82,min1);
} break;
case 6:
{
time_buf[1]=time_buf[1]+1;
if(time_buf[1]>=60)
time_buf[1]=0;
min1=time_buf[1]/10*16+time_buf[1]%10;
write_ds1302(0X82,min1);
} break;
}
}
while(!key2);
}
if (key3==0)
{
_delay_ms(10);
if (key3==0)
{
switch(a)
{
case 1:
{
time_buf[5]=time_buf[5]-1;
if(time_buf[5]==0)
time_buf[5]=96;
year1=time_buf[5]/10*16+time_buf[5]%10;
write_ds1302(0X8C,year1);
} break;
case 2:
{
time_buf[4]=time_buf[4]-1;
if(time_buf[4]==1)
time_buf[4]=12;
mon1=time_buf[4]/10*16+time_buf[4]%10;
write_ds1302(0X88,mon1);
} break;
case 3:
{
time_buf[3]=time_buf[3]-1;
if(time_buf[3]==0)
time_buf[3]=31;
day1=time_buf[3]/10*16+time_buf[3]%10;
write_ds1302(0X86,day1);
} break;
case 4:
{
time_buf[6]=time_buf[6]-1;
if(time_buf[6]==1)
time_buf[6]=7;
week1=time_buf[6]%10;
write_ds1302(0X8A,week1);
} break;
case 5:
{
time_buf[2]=time_buf[2]-1;
if(time_buf[2]==0)
time_buf[2]=23;
hour1=time_buf[2]/10*16+time_buf[2]%10;
write_ds1302(0X84,hour1);
} break;
case 6:
{
time_buf[1]=time_buf[1]-1;
if(time_buf[1]==0)
time_buf[1]=59;
min1=time_buf[1]/10*16+time_buf[1]%10;
write_ds1302(0X82,min1);
} break;
}
while(!key3);
}
}
}
int main(void)
{
GICR|=(1<<INT0);
MCUCR|=(1<<ISC01);
MCUCR&=~(1<<ISC00);
lcd_clr();
port_init_LCD();
init_ds1302();
_delay_ms(100);
LCD_init();
write_string(0,0," 年 月 日 "); //初始化显示
write_string(0,1," 时 分 秒 ");
while(1)
{
show_wenshidu();
get_time(); //读取时间
lcd_conv();
_delay_ms(100);
time_display(); //显示时间
}
}
12864子程序
/*lcd12864接口*/
// GND GND
// VCC
// V0
// RS(CS) PD0
// R/W(SID) PD1
// E PD2
// DB0
// DB1
// DB2
// DB3
// DB4
// DB5
// DB6
// DB7
// PSB PD3
// NC
// RST PD4
// VOUT
// BLA VCC
// BLK GND
#define uchar unsigned char
#define uint unsigned int
#define CS_0 PORTD&=~(1<<PD0) //片选 高电平有效
单片机使用固定高电平
#define CS_1 PORTD|=(1<<PD0)
#define SID_0 PORTD&=~(1<<PD1) //串口数据输入端
#define SID_1 PORTD|=(1<<PD1)
#define SCLK_0 PORTD&=~(1<<PD2) //串口时钟
#define SCLK_1 PORTD|=(1<<PD2)
#define PSB_0 PORTD&=~(1<<PD3) //并口串口选择端,高电平为并口
#define PSB_1 PORTD|=(1<<PD3) //低电平为串口输入
#define RST_0 PORTD&=~(1<<PD4) //复位信号,电平有效
#define RST_1 PORTD|=(1<<PD4)
/*******************************************
发送字节函数 写入一个字节
*******************************************/
void sendbyte(uchar byte)
{
uchar i;
for(i=0;i<8;i++)
{
if(byte&0X80)
{SID_1;}
else
{SID_0;}
SCLK_1;
SCLK_0;
byte<<=1;
}
}
/****************************************
写指令函数规定写指令操作
*****************************************/
void write_com(uchar com) //command
{
uchar star_data,Hdata,Ldata;
star_data=0XF8;
Hdata=com&0XF0;
Ldata=(com<<4)&0XF0;
sendbyte(star_data);
_delay_us(1);
sendbyte(Hdata);
_delay_us(1);
sendbyte(Ldata);
_delay_us(1);
}
/******************************************
写数据函数 规定写数据的流程
*******************************************/
void write_data(uchar data) //data
{
uchar star_data,Hdata,Ldata;
star_data=0XFA;
Hdata=data&0XF0;
Ldata=(data<<4)&0XF0;
sendbyte(star_data);
_delay_us(1);
sendbyte(Hdata);
_delay_us(1);
sendbyte(Ldata);
_delay_us(1);
}
/**********************************************
LCD初始化函数
************************************************/
void LCD_init()
{
RST_0;
_delay_ms(3);
RST_1;
_delay_ms(3);
CS_1;
write_com(0X34);
_delay_ms(5);
write_com(0X30);
_delay_ms(5);
write_com(0X0C);
_delay_ms(5);
write_com(0X01);
_delay_ms(5);
}
/********************清屏*********************/
void lcd_clr(void)
{
write_com(0X01);
_delay_ms(5);
}
/********************************************
光标定位函数,X显示列,Y显示行
***********************************************/
void LocateXY(uchar x,uchar y)
{
if(y==0)
{write_com(0X80+x);}
else if(y==1)
{write_com(0X90+x);}
else if(y==2)
{write_com(0X88+x);}
else if(y==3)
{write_com(0X98+x);}
}
/*************************************************
显示屏字符串写入函数,X表示列,Y表示行
************************************************/
void write_string(uchar x,uchar y,const char *s)
{
LocateXY(x,y);
while(*s)
{
write_data(*s);
s++;
}
}
DS1302子程序
/***复位脚*****/
#define RST_CLR PORTB&=~(1<<PB2) //电平置地
#define RST_SET PORTB|=(1<<PB2) //电平置高
#define RST_IN DDRB&=~(1<<PB2) //方向输入
#define RST_OUT DDRB|=(1<<PB2) //方向输出
/*****双向数据******/
#define IO_CLR PORTB&=~(1<<PB1) //电平置低
#define IO_SET PORTB|=(1<<PB1) //电平置高
#define IO_R PINB&(1<<PB1) //电平读取
#define IO_IN DDRB&=~(1<<PB1) //方向输入
#define IO_OUT DDRB|=(1<<PB1) //方向输出
/*********时钟信号********/
#define SCK_CLR PORTB&=~(1<<PB0) // 时钟信号
#define SCK_SET PORTB|=(1<<PB0) // 电平置高
#define SCK_IN DDRB&=~(1<<PB0) //方向输入
#define SCK_OUT DDRB|=(1<<PB0)/*向DS1302写一个字节*/
uchar read_byte(void); //读一个字节数据
void write_byte(uchar dat); //写一字节数据
void write_ds1302(uchar addr,uchar data); //在指定地址写一字节数据
void set_ds1302(uchar addr,uchar *p,uchar n); //设置初始化
void init_ds1302(void); //初始化函数
/***************从DS1302中读一个字节数据********************/
uchar read_byte(void)
{
uchar i,dat=0;
IO_IN;
IO_CLR;
for(i=0;i<7;i++)
{
SCK_SET;
_delay_us(10);
SCK_CLR;
_delay_us(10);
if(IO_R)
dat|=0X80;
else
dat&=0X7F;
SCK_SET;
dat=dat>>1;
}
IO_OUT;
return dat;
}
/***************从DS1302中写一个字节数据********************/
void write_byte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
SCK_CLR;
if(dat&0X01)
IO_SET;
else
IO_CLR;
_delay_us(10);
SCK_SET;
dat>>=1;
}
}
/*********************在指定的地址读一字节数据************************/
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(void)
{
RST_CLR;
SCK_CLR;
RST_OUT;
SCK_OUT;
write_ds1302(0X80,0X00);
write_ds1302(0X90,0XAB);
write_ds1302(0X8E,0X80);
}
DHT11子程序
#define uchar unsigned char
#define uint unsigned int
#define mclk 8000000
#define DINC_1 DDRC|=_BV(PC0)
#define DINC_0 DDRC&=~_BV(PC0)
#define MOSIN (PINC&0X01)
//数据采集端口PA0
uchar U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
uchar bet[5];
uchar U8temp;
/**********************************************************************
采集数据函数
数据格式为:数据格式:8bit湿度整数数据+8bit湿度小数数据
+8bi温度整数数据+8bit温度小数数据+8bit校验和
*********************************************************************/
void COM(void)
{
uchar i,j,m;
for(i=0;i<5;i++)
{
bet
=0X00;
for(j=0;j<8;j++)
{
while(!MOSIN);//等待高电平的到来,当高电平到来后便开始计时
for(m=0;m<50;m++); //延时50us后看还是不是高电平,如果是高那么这位就为1,否则为0
if(MOSIN) //50us就是时隙,构成电平的一部分
{
bet|=1<<(7-j);
while(MOSIN); //似乎不能辨别高低电平
}
}
}
}
/**************************************************************
初始化DHT进行工作,即驱动DHT工作函数
*************************************************************/
void RH(void)
{
//主机拉低18ms
uchar i;
DINC_1;
PORTC&=~_BV(0);
_delay_ms(20);
PORTC|=_BV(0);
//总线由上拉电阻拉高 主机延时20us
for(i=0;i<23;i++); //此操作为微秒级的延时
//主机设为输入 判断从机响应信号
DINC_0;
for(i=0;i<10;i++);
//判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
if(!MOSIN) //x
{
//判断从机是否发出 80us 的低电平响应信号是否结束
while(!MOSIN);
//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
while(MOSIN);
//数据接收状态
COM();
DDRC=0XFF;
PORTC=0X01;
//数据校验
U8temp=(bet[0]+bet[1]+bet[2]+bet[3]);
if(bet[4]==U8temp)
{
U8RH_data_H=bet[0];
U8RH_data_L=bet[1];
U8T_data_H=bet[2];
U8T_data_L=bet[3];
U8checkdata=bet[4];
}
}
}
/********************************************************************
采集的数据拆分显示到液晶12864上,x,y要显示的位置,z要显示的数据
********************************************************************/
void digital(uchar x,uchar y,uchar z)
{
uchar j,m;
j=z/10;
m=z%10;
//write_com(0x80+0x42+y);
LocateXY(x,y);
write_data(j+0x30);
write_data(m+0x30);
}
//**************houmiantianjia
void show_wenshidu()
{
write_string(0,2,"湿度:");//显示测量项目
_delay_ms(200);
write_string(0,3,"温度:");
_delay_ms(200);
RH();
digital(3,0,U8RH_data_H);//湿度
write_data(0x25);
digital(3,1,U8T_data_H);//温度
write_string(5,1,"℃");
//读取模块数据周期不易小于 2S
_delay_ms(2000);
}
补充内容 (2016-4-30 11:17):
可以显示但是数据不变
补充内容 (2016-4-30 11:53):
DS1302不走时,DHT11数据没变化????苦恼
一周热门 更多>