qq_512275954 2018-11-11 11:57 采纳率: 0%
浏览 740
已结题

求各位大神帮忙看一下我用51做的万年历程序有没有问题

求各位大神帮忙看一下我用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 int

sbit 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; // 复位LCD
write(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到960us
       DQ=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,持续时间最少60us
     DQ=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);
 }
  • 写回答

1条回答

  • dabocaiqq 2018-11-11 15:52
    关注

    你可以上机运行一下就可以了。建议你买一个试验箱,100多块钱,一顿饭钱。然后在家就可以自己实验了。

    评论

报告相同问题?

悬赏问题

  • ¥50 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?