久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1613|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

基于51單片機萬年歷的程序設(shè)計 僅供參考

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:1059216 發(fā)表于 2022-12-28 11:03 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本文介紹了基于AT89S52單片機的多功能電子萬年歷的硬件結(jié)構(gòu)和軟硬件設(shè)計方法。本設(shè)計由數(shù)據(jù)顯示模塊、溫度采集模塊、時間處理模塊和調(diào)整設(shè)置模塊四個模塊組成。系統(tǒng)以AT89S52單片機為控制器,以串行時鐘日歷芯片DS1302記錄日歷和時間,它可以對年、月、日、時、分、秒進行計時,還具有閏年補償?shù)榷喾N功能。溫度采集選用DS18B20芯片,萬年歷采用直觀的數(shù)字顯示,數(shù)據(jù)顯示采用1602A液晶顯示模塊,可以在LCD上同時顯示年、月、日、周日、時、分、秒,還具有時間校準等功能。

源程序
#include <AT89x52.h>
#include <string.h>
#include<intrins.h>
#define LCM_RS P1_0 //定義引腳
#define LCM_RW P1_1
#define LCM_E P1_2
#define LCM_Data P2
#define Busy 0x80 //用于檢測LCM狀態(tài)字中的Busy標識
#define uchar unsigned char
uchar id,timecount,dipsmodid;
bit lmcinit_or_not; //是否需要清屏標志位“1”為需要“0”為不需要
bit flag,sflag; //flag是時鐘冒號閃爍標志,sflag是溫度負號顯示標志
void Disp_line1(void); //顯示屏幕第一行
void Disp_line2(void); //顯示屏幕第二行
void id_case1_key();
void Disp_mod0(void);//顯示模式0
void Disp_mod1(void);//顯示模式
void Disp_mod2(void);

//*********** DS1302 時間顯示定義部分
sbit T_CLK=P3^4;
sbit T_IO =P3^5;
sbit T_RST=P3^6;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
void Set(uchar,uchar);     //根據(jù)選擇調(diào)整相應(yīng)項目
void   RTInputByte(uchar);       /* 輸入 1Byte */
uchar  RTOutputByte(void);       /* 輸出 1Byte */
uchar clock_h,clock_m;
void   W1302(uchar, uchar);   // 向DS1302寫入一個字節(jié)
uchar  R1302(uchar);          // 從DS1302讀出一個字節(jié)
void   Set1302(unsigned char * ); //  設(shè)置時間
bit sec,min,hour,year,mon,day,weekk; //閃爍標志位
//初始化后設(shè)置為:04年12月2日星期4 0點0分0秒
unsigned char inittime[7]={0x00,0x00,0x00,0x10,0x05,0x04,0x12};
//                          秒  分鐘 小時  日   月   年  星期

//***** 18B20溫度顯示定義部
sbit DQ=P3^7; //18B20 接P07口
typedef unsigned char byte;
typedef unsigned int  word;
Read_Temperature(char,char);
void mychar(void);
byte ow_reset(void);
byte read_byte(void);
void write_byte(char val);
void adjust_res(char res); //res 分別等于 0x1f, 0x3f, 0x5f 溫度讀數(shù)分辨率分別對應(yīng)
                           //              0.5, 0.25, 0.125   
//*******溫度控制部分*********
bit tl_flash_flag;       //下限閃爍標志
bit th_flash_flag;       //上限閃爍標志
bit tl_flag;               //下限越限標志  
bit th_flag;               //上限越限標志  
bit tl_sign,th_sign;                //溫度零下標志 0:零上,1:零下
char tempid;
void Disp_Temp(void);    //顯示上下限溫度
void Set_TH_Temp(void);  //設(shè)置溫度上限
void Set_TL_Temp(void);  //設(shè)置溫度下限
signed char tl=20,th=30;
void Compare_Temp(signed char l,signed char h);     //比較溫度
void Tl_Al(void);         //下限越限報警
void Th_Al(void);         //上限越限報警
//*******1602LCD驅(qū)動程序**********************************************************
void WriteDataLCM(unsigned char WDLCM);
void WriteCommandLCM(unsigned char WCLCM,BuysC);
unsigned char ReadStatusLCM(void);
void LCMInit(void);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
void Delay5Ms(void);
void Delay400Ms(void);
unsigned char code week[]={"Week."};
void main(void)
{
  Delay400Ms(); //啟動等待,等LCM講入工作狀態(tài)
  LCMInit(); //LCM初始化
  Delay5Ms(); //延時片刻(可不要)
  mychar();
  TMOD=0x01;
  TH0=(65535-50000)/256;
  TL0=(65535-50000)%256;
  EA=1;
  TR0=1;
  ET0=1;  
  W1302(0x90,0xa5);//打開充電二級管  一個二級管串聯(lián)一個2K電阻
  W1302(0x8e,0x80);//寫保護,禁止寫操作
  adjust_res(0x1f); //調(diào)整18B20的分辨率 0x1f:0.5; 0x3f:0.25; 0x5f:0.125
  while(1)
    {              
         if (P3_3==0)
      {dipsmodid++;
           lmcinit_or_not=1;
       if(dipsmodid>3) dipsmodid=0;
       while(P3_3==0);
      }
     switch(dipsmodid)
      {
       case 0:
        Disp_mod0();
      
             if( ((R1302(0x83)/16)==clock_m/10) && (R1302(0x83)%16)==clock_m%10   &&((R1302(0x85)/16)==clock_h/10 && (R1302(0x85)%16)==clock_h%10) )
           {
                             P1_3=0;
                     while(P3_2==0);
                                  }
                break;
       case 1:
        Disp_mod1();
        break;
                case 2:
           Disp_mod2();
        break;
            }
    }
}
/*//選擇顯示模?
void Dispmod_id_case_key()
{
if (P0_3==0)
  {dipsmodid++;
   if(dipsmodid>1) dipsmodid=0;
  }
}*/
//顯示模式0
void Disp_mod0(void)
{
if(lmcinit_or_not==1)
  {LCMInit();
   lmcinit_or_not=0;
  }
if ((P3_0|P3_1)==0) //初始化
  {
   Delay5Ms();
   if ((P3_0|P3_1)==0) Set1302(inittime);
  }
//mychar(); //顯示自定義字符
if (P3_2==0) // 設(shè)置和選擇項目鍵
      {
       Delay5Ms();
       if(P3_2==0){id++;if(id>7) id=0;}
       while(P3_2==0);   
      }
     switch(id)
      {
       case 0:
         sec=0;
         Disp_line1(); Disp_line2();
         break;
       case 1://年
         year=1;
         Disp_line1(); Disp_line2();                  
         id_case1_key();
         break;
       case 2://月
         year=0;mon=1;
         Disp_line1(); Disp_line2();                 
         id_case1_key();
         break;
       case 3://日
         mon=0;day=1;
         Disp_line1(); Disp_line2();
         id_case1_key();
         break;            
       case 4://星期
         day=0;weekk=1;
         Disp_line1(); Disp_line2();         
         id_case1_key();
         break;
       case 5://小時
         weekk=0;hour=1;
         Disp_line1(); Disp_line2();
         id_case1_key();      
         break;      
       case 6://分鐘
         hour=0;min=1;
         Disp_line1(); Disp_line2();
         id_case1_key();
         break;
       case 7://秒
         min=0;sec=1;
         Disp_line1(); Disp_line2();            
         id_case1_key();
         break;              
      }
}
//顯示模式1
void Disp_mod1(void)
{
if(lmcinit_or_not==1)
  {LCMInit();
   lmcinit_or_not=0;
  }
  Read_Temperature(1,0);
  DisplayOneChar(0,1,'T');
  DisplayOneChar(1,1,'L');
  DisplayOneChar(2,1,':');
  DisplayOneChar(7,1,'T');
  DisplayOneChar(8,1,'H');
  DisplayOneChar(9,1,':');

  if(R1302(0x89)%16==5&&R1302(0x87)%16==1)

  { DisplayOneChar(9,0,'L' );
   DisplayOneChar(10,0,'a' );
   DisplayOneChar(11,0,'b' );
   DisplayOneChar(12,0,'o' );
   DisplayOneChar(13,0,'r' );
  }
    if(R1302(0x89)/16==1&&R1302(0x89)%16==0&&R1302(0x87)==1)

    {DisplayOneChar(8,0,'N' );
    DisplayOneChar(9,0,'a' );
        DisplayOneChar(10,0,'t' );
        DisplayOneChar(11,0,'i' );
        DisplayOneChar(12,0,'o' );
        DisplayOneChar(13,0,'n' );
        DisplayOneChar(14,0,'a' );
        DisplayOneChar(15,0,'l' );
        }
   
        if(R1302(0x89)%16==1&&R1302(0x87)%16==1)
        { DisplayOneChar(8,0,'Y' );
    DisplayOneChar(9,0,'e' );
        DisplayOneChar(10,0,'a' );
        DisplayOneChar(11,0,'r' );
//        DisplayOneChar(12,0,''' );
        DisplayOneChar(12,0,'s' );
        }
   
if(P3_2==0)
  {
    if(P3_2==0)
     {
      tempid++;
      if(tempid>2) tempid=0;
      while(P3_2==0);
     }
  }
switch(tempid)
  {
   case 0:
    tl_flash_flag=0;
    th_flash_flag=0;
    Disp_Temp();
   break;
   case 1:
    tl_flash_flag=1;
    th_flash_flag=0;
    Disp_Temp();
        Set_TL_Temp();
   break;
   case 2:
    tl_flash_flag=0;
    th_flash_flag=1;
    Disp_Temp();
    Set_TH_Temp();
   break;
  }
Compare_Temp(tl,th);
Tl_Al();
Th_Al();
}
void Disp_mod2(void)
{
if(lmcinit_or_not==1)
  {LCMInit();
   lmcinit_or_not=0;
  }

  DisplayOneChar(6,0,'c' );        
  DisplayOneChar(7,0,'l' );
  DisplayOneChar(8,0,'o' );
  DisplayOneChar(9,0,'c' );
  DisplayOneChar(10,0,'k' );

  DisplayOneChar(1,1,'H');//**********************
  DisplayOneChar(2,1,':');
  DisplayOneChar(3,1,clock_h/10+0x30);
  DisplayOneChar(4,1,clock_h%10+0x30);

  DisplayOneChar(8,1,'M');
  DisplayOneChar(9,1,':'); //***********************
  DisplayOneChar(10,1,clock_m/10+0x30);
  DisplayOneChar(11,1,clock_m%10+0x30);
  
  
if(P3_2==0)
  {
     if(P3_1==0)
          {
             while(P3_1==0);
            clock_h++;
                if(clock_h>23)
                  clock_h=0;
          }
         if(P3_0==0)
          {
            while(P3_0==0);            
                        if(clock_h<1)
                      clock_h=24;
                          clock_h--;
          }
  
  
  }

if(P3_2==1)
  {
     if(P3_1==0)
          {
             while(P3_1==0);
            clock_m++;  
                   if(clock_m>59)
                      clock_m=0;
          }
         if(P3_0==0)
          {
          while(P3_0==0);
            
                  if(clock_m<1)
                     clock_m=60;
                         clock_m--;
          }
  
  
  }













}
               

//顯示上下限溫度
void Disp_Temp(void)
{

unsigned char tl_gw,tl_sw,tl_bw;                //下限溫度的個位,十位,百位
unsigned char th_gw,th_sw,th_bw;                //上限溫度的個位,十位,百位

tl_sign=tl>>7;
if(tl_sign)
  {
   tl_bw=(~(tl-1))/100;                //計算百位
   tl_sw=((~(tl-1))-tl_bw*100)/10;                //計算十位
   tl_gw=(~(tl-1))-tl_bw*100-tl_sw*10;                //計算個位
  }
else
  {
   tl_bw=(tl)/100;         
   tl_sw=(tl-tl_bw*100)/10;
   tl_gw=tl-tl_bw*100-tl_sw*10;
  }

if(tl_flash_flag==1)
  {
   if(flag==1)
    {if(tl_sign)
          {
           DisplayOneChar(3,1,0x2d);
       DisplayOneChar(4,1,tl_sw+0x30);
       DisplayOneChar(5,1,tl_gw+0x30);
          }
         else
          {
           DisplayOneChar(3,1,tl_bw+0x30);
       DisplayOneChar(4,1,tl_sw+0x30); //顯示下限溫度
       DisplayOneChar(5,1,tl_gw+0x30);
      }
    }
   else
    {DisplayOneChar(3,1,0x20);
     DisplayOneChar(4,1,0x20); //顯示下限溫度
     DisplayOneChar(5,1,0x20);   
    }
  }
else
  {
   DisplayOneChar(3,1,tl_bw+0x30);
   DisplayOneChar(4,1,tl_sw+0x30); //顯示下限溫度
   DisplayOneChar(5,1,tl_gw+0x30);
  }

  
  th_sign=th>>7;
  if(th_sign)
   {
    th_bw=(~(th-1))/100;                //計算百位
    th_sw=((~(th-1))-th_bw*100)/10;                //計算十位
    th_gw=(~(th-1))-th_bw*100-th_sw*10;                //計算個位
   }
  else
   {
    th_bw=(th)/100;         
    th_sw=(th-th_bw*100)/10;
    th_gw=th-th_bw*100-th_sw*10;
   }


if(th_flash_flag==1)
  {
   if(flag==1)
    {if(th_sign)
          {
       DisplayOneChar(10,1,0x2d);
       DisplayOneChar(11,1,th_sw+0x30); //顯示下限溫度
       DisplayOneChar(12,1,th_gw+0x30);  
          }
         else
          {
       DisplayOneChar(10,1,th_bw+0x30);
       DisplayOneChar(11,1,th_sw+0x30); //顯示下限溫度
       DisplayOneChar(12,1,th_gw+0x30);  
      }
    }
   else
    {
         DisplayOneChar(10,1,0x20);
     DisplayOneChar(11,1,0x20); //顯示下限溫度
     DisplayOneChar(12,1,0x20);   
    }
  }
else
  {
   DisplayOneChar(10,1,th_bw+0x30);
   DisplayOneChar(11,1,th_sw+0x30); //顯示下限溫度
   DisplayOneChar(12,1,th_gw+0x30);      
  }
}

//設(shè)置溫度下限
void Set_TL_Temp(void)
{
if(P3_1==0)
  {
   Delay5Ms();
   if(P3_1==0)
    {
         tl++;
         if(tl>125) tl=-55;
         //if(tl<-55) tl=155;
        }
   while(P3_1==0);
  }
if(P3_0==0)
  {
   Delay5Ms();
   if(P3_0==0)
    {
         tl--;
         if(tl<-55) tl=125;
        }
  }
}

//設(shè)置溫度上限
void Set_TH_Temp(void)
{
if(P3_1==0)
  {
   Delay5Ms();
   if(P3_1==0)
    {
         th++;
         if(th>125) th=-55;
         //if(tl<-55) tl=155;
        }
   while(P3_1==0);
  }
if(P3_0==0)
  {
   Delay5Ms();
   if(P3_0==0)
    {
         th--;
         if(th<-55) th=125;
        }
  }
}

void Compare_Temp(signed char l,signed char h)     //比較溫度
{
  unsigned char tl_temp;
  unsigned char y,s;
  //unsigned int  x;
  //unsigned char ct[8];
  union{byte c[2]; int x;}temp;
  
  ow_reset();
  write_byte(0xCC); // Skip ROM
  write_byte(0x44); // 轉(zhuǎn)換溫度
  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;    //計算后重新存入數(shù)組
    if(tl_temp>255) temp.c[0]++;  //如果低8位大于255,向高8位進1
   }
  y=0;
  s=0;
  y=temp.c[0]<<4;  
  s=temp.c[1]>>4;
  y=s|y;
  //x=((temp.c[0]&0x07)*256+temp.c[1])*.625;
  if(y<l)
   
    tl_flag=1;
   
  else
   
    tl_flag=0;
   
  if(y>h)
   
    th_flag=1;
   
  else
   
    th_flag=0;
   
}

void Tl_Al(void)         //下限越限報?
{
if(tl_flag==1)
  {
   if(flag==1)
    {   
     DisplayOneChar(14,1,'A');
     DisplayOneChar(15,1,'L');        
    }
   else
    {
     DisplayOneChar(14,1,0x20);
     DisplayOneChar(15,1,0x20);   
    }
  }
else
  {
   DisplayOneChar(14,1,0x20);
   DisplayOneChar(15,1,0x20);         
  }
}

void Th_Al(void)         //上限越限報警
{
if(th_flag==1)
  {
   if(flag==1)
    {   
     DisplayOneChar(14,0,'A');
     DisplayOneChar(15,0,'H');        
    }
   else
    {
     DisplayOneChar(14,0,0x20);
     DisplayOneChar(15,0,0x20);   
    }
  }
else
  {
   DisplayOneChar(14,0,0x20);
   DisplayOneChar(15,0,0x20);         
  }
}



//中斷入口,冒號閃爍
void t0(void) interrupt 1 using 0
{
  TH0=(65535-50000)/256; //50ms定時
  TL0=(65535-50000)%256;  
  timecount++;
  if(timecount>9)
   {
    timecount=0;   
    flag=~flag;            
   }  
}

//id為1時的下一級選擇
void id_case1_key()
{
  if (P3_1==0) //增加
      {
       Delay5Ms();
       if(P3_1==0) Set(id,0);  
       if(id!=7)  while(P3_1==0);   
      }
   if (P3_0==0)  //減少
      {
       Delay5Ms();
       if(P3_0==0) Set(id,1);         
       if(id!=7) while(P3_0==0);   
      }
}

//根據(jù)選擇調(diào)整相應(yīng)項目并寫入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驅(qū)動程序 ***************
//寫數(shù)據(jù)
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(); //根據(jù)需要檢測忙
  LCM_Data = WCLCM;
  LCM_RS = 0;
  LCM_RW = 0;
  LCM_E = 0;
  LCM_E = 0;
  LCM_E = 1;
}
//讀狀態(tài)
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); //三次顯示模式設(shè)置,不檢測忙信號
  Delay5Ms();
  WriteCommandLCM(0x38,0);
  Delay5Ms();
  WriteCommandLCM(0x38,0);
  Delay5Ms();
  WriteCommandLCM(0x38,1); //顯示模式設(shè)置,開始要求每次檢測忙信號
  WriteCommandLCM(0x08,1); //關(guān)閉顯示
  WriteCommandLCM(0x01,1); //顯示清屏
  WriteCommandLCM(0x06,1); // 顯示光標移動設(shè)置
  WriteCommandLCM(0x0C,1); // 顯示開及光標設(shè)置
}
//按指定位置顯示一個字符
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); //這里不檢測忙信號,發(fā)送地址碼
  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坐標應(yīng)小于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讀寫程序***************
/********************************************************************
函 數(shù) 名:RTInputByte()
功    能:實時時鐘寫入一字節(jié)
說    明:往DS1302寫入1Byte數(shù)據(jù) (內(nèi)部函數(shù))
入口參數(shù):d 寫入的數(shù)據(jù)
返 回 值:無  
***********************************************************************/
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;
    }
}
/********************************************************************
函 數(shù) 名:RTOutputByte()
功    能:實時時鐘讀取一字節(jié)
說    明:從DS1302讀取1Byte數(shù)據(jù) (內(nèi)部函數(shù))
入口參數(shù):無  
返 回 值:ACC
設(shè)    計: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);
}
/********************************************************************
函 數(shù) 名:W1302()
功    能:往DS1302寫入數(shù)據(jù)
說    明:先寫地址,后寫命令/數(shù)據(jù) (內(nèi)部函數(shù))
調(diào)    用:RTInputByte() , RTOutputByte()
入口參數(shù):ucAddr: DS1302地址, ucData: 要寫的數(shù)據(jù)
返 回 值:無
***********************************************************************/
void W1302(uchar ucAddr, uchar ucDa)
{
    T_RST = 0;
    T_CLK = 0;
    T_RST = 1;
    RTInputByte(ucAddr);       /* 地址,命令 */
    RTInputByte(ucDa);       /* 寫1Byte數(shù)據(jù)*/
    T_CLK = 1;
    T_RST = 0;
}
/********************************************************************
函 數(shù) 名:R1302()
功    能:讀取DS1302某地址的數(shù)據(jù)
說    明:先寫地址,后讀命令/數(shù)據(jù) (內(nèi)部函數(shù))
調(diào)    用:RTInputByte() , RTOutputByte()
入口參數(shù):ucAddr: DS1302地址
返 回 值:ucData :讀取的數(shù)據(jù)
***********************************************************************/
uchar R1302(uchar ucAddr)
{
    uchar ucData;
    T_RST = 0;
    T_CLK = 0;
    T_RST = 1;
    RTInputByte(ucAddr);             /* 地址,命令 */
    ucData = RTOutputByte();         /* 讀1Byte數(shù)據(jù) */
    T_CLK = 1;
    T_RST = 0;
    return(ucData);
}

/********************************************************************
函 數(shù) 名:Set1302()
功    能:設(shè)置初始時間
說    明:先寫地址,后讀命令/數(shù)據(jù)(寄存器多字節(jié)方式)
調(diào)    用:W1302()
入口參數(shù):pClock: 設(shè)置時鐘數(shù)據(jù)地址 格式為: 秒 分 時 日 月 星期 年
                               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驅(qū)動 **************************
//延時
void delay(unsigned int num)
{
  while( --num ) ;
}

//復(fù)位
byte ow_reset(void)
{
  byte presence;
  DQ = 0;        //拉低總線
  delay(29);    // 保持 480us
  DQ = 1;       // 釋放總線
  delay(3);     // 等待回復(fù)
  presence = DQ; // 讀取信號
  delay(25);    // 等待結(jié)束信號
  return(presence); // 返回   0:正常 1:不存在
}     

//從 1-wire 總線上讀取一個字節(jié)
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 總線上寫一個字節(jié)
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); // 轉(zhuǎn)換溫度
  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;    //計算后重新存入數(shù)組
    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);//顯示溫度十位數(shù)
  DisplayOneChar(xx+1,yy,ct[1]+0x30);//顯示溫度個位數(shù)
  DisplayOneChar(xx+2,yy,0x2e);//顯示小數(shù)點
  DisplayOneChar(xx+3,yy,ct[0]+0x30);//顯示溫度小數(shù)位
  DisplayOneChar(xx+4,yy,0x01);//顯示自定義字符
  DisplayOneChar(xx+5,yy,0x43);//顯示字符“C
//if(ct[2]+0x30==th_sw+0x30&&ct[1]+0x30==th_gw+0x30)
//baojing=0;
// delay
}

//溫度分辨率調(diào)整
void adjust_res(char res) ///res 分別等于 0x1f, 0x3f, 0x5f 溫度讀數(shù)分辨率分別對應(yīng)
                           //              0.5, 0.25, 0.125   
{
  ow_reset();        //復(fù)位
  write_byte(0xcc);  //跳過Rom
  write_byte(0x4e);  //寫暫存器
  write_byte(0x02);  //寫TH
  write_byte(0x01);  //寫TL
  //write_byte(0x5f);  //寫結(jié)構(gòu)寄存器
  write_byte(res);
  ow_reset();       //復(fù)位
  write_byte(0xcc); //跳過Rom
  write_byte(0x48); //把暫存器內(nèi)容寫到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);


為防止有人照搬,僅提供wrod文檔下載(不含其他資料,僅供參考)
文檔僅供參考(如有錯誤請指出,大家一起研究): 1602萬年歷設(shè)計文檔.doc (537 KB, 下載次數(shù): 14)

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 国产精品国产a级 | 欧美无乱码久久久免费午夜一区 | 亚洲码欧美码一区二区三区 | 欧美精品一区二区三区蜜臀 | 国产免费观看久久黄av片涩av | 成人水多啪啪片 | 91久久夜色精品国产网站 | 一区二区精品 | 久久新 | 欧美一级免费 | 五月天婷婷综合 | 日韩一区二区三区av | 中文字幕亚洲一区 | 日韩精品在线观看网站 | 亚洲一区精品在线 | 色久影院| 精品美女在线观看 | 亚洲精品一区在线 | 欧美日韩专区 | 久久er精品 | 国产自产21区 | 国产精品久久久久久久久久久久冷 | 国产一区二区自拍 | 国产日韩欧美一区二区 | 一级毛片在线播放 | 国产精品视频网 | 国产成人a亚洲精品 | 成人午夜影院 | 久久久久久国产精品免费 | 国内自拍视频在线观看 | 色综合99 | 国精产品一区一区三区免费完 | 干狠狠| 丝袜一区二区三区 | 亚洲成人精品 | 91精品国产欧美一区二区成人 | 久久影音先锋 | 中文视频在线 | 国内精品视频免费观看 | 男女深夜网站 | 国产精品永久免费视频 |