找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1984|回复: 1
打印 上一主题 下一主题
收起左侧

单片机LCD1602的0显示不正常是程序哪一部分错误,如ds1302.h

[复制链接]
跳转到指定楼层
楼主

#ifndef _DS1302_H_
#define _DS1302_H_
#define uchar unsigned char
sbit SCLK=P2^3;  //ds1302时钟线定义
sbit IO=P2^4;    //数据线
sbit RST=P2^5;         //复位线
uchar sec,min,hour,day,mon,year,week;
//uchar n_year,n_mon,n_day;//农历显示的函数

/*------------------------------------------------
                    DS1302编程部分
------------------------------------------------*/

void write_1302(uchar add,uchar dat) //写操作 (写地址+写数据)
{
        uchar i;
        RST=1;                 //把复位线拉高
        for(i=0;i<8;i++)
        {
                SCLK=0;//时钟信号为低,开始写地址
                IO = add & 0x01;            
                add >>= 1;                 //把地址右移一位
                SCLK=1;                         //时钟线拿高
        }
        for(i=0;i<8;i++)
        {
                SCLK=0;//时钟信号为低,开始写数据
                IO = dat & 0x01;            
                dat >>= 1;                 //把地址右移一位
                SCLK=1;                         //时钟线拿高
        }
        SCLK=0;
        RST=0;//写操作结束
        IO =0;
}
uchar read_1302(uchar add)        //读操作(写地址+读数据)
{
        uchar i,value;
        RST=0;
        SCLK=0;
        RST=1;                 //把复位线拉高
        for(i=0;i<8;i++)
        {
                SCLK=0;//时钟信号为低,开始写地址
                IO = add & 0x01; //让IO保存add的最低位           
                add >>= 1;                 //把地址右移一位
                SCLK=1;                         //时钟线拿高
        }
        for(i=0;i<8;i++)
        {
               
                value >>= 1;         //把数据右移一位
                if(IO == 1)  value |= 0x80; // 将数据放在value的最高位,达到保存数据的结果
                SCLK=0;//时钟信号为低,开始写数据        
                SCLK=1;                         //时钟线拿高
        }
        SCLK=0;
        RST=0;//读操作结束
        IO =0;
        return value;                 //返回读出来的数据
}
uchar BCD_Decimal(uchar bcd)
{
uchar Decimal;
Decimal=bcd>>4;
return(Decimal=Decimal*10+(bcd&=0x0F));
}
/*************把要的时间 年月日 都读出来***************/
void read_time()
{        
    sec = BCD_Decimal(read_1302(0x81));
        min = BCD_Decimal(read_1302(0x83));
        hour  = BCD_Decimal(read_1302(0x85));
        day  = BCD_Decimal(read_1302(0x87));
        mon = BCD_Decimal(read_1302(0x89));
        year=BCD_Decimal(read_1302(0x8d));
        week=BCD_Decimal(read_1302(0x8b));

//        Conversion(0,year,mon,day);        //农历转换                                    
//        n_year = year_moon ;
//        n_mon  = month_moon ;
//        n_day  = day_moon ;

}
                                                //秒  分   时   日   月  年   星期         
//uchar code write_add[]={0x80,0x82,0x84,0x86,0x88,0x8c,0x8a};   //写地址
//uchar code read_add[] ={0x81,0x83,0x85,0x87,0x89,0x8d,0x8b};   //读地址
//uchar code tab1[]={"2020-06-19 FRI"};
//uchar code tab2[]={"10:32:48"};

/*************把要写的时间 年月日 都写入ds1302里***************/
void write_time()
{
    uchar temp;
    write_1302(0x80,sec|0x00);//允许写
        write_1302(0x8e,0x00);                        //打开写保护
        sec= (tab2[6]-0x30)*10+(tab2[7]-0x30);
        temp=(sec)/10*16+(sec)%10;
        write_1302(0x80,0x00|temp);

        min= (tab2[3]-0x30)*10+(tab2[4]-0x30);
        temp=(min)/10*16+(min)%10;
        write_1302(0x82,0x00|temp);

        hour= (tab2[0]-0x30)*10+(tab2[1]-0x30);
        temp=(hour)/10*16+(hour)%10;
        write_1302(0x84,0x00|temp);

        day= (tab1[8]-0x30)*10+(tab1[9]-0x30);
        temp=(day)/10*16+(day)%10;
        write_1302(0x86,0x00|temp);

        mon= (tab1[5]-0x30)*10+(tab1[6]-0x30);
        temp=(mon)/10*16+(mon)%10;
        write_1302(0x88,0x00|temp);

        write_1302(0x8e,0x80);                        //关闭写保护
}
//*************把数据保存到ds1302 RAM中**0-31*************/
//void write_1302ram(uchar add,uchar dat)
//{
//        add <<= 1;     //地址是从第二位开始的
//        add &= 0xfe;   //把最低位清零  是写的命令
//        add |= 0xc0;   //地址最高两位为 1  
//        write_1302(0x8e,0x00);
//        write_1302(add,dat);        
//        write_1302(0x8e,0x80);
//}
//*************把数据从ds1302 RAM读出来**0-31*************/
//uchar read_1302ram(uchar add)
//{
//        add <<= 1;     //地址是从第二位开始的
//        add |= 0x01;   //把最高位置1  是读命令
//        add |= 0xc0;   //地址最高两位为 1  
//        return(read_1302(add));        
//}                                                                                                                 



/*************初始化ds1302时间***************/
void init_ds1302()
{
        RST = 0;        //第一次读写数据时要把IO口拿低
        SCLK=0;
        IO= 0;
        write_time();
}

#endif


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:782437 发表于 2020-6-20 17:25 | 只看该作者
#ifndef _LCD1602_H_
#define _LCD1602_H_
#define uchar unsigned char
#define uint unsigned int
uchar sec,min,hour,day,min,year,week;
sbit RS = P2^0;   //寄存器选择信号 H:数据寄存器          L:指令寄存器
sbit RW = P2^1;          //读写选择信号 H:读          L:写
sbit EN = P2^2;          //片选信号   下降沿触发
#define yh 0x80  //第一行的初始位置
#define er 0x80+0x40 //第二行初始位置
uchar code tab1[]={"2020-06-19 FRI"};
uchar code tab2[]={"10:32:48"};
/***********************延时函数************************/
void delay(uint xms)//延时函数
{
        uint x,y;
        for(x=xms;x>0;x--)
         for(y=110;y>0;y--);
}
void delay_uint(uint q)
{
        while(q--);
}
/*------------------------------------------------
              写入命令函数
------------------------------------------------*/
void LCD_Write_Cmd(uchar cmd)
{  

RS=0; //        选择指令寄存器
RW=0;//写操作
EN=0;//正跳变,将命令写入液晶模块
P0=cmd; //将命令送入P0
delay_uint(3);
EN=1;
delay_uint(25);
EN=0;
}
/*------------------------------------------------
              写入数据函数
------------------------------------------------*/
void LCD_Write_Data(uchar Data)
{
RS=1; //选择数据寄存器
RW=0; //写操作
EN=0;
P0= Data; //将数据送入P0
delay_uint(3);
EN=1;
delay_uint(25);
EN=0;
}
/*------------------------------------------------
              写入星期函数
------------------------------------------------*/
void LCD_Write_week(uchar week)
{     
    LCD_Write_Cmd(yh+0x0d);//将星期显示到LCD的第一行的13位
        switch(week)
        {
                case 1:LCD_Write_Data('M');
                           LCD_Write_Data('O');
                           LCD_Write_Data('N');
                           break;
          
                case 2:LCD_Write_Data('T');
                           LCD_Write_Data('U');
                           LCD_Write_Data('E');
                           break;
               
                case 3:LCD_Write_Data('W');
                           LCD_Write_Data('E');
                           LCD_Write_Data('D');
                           break;
               
                case 4:LCD_Write_Data('T');
                           LCD_Write_Data('H');
                           LCD_Write_Data('U');
                           break;
               
                case 5:LCD_Write_Data('F');
                           LCD_Write_Data('R');
                           LCD_Write_Data('I');
                           break;
               
                case 6:LCD_Write_Data('S');
                           LCD_Write_Data('T');
                           LCD_Write_Data('A');
                           break;
               
                case 7:LCD_Write_Data('S');
                           LCD_Write_Data('U');
                           LCD_Write_Data('N');
                           break;  
         }
}

/*------------------------------------------------
              写入时分秒函数
------------------------------------------------*/
void LCD_Write_sfm(uchar add,uchar dat)
{
uchar gw,sw;//定义十位 个位
gw=dat%10;
sw=dat/10;
LCD_Write_Cmd(er+add); ///将时分秒显示到LCD的第二行的add位
LCD_Write_Data(0x30+sw);
LCD_Write_Data(0x30+gw);//0x30=48  十进制数+48=等于其ascll值   lcd1602为字符型  
}
/*------------------------------------------------
              写入年月日函数
------------------------------------------------*/
void LCD_Write_nyr(uchar add,uchar dat)
{
uchar gw,sw;//定义十位 个位
gw=dat%10;
sw=dat/10;
LCD_Write_Cmd(yh+add); ///将时分秒显示到LCD的第二行的add位
LCD_Write_Data(0x30+sw);
LCD_Write_Data(0x30+gw);//0x30=48  十进制数+48=等于其ascll值   lcd1602为字符型  
}
/*------------------------------------------------
              写入字符串函数
------------------------------------------------*/
void LCD_Write_String(uchar x,uchar y,uchar *s)
{     
if (x == 0)
        {     
         LCD_Write_Cmd(0x80 + y);     //表示第一行
        }
else
        {      
        LCD_Write_Cmd(0xC0 + y);      //表示第二行
        }        
while (*s)
        {     
LCD_Write_Data( *s);     
s ++;     
        }
}
/*------------------------------------------------
        开机液晶显示函数
------------------------------------------------*/
void Init_1602()  //初始化液晶
{  
  LCD_Write_String(0,2,"Hello world");
}
/*------------------------------------------------
              初始化函数
------------------------------------------------*/
void LCD_Init(void)
{
   uchar i;
   LCD_Write_Cmd(0x38);//显示模式设置:16x2显示,5x7点阵,8位数据接口
   LCD_Write_Cmd(0x0c);    //显示模式设置:显示开,有光标
   LCD_Write_Cmd(0x06);   //显示模式设置:光标右移,字符不移
   LCD_Write_Cmd(0x01);        //清屏
   Init_1602();
   delay(1000);
   LCD_Write_Cmd(yh+2);//字符写入的位置--第一行第2位
           for(i=0;i<14;i++)
        {
        LCD_Write_Data(tab1[i]);
        }
        LCD_Write_Cmd(er+4);
        for(i=0;i<8;i++)                                                                          
        {
        LCD_Write_Data(tab2[i]);
        }

   }


#endif
这是LCD1602的程序
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表