⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 1602液晶显示ds1302+s51时钟+温度显示 源程序.txt

📁 1602液晶显示DS1302+S51时钟+温度显示 源程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:
  timecount=0;  
  flag=~flag;       
  } 
}
//id为1时的下一级选择
void id_case1_key()
{
 if (P0_5==0) //增加
   {
    Delay5Ms();
    if(P0_5==0) Set(id,0); 
    if(id!=7) while(P0_5==0);  
   }
  if (P0_4==0) //减少
   {
    Delay5Ms();
    if(P0_4==0) Set(id,1);     
    if(id!=7) while(P0_4==0);  
   }
}

//根据选择调整相应项目并写入DS1302
void Set(uchar sel,uchar sel_1) 
{
 signed char address,item;
 signed char max,mini;
 if(sel==7) {address=0x80; max=0;mini=0;}   //秒
 if(sel==6) {address=0x82; max=59;mini=0;}  //分钟
 if(sel==5) {address=0x84; max=23;mini=0;}  //小时
 if(sel==3) {address=0x86; max=31;mini=1;}  //日
 if(sel==2) {address=0x88; max=12;mini=1;}  //月
 if(sel==1) {address=0x8c; max=99;mini=0;}  //年
 if(sel==4) {address=0x8a; max=7; mini=1;}  //星期
 
 item=R1302(address+1)/16*10+R1302(address+1)%16;
 if (sel_1==0) item++; else item--;
 if(item>max) item=mini;  
 if(item<mini) item=max;
      
 W1302(0x8e,0x00);//允许写操作
 W1302(address,item/10*16+item%10);
 W1302(0x8e,0x80);//写保护,禁止写操作 
}

//屏幕显示第一行 时间和温度
void Disp_line1(void) 
{ 
 Read_Temperature(10,0); //温度显示
 //冒号闪烁   
 if(flag==0)
  {DisplayOneChar(3,0,0x3a); DisplayOneChar(6,0,0x3a);}
 else
  {DisplayOneChar(3,0,0x20); DisplayOneChar(6,0,0x20);}

 if(sec==1) //秒闪烁标志位
  {
   if(flag==1)
    {  
    DisplayOneChar(7,0,R1302(0x81)/16+0x30); //显示秒
    DisplayOneChar(8,0,R1302(0x81)%16+0x30);    
    }
   else
    {
    DisplayOneChar(7,0,0x20); //显示秒
    DisplayOneChar(8,0,0x20);  
    }
  } 
 else
  {
   DisplayOneChar(7,0,R1302(0x81)/16+0x30); //显示秒
   DisplayOneChar(8,0,R1302(0x81)%16+0x30);     
  }  
  
 if(min==1) //分钟闪烁标志位
  {
   if(flag==1)
    {  
    DisplayOneChar(4,0,R1302(0x83)/16+0x30); //显示分钟
    DisplayOneChar(5,0,R1302(0x83)%16+0x30);    
    }
   else
    {
    DisplayOneChar(4,0,0x20); //显示分钟
    DisplayOneChar(5,0,0x20);  
    }
  } 
 else
  {
   DisplayOneChar(4,0,R1302(0x83)/16+0x30); //显示分钟
   DisplayOneChar(5,0,R1302(0x83)%16+0x30);     
  } 

 if(hour==1) //小时闪烁标志位
  {
   if(flag==1)
    {  
    DisplayOneChar(1,0,R1302(0x85)/16+0x30);//显示小时
    DisplayOneChar(2,0,R1302(0x85)%16+0x30); 
    }
   else
    {
    DisplayOneChar(1,0,0x20); //显示小时
    DisplayOneChar(2,0,0x20);  
    }
  } 
 else
  { 
  DisplayOneChar(1,0,R1302(0x85)/16+0x30);//显示小时
  DisplayOneChar(2,0,R1302(0x85)%16+0x30);
  }
}

// 屏幕显示第二行 日期和星期  
void Disp_line2(void)
{
 DisplayOneChar(3,1,0x2f); //显示固定字符
 DisplayOneChar(6,1,0x2f);
 DisplayListChar(10,1,week);
  
 if(year==1) //年闪烁标志位
  {
   if(flag==1)
    {  
    DisplayOneChar(1,1,R1302(0x8d)/16+0x30);//显示年
    DisplayOneChar(2,1,R1302(0x8d)%16+0x30);
    }
   else
    {
    DisplayOneChar(1,1,0x20); //显示年
    DisplayOneChar(2,1,0x20);  
    }
  } 
 else
  { 
   DisplayOneChar(1,1,R1302(0x8d)/16+0x30);//显示年
   DisplayOneChar(2,1,R1302(0x8d)%16+0x30);
  }
   
 if(mon==1) //月闪烁标志位
  {
   if(flag==1)
    {  
    DisplayOneChar(4,1,R1302(0x89)/16+0x30);//显示月 
    DisplayOneChar(5,1,R1302(0x89)%16+0x30);
    }
   else
    {
    DisplayOneChar(4,1,0x20); //显示月
    DisplayOneChar(5,1,0x20);  
    }
  } 
 else
  { 
   DisplayOneChar(4,1,R1302(0x89)/16+0x30);//显示月 
   DisplayOneChar(5,1,R1302(0x89)%16+0x30);
  }  

 if(day==1) //日闪烁标志位
  {
   if(flag==1)
    {  
     DisplayOneChar(7,1,R1302(0x87)/16+0x30);//显示日
     DisplayOneChar(8,1,R1302(0x87)%16+0x30);
    }
   else
    {
    DisplayOneChar(7,1,0x20); //显示日
    DisplayOneChar(8,1,0x20);  
    }
  } 
 else
  { 
   DisplayOneChar(7,1,R1302(0x87)/16+0x30);//显示日
   DisplayOneChar(8,1,R1302(0x87)%16+0x30);
  }
  
  if(weekk==1) //星期闪烁标志位
  {
   if(flag==1)
    {  
     DisplayOneChar(15,1,R1302(0x8b)%16+0x30);//显示星期
    }
   else
    {
    DisplayOneChar(15,1,0x20); //显示星期     
    }
  } 
 else
  { 
   DisplayOneChar(15,1,R1302(0x8b)%16+0x30);//显示星期
  }   
}

//********* LCM1602驱动程序 ***************
//写数据
void WriteDataLCM(unsigned char WDLCM)
{
 ReadStatusLCM(); //检测忙
 LCM_Data = WDLCM;
 LCM_RS = 1;
 LCM_RW = 0;
 LCM_E = 0; //若晶振速度太高可以在这后加小的延时
 LCM_E = 0; //延时
 LCM_E = 1;
}
//写指令
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
{
 if (BuysC) ReadStatusLCM(); //根据需要检测忙
 LCM_Data = WCLCM;
 LCM_RS = 0;
 LCM_RW = 0; 
 LCM_E = 0;
 LCM_E = 0;
 LCM_E = 1; 
}
//读状态
unsigned char ReadStatusLCM(void)
{
 LCM_Data = 0xFF; 
 LCM_RS = 0;
 LCM_RW = 1;
 LCM_E = 0;
 LCM_E = 0;
 LCM_E = 1;
 while (LCM_Data & Busy); //检测忙信号
 return(LCM_Data);
}
//LCM初始化
void LCMInit(void) 
{
 LCM_Data = 0;
 WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
 Delay5Ms(); 
 WriteCommandLCM(0x38,0);
 Delay5Ms(); 
 WriteCommandLCM(0x38,0);
 Delay5Ms(); 
 WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
 WriteCommandLCM(0x08,1); //关闭显示
 WriteCommandLCM(0x01,1); //显示清屏
 WriteCommandLCM(0x06,1); // 显示光标移动设置
 WriteCommandLCM(0x0C,1); // 显示开及光标设置
}
//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
 Y &= 0x1;
 X &= 0xF; //限制X不能大于15,Y不能大于1
 if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
 X |= 0x80; //算出指令码
 WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
 WriteDataLCM(DData);
}
//按指定位置显示一串字符 ***原来的遇到空格0x20就不显示***
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
 unsigned char ListLength,j;
 ListLength = strlen(DData);
 Y &= 0x1;
 X &= 0xF; //限制X不能大于15,Y不能大于1
   if (X <= 0xF) //X坐标应小于0xF
    { 
  for(j=0;j<ListLength;j++)
   {
        DisplayOneChar(X, Y, DData[j]); //显示单个字符
        X++;
       }
    }
}
//5ms延时
void Delay5Ms(void)
{
 unsigned int TempCyc = 5552;
 while(TempCyc--);
}
//400ms延时
void Delay400Ms(void)
{
 unsigned char TempCycA = 5;
 unsigned int TempCycB;
 while(TempCycA--)
  {
  TempCycB=7269;
  while(TempCycB--);
  };
}

//********DS1302读写程序***************
/******************************************************************** 
函 数 名:RTInputByte()
功  能:实时时钟写入一字节
说  明:往DS1302写入1Byte数据 (内部函数)
入口参数:d 写入的数据 
返 回 值:无 
***********************************************************************/
void RTInputByte(uchar d) 
{ 
  uchar i;
  ACC = d;
  for(i=8; i>0; i--)
  {
    T_IO = ACC0;      /*相当于汇编中的 RRC */
    T_CLK = 1;
    T_CLK = 0;
    ACC = ACC >> 1; 
  } 
}
/******************************************************************** 
函 数 名:RTOutputByte()
功  能:实时时钟读取一字节
说  明:从DS1302读取1Byte数据 (内部函数)
入口参数:无 
返 回 值:ACC
设  计:zhaojunjie      日  期:2002-03-19
修  改:           日  期: 
***********************************************************************/
uchar RTOutputByte(void) 
{ 
  uchar i;
  for(i=8; i>0; i--)
  {
    ACC = ACC >>1;     /*相当于汇编中的 RRC */
    ACC7 = T_IO;
    T_CLK = 1;
    T_CLK = 0;
  } 
  return(ACC); 
}
/******************************************************************** 
函 数 名:W1302()
功  能:往DS1302写入数据
说  明:先写地址,后写命令/数据 (内部函数)
调  用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址, ucData: 要写的数据
返 回 值:无
***********************************************************************/
void W1302(uchar ucAddr, uchar ucDa)
{
  T_RST = 0;
  T_CLK = 0;
  T_RST = 1;
  RTInputByte(ucAddr);    /* 地址,命令 */
  RTInputByte(ucDa);    /* 写1Byte数据*/
  T_CLK = 1;
  T_RST = 0;
}
/******************************************************************** 
函 数 名:R1302()
功  能:读取DS1302某地址的数据
说  明:先写地址,后读命令/数据 (内部函数)
调  用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址
返 回 值:ucData :读取的数据
***********************************************************************/
uchar R1302(uchar ucAddr)
{
  uchar ucData;
  T_RST = 0;
  T_CLK = 0;
  T_RST = 1;
  RTInputByte(ucAddr);       /* 地址,命令 */
  ucData = RTOutputByte();     /* 读1Byte数据 */
  T_CLK = 1;
  T_RST = 0;
  return(ucData);
}

/******************************************************************** 
函 数 名:Set1302()
功  能:设置初始时间
说  明:先写地址,后读命令/数据(寄存器多字节方式)
调  用:W1302()
入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年
                7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B
返 回 值:无
***********************************************************************/
void Set1302(uchar *pClock) 
{
  uchar i;
  uchar ucAddr = 0x80; 
  W1302(0x8e,0x00);      /* 控制命令,WP=0,写操作?*/
  for(i =7; i>0; i--)
  { 
    W1302(ucAddr,*pClock); /* 秒 分 时 日 月 星期 年 */ 
    pClock++;
    ucAddr +=2;
  }
  W1302(0x8e,0x80);      /* 控制命令,WP=1,写保护?*/
}

//*********** 18B20驱动 **************************
//延时
void delay(word useconds)
{
 for(;useconds>0;useconds--);
}

//复位
byte ow_reset(void)
{
 byte presence;
 DQ = 0;    //拉低总线
 delay(29);  // 保持 480us
 DQ = 1;    // 释放总线
 delay(3);   // 等待回复
 presence = DQ; // 读取信号
 delay(25);  // 等待结束信号
 return(presence); // 返回  0:正常 1:不存在
}   

//从 1-wire 总线上读取一个字节
byte read_byte(void)
{
 byte i;
 byte value = 0;
 for (i=8;i>0;i--)
 {
  value>>=1;
  DQ = 0; 
  DQ = 1;
  delay(1); 
  if(DQ)value|=0x80;
  delay(6); 
 }
 return(value);
}

//向 1-WIRE 总线上写一个字节
void write_byte(char val)
{
 byte i;
 for (i=8; i>0; i--) // 一次写一位
 {
  DQ = 0; // 
  DQ = val&0x01;
  delay(5); // 
  DQ = 1;
  val=val/2;
 }
 delay(5);
}

//读取和显示温度
Read_Temperature(char xx,char yy)
{
 unsigned char i,tl_temp;
 unsigned int x;
 unsigned char ct[8];
 union{byte c[2]; int x;}temp;
 
 ow_reset();
 write_byte(0xCC); // Skip ROM
 write_byte(0x44); // 转换温度
 ow_reset();
 write_byte(0xCC); //Skip ROM
 write_byte(0xbe); // 读取寄存器
 temp.c[1]=read_byte();//读出温度低8位
 temp.c[0]=read_byte();//读出温度高8位

 // 零下温度判断
 sflag=0; //温度零下标志 0:零上,1:零下
 if((temp.c[0]&0xf8)!=0x00)
  {
  sflag=1; //零下标志位置1
  temp.c[1]=~temp.c[1]; //低8位取反
  temp.c[0]=~temp.c[0]; //高8位取反
  tl_temp=temp.c[1]+1; //低8位加1 
  temp.c[1]=tl_temp;  //计算后重新存入数组
  if(tl_temp>255) temp.c[0]++; //如果低8位大于255,向高8位进1
 } 

 x=((temp.c[0]&0x07)*256+temp.c[1])*.625;
 for(i=0;i<8;i++)
    {
     ct[i]=0;
    }
 i=0;
 while(x/10)
  {
  ct[i]=x%10;
  x=x/10;
  i++;
  }
 ct[i]=x;

 if(sflag==1) DisplayOneChar(xx-1,yy,0x2d);
 else     DisplayOneChar(xx-1,yy,0x20);
 DisplayOneChar(xx, yy,ct[2]+0x30);//显示温度十位数
 DisplayOneChar(xx+1,yy,ct[1]+0x30);//显示温度个位数
 DisplayOneChar(xx+2,yy,0x2e);//显示小数点
 DisplayOneChar(xx+3,yy,ct[0]+0x30);//显示温度小数位
 DisplayOneChar(xx+4,yy,0x01);//显示自定义字符
 DisplayOneChar(xx+5,yy,0x43);//显示字符“C
}

//温度分辨率调整
void adjust_res(char res) ///res 分别等于 0x1f, 0x3f, 0x5f 温度读数分辨率分别对应
              //       0.5, 0.25, 0.125  
{
 ow_reset();    //复位
 write_byte(0xcc); //跳过Rom
 write_byte(0x4e); //写暂存器
 write_byte(0x02); //写TH 
 write_byte(0x01); //写TL
 //write_byte(0x5f); //写结构寄存器
 write_byte(res);
 ow_reset();    //复位
 write_byte(0xcc); //跳过Rom 
 write_byte(0x48); //把暂存器内容写到EPRam中
} 

void mychar()//自定义字符
{
///////////////////////自定义字符
WriteCommandLCM(0x48, 0); //第一行
WriteDataLCM(0x02);
WriteCommandLCM(0x49, 0); //第2行
WriteDataLCM(0x05);
WriteCommandLCM(0x4a, 0); //第3
WriteDataLCM(0x05);
WriteCommandLCM(0x4b, 0); //第4
WriteDataLCM(0x02);
WriteCommandLCM(0x4c, 0); //第5
WriteDataLCM(0x00);
WriteCommandLCM(0x4d, 0); //第6
WriteDataLCM(0x00);
WriteCommandLCM(0x4e, 0); //第7
WriteDataLCM(0x00);
WriteCommandLCM(0x4f, 0); //第8
WriteDataLCM(0x00);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -