求各位大神帮忙看一下我用51做的万年历程序有没有问题,液晶只有被光亮,不显示内容。
#include<reg52.h>#include<intrins.h>#define ds1302_sec_add 0x80 //设置秒的地址#define ds1302_min_add 0x82 //设置分的地址#define ds1302_hr_add 0x84 //设置时的地址#define ds1302_date_add 0x86 //设置天的地址#define ds1302_month_add 0x88 //设置月的地址#define ds1302_year_add 0x8c //设置年的地址#define ds1302_control_add 0x8e#define ds1302_charger_add 0x90 #define ds1302_clkburst_add 0xbe#define uchar unsigned char#define uint unsigned intsbit E = P2^0;//使能sbit RW = P2^1; //读写sbit RS = P2^2; //数据/命令sbit busy=P0^7; //检测忙sbit DQ= P2^5; //DS18B02单总线sbit RST= P1^1;sbit SCK=P1^2;sbit IO = P1^3;sbit PSB= P2^6;uchar code dig[]={"0123456789"};uchar lcdday [8];uchar lcddisbuf[8];uchar tempbuf[3];uchar timebuf[6] = {23,59,59,18,11,2}; //时间,日期uchar readbuf[6];uchar disbuf[7];uchar writebuf[6]; /*******************************延时子程序**********************************/void delay100(int n){unsigned char i;while(n--)for(i=0;i<100;i++);}/*******************************LCD 忙标志查询******************************/void lcd_busy(void){uchar busy;P0=0xff;RS=0;RW=1;do{E=1;busy=P0;E=0;}while(busy>0x7f);}/*****************************写指令或数据**********************************/void write(uchar x,uchar Data){lcd_busy(); //忙查询if(x==0){RS=0;RW=0; //写单字节命令字}else if(x==1){RS=1;RW=0; //写单字节数据}E=1;P0=Data;E=0;P0=0xff;}/*******************************初始化LCD **********************************/void Init_lcd(void){delay100(20); //启动等待,等LCM讲入工作状态PSB=1; //并口驱动模式RST=0;delay100(4);RST=1; // 复位LCDwrite(0,0x30); //8 位介面,基本指令集write(0,0x0c); //显示打开,光标关,反白关write(0,0x01); //清屏,将DDRAM的地址计数器归零}/*******汉字和字符显示,参数入口:Show(地址,显示宽度,汉字数组)************/void Show(uchar address,uchar L,uchar STR1[]){uchar i;write(0,address);for(i=0;i<L;i++)write(1,STR1[i]);}/************纯阿拉伯数字显示,参数入口:Show_dig(地址,数字)**************/void Show_dig1(uchar address,uint number){uchar shi,ge,fen;shi=number/10;ge=number%10;fen=number*10%10;write(0,address);delay100(20);write(1,dig[shi]);delay100(20);write(1,dig[ge]);delay100(20);write(1,dig[fen]);}void Show_dig(uchar address,uint number){uchar shi,ge;shi=number/10;ge=number%10;write(0,address);delay100(20);write(1,dig[shi]);delay100(20);write(1,dig[ge]);}/*****************DS18B20温度传感器*****************//* 软件延时函数,延时时间(t*10)us */void delay_us(uchar n) //延时约16微妙{for(;n>0;n--){_nop_();}}void DS18B20_init(){uchar i;DQ=1;delay_us(1);//稍作延时DQ=0;delay_us(80); //延时480到960usDQ=1;i = 0;while(DQ){} //等待DS18B20拉低总线while(!DQ){} }void write_byte(uchar dat) //写一个字节{uchar i;for(i=0;i<8;i++){DQ=0; //每写入一位数据之前先把总线拉低1us_nop_();DQ=dat&0x01; //取最低位写入delay_us(7); //延时68us,持续时间最少60usDQ=1; //然后释放总线dat=dat>>1; //从低位开始写}delay_us(10);}uchar read_byte() //读一个字节{uchar i,dat=0;for(i=0;i<8;i++){DQ=0; //先将总线拉低1us_nop_();DQ=1; //然后释放总线_nop_();_nop_();_nop_();_nop_();if(DQ) dat=dat|0x80; //每次读一位dat=dat>>1; //从最低位开始读delay_us(4); //读取完之后等待48us再接着读取下一个数}return dat;}uint read_temper (){ uchar a,b; uint t=0;DS18B20_init(); delay_us(15);write_byte(0xcc); //跳过ROM操作命令write_byte(0x44);//发送启动温度转换命令DS18B20_init(); delay_us(15);write_byte(0xcc); //跳过ROM操作命令write_byte(0xbe);//发送读温度寄存器命令a=read_byte(); //先读低八位b=read_byte();//再读高八位t=b; t<<=8;//左移八位t=t|a;//t为16位的数,使高八位为b的值,低八位为a的值 return t; //返回温度值}uint temper_change(){uint temper;float tp;temper=read_temper();if(temper<0) //考虑负温度的情况{temper=temper-1;temper=~temper;tp=temper*0.0625; //16位温度转换成10进制的温度temper=tp*100+0.5; //留两个小数点,并四舍五入}else{tp=temper*0.0625; //16位温度转换成10进制的温度temper=tp*100+0.5; //留两个小数点,并四舍五入}return temper;}/*************DS1302时钟模块*************/void ds1302_write_byte(unsigned char addr, unsigned char byte){unsigned char i;addr = addr & 0xfe;SCK = 0;RST = 0;RST = 1;/****一个个2进制数依此输进DS1302 *****/for(i = 0; i < 8; i++){IO = addr & 0x01;SCK = 0;SCK = 1;addr >>= 1;}for(i = 0; i < 8; i++){IO = byte & 0x01;SCK = 0;SCK = 1;byte >>= 1;}SCK = 0;RST = 0;}unsigned char ds1302_read_byte(unsigned char addr){unsigned char i;unsigned char temp;addr = addr & 0xfe; //改为读操作SCK = 0;RST = 0;RST = 1;addr = addr + 1; //改为读操作for(i = 0; i < 8; i++){IO = addr & 0x01;SCK = 0;SCK = 1;addr >>= 1;}for(i = 0; i < 8; i++){SCK = 1;SCK = 0;temp >>= 1;if(IO){temp += 0x80;}}//SCK = 0;RST = 0;return temp; // temp:输出的时间或日期}void ds1302_write_time(){unsigned char i;unsigned char temp;unsigned char temp1;for(i = 0; i < 6; i++){ temp = timebuf[i] / 10;//十位temp1 = timebuf[i] % 10;//个位writebuf[i] = (temp << 4) | temp1;//writebuf[i] = ((timebuf[i] / 10) << 4) + (timebuf[i] % 10);} //十进制转化为二进制ds1302_write_byte(ds1302_control_add,0x00);ds1302_write_byte(ds1302_hr_add,writebuf[0]); /***** 时*****/ds1302_write_byte(ds1302_min_add,writebuf[1]);/***** 分 *****/ds1302_write_byte(ds1302_sec_add,writebuf[2]); /***** 秒 *****/ds1302_write_byte(ds1302_year_add,writebuf[3]);/*****年 *****/ds1302_write_byte(ds1302_month_add,writebuf[4]);/***** 月 *****/ds1302_write_byte(ds1302_date_add,writebuf[5]);/*****日 *****/ds1302_write_byte(ds1302_control_add,0x80);}void ds1302_read_time(){unsigned char i;readbuf[0] = ds1302_read_byte(ds1302_hr_add);readbuf[1] = ds1302_read_byte(ds1302_min_add);readbuf[2] = ds1302_read_byte(ds1302_sec_add);readbuf[3] = ds1302_read_byte(ds1302_year_add);readbuf[4] = ds1302_read_byte(ds1302_month_add);readbuf[5] = ds1302_read_byte(ds1302_date_add);for(i = 0; i < 6; i++){disbuf[i] = ((readbuf[i] >> 4) * 10) + (readbuf[i] & 0x0f); //想转化为10进制 }}void welcome(temp){Show(0x80,6,"日历:"); //写数组里的内容Show(0x88,6,"温度:"); //写数组里的内容Show_dig1(0x98,temp);Show(0x82,2,"年"); //写数组里的内容Show(0x84,2,"月"); //写数组里的内容Show(0x86,2,"日"); //写数组里的内容Show(0x92,2,"时"); //写数组里的内容Show(0x94,2,"分"); //写数组里的内容Show(0x96,2,"秒"); //写数组里的内容Show_dig(0x83,disbuf[3]);Show_dig(0x85,disbuf[4]);Show_dig(0x87,disbuf[5]);Show_dig(0x93,disbuf[0]);Show_dig(0x95,disbuf[1]);Show_dig(0x97,disbuf[2]);}void main(){uchar temp;Init_lcd();DS18B20_init();temp = temper_change();ds1302_read_time();ds1302_write_time();welcome(temp);}