微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 求救!急!做的万年历无法在LCD12864显示,求各位大神赐教

求救!急!做的万年历无法在LCD12864显示,求各位大神赐教

时间:10-02 整理:3721RD 点击:
本人菜鸟一个,做的万年历无法在LCD12864显示,求各位大神赐教
#define F_CPU 8000000L
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/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数据没变化?苦恼

大神快快快来啊啊啊啊!

怎么没有大神啊啊啊!

要干嘛      1002925094                 

不走是啊啊啊啊啊     只是能够显示   怎么改

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top