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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6166|回復: 4
打印 上一主題 下一主題
收起左側

求助!電子鐘

[復制鏈接]
跳轉到指定樓層
樓主
ID:17087 發表于 2009-12-10 15:43 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
 求助!~本人是阿蔡~據以下程序做了一個電子鐘,但最后有點小問題,1602顯示不正確~秒走起來時每隔一個就顯示一個問號~其余年月日,時間等也是如此~請問有誰遇到類似問題?怎樣解決啊~?原理圖及PCB見附件

 

#include "regx51.h"

#include "string.h"

#include "intrins.h"

#define uchar unsigned char

#define uint unsigned int

typedef unsigned char byte;

typedef unsigned int  word;


//*********** 1602引腳定義引腳

#define LCM_RS   P2_0    // 數據/命令選擇信號

#define LCM_RW   P2_1    // 讀/寫選擇信號

#define LCM_E    P2_2    // 使能信號


//*********** DS1302 時間顯示定義部分

sbit T_CLK=P1^0;         //串行時鐘輸入

sbit T_IO =P1^1;         //串行數據端口

sbit T_RST=P1^2;         //復位端口


//*********** 18B20溫度顯示定義部分

sbit DQ=P3^3; //18B20 接P33口

sbit ACC0=ACC^0;

sbit ACC7=ACC^7;


#define LCM_Data P0      //顯示數據端口

#define Busy     0x80    //用于檢測LCM狀態字中的Busy標識


uchar id,timecount;      //全局變量

bit  flag,sflag;         //flag是時鐘冒號閃爍標志,sflag是溫度負號顯示標志

bit  sec,min,hour,year,mon,day,weekk; //閃爍標志位

//*********************函數申明

void   Disp_line1(void);             // 顯示屏幕第一行

void   Disp_line2(void);             // 顯示屏幕第二行

void   id_case1_key();               // id為1時的下一級選擇

void   Set(uchar,uchar);             // 根據選擇調整相應項目

void   RTInputByte(uchar);           /* 輸入 1Byte */

uchar  RTOutputByte(void);           /* 輸出 1Byte */

void   W1302(uchar, uchar);          // 向DS1302寫入一個字節

uchar  R1302(uchar);                 // 從DS1302讀出一個字節

void   Set1302(uchar * );            // 設置時間

//******* 1602LCD驅動 **********************************************************

void   WriteDataLCM(uchar WDLCM);           //寫數據

void   WriteCommandLCM(uchar WCLCM,BuysC);  //寫指令

uchar  ReadStatusLCM(void);                 //讀狀態

void   LCMInit(void);                       //LCM初始化

void   DisplayOneChar(uchar X, uchar Y, uchar DData);        //按指定位置顯示一個字符

void   DisplayListChar(uchar X, uchar Y, uchar code *DData); //按指定位置顯示一串字符

void   Delay5Ms(void);   //5ms延時

void   Delay400Ms(void); //400ms延時

       Read_Temperature(char,char);//溫度顯示

void   mychar(void);          //顯示自定義字符

void   adjust_res(char res);  //res 分別等于 0x1f, 0x3f, 0x5f 溫度讀數分辨率分別對應

                              //              0.5, 0.25, 0.125  

//初始化后設置為:07年07月04日 星期3 12點00分00秒

//      12:00:00 XX. C

//      07/07/04 Week.3

unsigned char inittime[7]={0x00,0x00,0x12,0x04,0x07,0x03,0x07};

//                          秒  分鐘 小時  日   月  星期  年 

uchar code week[]={"Week."};//星期顯示

 

 

 

 //主函數

void main(void)

  Delay400Ms();  //啟動等待,等LCM講入工作狀態

  LCMInit();     //LCM初始化

  Delay5Ms();    //延時片刻(可不要)

  mychar();      //顯示自定義字符


  TMOD=0x01;     //選擇定時模式

  TH0=(65535-50000)/256;//取定時初值

  TL0=(65535-50000)%256;

  EA=1;             //開中斷

  TR0=1;

  ET0=1; 

  W1302(0x90,0xa5); //打開充電二級管  一個二級管串聯一個2K電阻

  W1302(0x8e,0x80); //寫保護,禁止寫操作

  adjust_res(0x5f); //調整18B20的分辨率 0x1f:0.5; 0x3f:0.25; 0x5f:0.125


  while(1)

    {             

     if ((P1_4|P1_5)==0)   // 初始化 同時按下P1_4、P1_5

      {

         Delay5Ms();       // 適當延時,消除抖動

         if ((P1_4|P1_5)==0) Set1302(inittime); // 顯示初始值

      }

     if (P1_6==0)                               // 設置和選擇項目鍵

      {

         Delay5Ms();                            // 適當延時,消除抖動

         if(P1_6==0){id++;if(id>7) id=0;}       // 7個可調節項目循環調節

         while(P1_6==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;      

      }

    }

}

//================================== 定時中斷

/*****************************************************

// 函 數 名:void t0()

// 功    能:時間工作時,冒號閃爍

 //T0中斷入口,方式1

 

void t0(void) interrupt 1 using 0

{

  TH0=(65535-50000)/256; //取50ms定時初值

  TL0=(65535-50000)%256; 

  timecount++;

  if(timecount>9)

   {

    timecount=0;    //計時到,從先開始

    flag=~flag;     //標志位取反         

   } 

}

//==================================== 項目設置

/*****************************************************

 函 數 名:void id_case1_key()

 功    能:項目設置加減控制

 說    明:P1.5和P1.4 <==> +和-

 *****************************************************/

//id為1時的下一級選擇

void id_case1_key()

{

   if (P1_5==0)     //P1_5有按下,則數值增加(+)

      {

       Delay5Ms(); //適當延時,消除抖動

       if(P1_5==0) Set(id,0);  //根據選擇調整相應項目

       if(id!=7)  while(P1_5==0);   

      }

   if (P1_4==0)    //P1_4有按下,則數值減少(-)

      {

       Delay5Ms(); //適當延時,消除抖動

       if(P1_4==0) Set(id,1);     //根據選擇調整相應項目    

       if(id!=7) while(P1_4==0);   

      }

}

/*****************************************************

 函 數 名:void Set()

 功    能:項目設置

 說    明:sel_1=0時,數值加;sel_1=1時,數值減

 入口參數:sel和sel_1

 *****************************************************/

//根據選擇調整相應項目并寫入DS1302

void Set(uchar sel,uchar sel_1)

{

  signed char address,item;

  signed char max,mini;

  //偶數指令是寫,奇數指令是讀

  //最大值與最小值限定

  if(sel==7)  {address=0x80; max=00;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=07;mini=1;}    //星期

  //先從1302中讀出數據,把數據轉換成十進制進行加減設置;后從先轉換回來寫入1302中

  item=R1302(address+1)/16*10+R1302(address+1)%16;//從1302中讀出1字節,再轉換成十進制

  if (sel_1==0) item++;  else item--; //sel_1=0則加,sel_1=1則減

  if(item>max) item=mini;   //大于最大值,則賦最小值(循環)

  if(item<mini) item=max;   //小于最小值,則賦最大值(循環)

          

  W1302(0x8e,0x00);   //允許寫操作

  W1302(address,item/10*16+item%10);//把調節好的十進制數據轉換成十六進制后寫入1302中

  W1302(0x8e,0x80);   //寫保護,禁止寫操作 

}

//=======================================================================================

/*****************************************************

 函 數 名:void Disp_line1()

 功    能:顯示時間和溫度 (XX:XX:XX XX.X C)

 說    明:第一行顯示數據處理

 入口參數:無

 返 回 值:無 

 *****************************************************/

//屏幕顯示第一行: 時間和溫度顯示

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()

 功    能:顯示日期和星期 (XX/XX/XX Week.X)

 說    明:第二行顯示數據處理

 *****************************************************/

// 屏幕顯示第二行  日期和星期  

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);//顯示星期

    }    

}

 


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

使用道具 舉報

沙發
ID:17087 發表于 2009-12-10 15:44 | 只看該作者

//================================ LCM1602控制部分 =======================================

/*****************************************************

 函 數 名:void WriteDataLCM()

 功    能:向LCM1602中寫入數據

 說    明:將形參WDLCM中的數據寫入LCM中

 入口參數:WDLCM

 *****************************************************/

//寫數據

void WriteDataLCM(uchar WDLCM)

{

  ReadStatusLCM(); //檢測忙

  LCM_Data = WDLCM;//寫入數據到LCM

  LCM_RS = 1;

  LCM_RW = 0;

  LCM_E = 0; //若晶振速度太高可以在這后加小的延時

  LCM_E = 0; //延時

  LCM_E = 1;

}

/*****************************************************

 函 數 名:void WriteCommandLCM()

 功    能:向LCM1602中寫入指令

 說    明:向LCM中寫入指令;如果BuysC=0時,忽略忙檢測,如果BuysC=1時,不忽略忙檢測

 入口參數:WCLCM,BuysC

 返 回 值:無 

 *****************************************************/

//寫指令

void WriteCommandLCM(uchar 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;

}

/*****************************************************

 函 數 名:uchar ReadStatusLCM()

 功    能:讀狀態

 說    明:判斷LCM的工作狀態;也可以不用此函數,用一段延時程序代替

 入口參數:無

 返 回 值:LCM_Data 

 *****************************************************/

//讀狀態

uchar ReadStatusLCM(void)

{

  LCM_Data = 0xFF; //LCM數據口先置1

  LCM_RS = 0;

  LCM_RW = 1;

  LCM_E = 0;

  LCM_E = 0;

  LCM_E = 1;

  while (LCM_Data & Busy); //檢測忙信號.如果忙,則不執行

  return(LCM_Data);//不忙返回讀取數據

}

/*****************************************************

 函 數 名:void LCMInit()

 功    能:初始化LCM1602

 說    明:LCM在工作前先要對顯示屏初始化,否則模塊無法正常工作

 入口參數:無

 返 回 值:五 

 *****************************************************/

//LCM初始化

void LCMInit(void)

{

  LCM_Data = 0;

  WriteCommandLCM(0x38,0); // 三次顯示模式設置,不檢測忙信號

  Delay5Ms();

  WriteCommandLCM(0x38,0); // 0x38指令表示:8位數據顯示模式,倆行多顯示

  Delay5Ms();

  WriteCommandLCM(0x38,0);

  Delay5Ms();

  WriteCommandLCM(0x38,1); // 顯示模式設置,開始要求每次檢測忙信號

  WriteCommandLCM(0x08,1); // 關閉顯示

  WriteCommandLCM(0x01,1); // 顯示清屏

  WriteCommandLCM(0x06,1); // 顯示光標移動設置

  WriteCommandLCM(0x0C,1); // 顯示開及光標設置

}

/*****************************************************

 函 數 名:void DisplayOneChar()

 功    能:按指定坐標中寫入數據

 說    明:X-橫坐標,Y-縱坐標

 入口參數:X,Y,DData

 返 回 值: 

 *****************************************************/

//按指定位置顯示一個字符

void DisplayOneChar(uchar X, uchar Y, uchar DData)

{

  Y &= 0x01;

  X &= 0x0F;              //限制X不能大于15,Y不能大于1

  if (Y) X |= 0x40;       //當要顯示第二行時地址碼+0x40;

  X |= 0x80;              //算出指令碼

  WriteCommandLCM(X, 0);  //這里不檢測忙信號,發送地址碼

  WriteDataLCM(DData);

}

/*****************************************************

 函 數 名:void DisplayListChar()

 功    能:向指定坐標中寫入字符串

 說    明:X-橫坐標,Y-縱坐標

 入口參數:X,Y,*DData

 返 回 值: 

 *****************************************************/

//按指定位置顯示一串字符  ***原來的遇到空格0x20就不顯示***

void DisplayListChar(uchar X, uchar Y, uchar code *DData)

{

  uchar ListLength,j;

  ListLength = strlen(DData);//strlen:讀取字符串的長度

  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++;//橫坐標加1,縱坐標不變

            }

        }

}

//=================================== 自定義字符 ==========================================

/*****************************************************

 函 數 名:void mychar()

 功    能:自定義字符--CGRAM

 說    明:LCM1602字符庫中沒有溫度符號,自定義溫度符號

 入口參數:無

 返 回 值:無

 定義形式:1602中定義CGRAM的形式如下:

 ---------------------------------------------------------------------------

 |          CGRAM地址設置              |        自定義的代碼               |

 | DB7 DB6 | DB5 DB4 DB3 | DB2 DB1 DB0 | DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0   |

 |  0   1  |  0   0   0  |  X   X   X  |  0   0   0   0   *   0   0   0    |

 |  0   1  |  0   0   1  |  X   X   X  |  0   0   0   0   *   0   0   1    |

 |   ...   |     ...     |     ...     |       ...               ...       |

 |  0   1  |  1   1   0  |  X   X   X  |  0   0   0   0   *   1   1   0    |

 |  0   1  |  1   1   1  |  X   X   X  |  0   0   0   0   *   1   1   1    |

 ---------------------------------------------------------------------------

  1. 1602共能定義8個5x8字符;

  2. CGRAM地址設置: X X X--DB2 DB1 DB0對應寫入地址,1~8行;

  DB5 DB4 DB3對應自定義字符代碼;DB7 DB6為指令碼,不可變.

  3. 自定義的代碼: 高4位DB7 DB6 DB5 DB4為0000時它的低3位DB2 DB1 DB0對應于第1-8個,DB3為無關項。

  4. 自定義的代碼的DB2 DB1 DB0對應于CGRAM地址的DB5 DB4 DB3。

 *****************************************************/

void mychar()

{

//---------自定義字符代碼--01H-------------------

  WriteCommandLCM(0x48,0); //第1行  

  WriteDataLCM(0x02);//              

  WriteCommandLCM(0x49,0); //第2行  

  WriteDataLCM(0x05);//               

  WriteCommandLCM(0x4a,0); //第3行    1------**--

  WriteDataLCM(0x05);//               2----**--**

  WriteCommandLCM(0x4b,0); //第4行    3----**--**

  WriteDataLCM(0x02);//               4------**--

  WriteCommandLCM(0x4c,0); //第5行    5----------

  WriteDataLCM(0x00);//               6----------

  WriteCommandLCM(0x4d,0); //第6行    7----------

  WriteDataLCM(0x00);//               8----------

  WriteCommandLCM(0x4e,0); //第7行  

  WriteDataLCM(0x00);//

  WriteCommandLCM(0x4f,0); //第8行  

  WriteDataLCM(0x00);//

//-----------------------------------------------

}

//======================================= 延時函數部分 ====================================

/*****************************************************

 函 數 名:void Delay5Ms()

 功    能:5ms延時

 說    明:軟件消除按鍵抖動和適當的延時

 入口參數:無

 返 回 值:無 

 *****************************************************/

//5ms延時

void Delay5Ms(void)

{

  uint TempCyc = 5552; //放入延時數據

  while(TempCyc--);

}

/*****************************************************

 函 數 名:void Delay400Ms()

 功    能:400ms延時

 說    明:

 入口參數:無

 返 回 值:無 

 *****************************************************/

//400ms延時

void Delay400Ms(void)

{

  uchar TempCycA = 5;

  uint TempCycB;

  while(TempCycA--)

   {

     TempCycB=7269;

     while(TempCycB--);

   };

}

 

[此貼子已經被作者于2009-12-10 15:45:26編輯過]
回復

使用道具 舉報

板凳
ID:17087 發表于 2009-12-10 15:44 | 只看該作者

//================================== 時鐘芯片控制部分 ======================================

/*****************************************************

 函 數 名: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

 設    計:zhaojun              日    期:2007-06-29

 修    改:                     日    期:

*****************************************************/

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,寫保護?*/

}

//================================= 溫度顯示控制部分 ===============================================

/*****************************************************

 函 數 名:void delay()

 功    能:DS18B20延時

 說    明:DS18B20時序延時

 入口參數:useconds

 返 回 值:無 

 *****************************************************/

//*********** 18B20驅動 **************************

//延時

void delay(word useconds)

{

  for(;useconds>0;useconds--);

}

/*****************************************************

 函 數 名:byte ow_reset()

 功    能:DS18B20復位

 說    明:DS18B20使用時先要復位

 入口參數:無

 返 回 值:presence 

 *****************************************************/

//復位

byte ow_reset(void)

{

  byte presence;

  DQ = 0;           //拉低總線

  delay(29);        // 保持 480us

  DQ = 1;           // 釋放總線

  delay(3);         // 等待回復

  presence = DQ;    // 讀取信號

  delay(25);        // 等待結束信號

  return(presence); // 返回   0:正常 1:不存在

}    

/*****************************************************

 函 數 名:byte read_byte()

 功    能:從 1-wire 總線上讀取一個字節

 說    明:讀總線上的數據有嚴格的時序

 入口參數:

 返 回 值:value 

 *****************************************************/

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);

}

/*****************************************************

 函 數 名:void write_byte()

 功    能:向 1-WIRE 總線上寫一個字節

 說    明:寫總線上的數據有嚴格的時序

 入口參數:val

 返 回 值:無 

 *****************************************************/

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()

 功    能:讀取和顯示溫度

 說    明:

 入口參數:xx,yy

 返 回 值:無 

 *****************************************************/

Read_Temperature(char xx,char yy)

{

  uchar i,tl_temp;

  uint  x;

  uchar ct[8];

  union   //共用體

  {

    byte c[2];

    int x;

  }temp;   

 

  ow_reset();             // DS18B20復位

  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=0;

       }

  i=0;

  while(x/10)

   {

    ct=x%10;

    x=x/10;

    i++;

   }

  ct=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()

 功    能:溫度分辨率調整

 說    明:此函數可以對溫度的顯示進行精度調節.

 入口參數:res

 返 回 值:無 

 *****************************************************/

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(res);        // 溫度轉換分辨率設置

  ow_reset();             // 復位

  write_byte(0xcc);       // 跳過Rom

  write_byte(0x48);       // 把暫存器內容寫到EPRam中

}

//==========================程序結束======================================================

[此貼子已經被作者于2009-12-10 15:47:04編輯過]
回復

使用道具 舉報

地板
ID:17087 發表于 2009-12-11 20:52 | 只看該作者

咋沒人鳥一下呢?~~

回復

使用道具 舉報

5#
ID:20595 發表于 2009-12-29 21:52 | 只看該作者
我鳥你一下,可惜我看不懂
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久不卡 | 自拍偷拍小视频 | www.操.com | 91观看 | 最新午夜综合福利视频 | 91精品国产高清一区二区三区 | 国产成人精品一区二区三区网站观看 | a级大片| 天天草天天干天天 | 亚洲欧美中文日韩在线v日本 | 久久精品视频在线播放 | 国产一区久久精品 | 欧美精品在线一区二区三区 | 日本在线视频一区二区 | 99re在线 | 久久免费观看视频 | 97国产精品视频人人做人人爱 | 欧美日韩不卡 | 日韩不卡视频在线观看 | 伊人超碰 | 在线观看成人免费视频 | 91亚洲欧美 | 久久久www成人免费精品 | 欧美黄在线观看 | 国产午夜精品一区二区三区四区 | 亚洲精品国产第一综合99久久 | 国产成人在线看 | 成人av观看| 欧美精品一区二区在线观看 | 日韩三级免费网站 | 91久久久久久| 国产免费一区二区 | 狠狠干av | 欧美乱码精品一区二区三区 | 网页av | 看黄在线| 国产精品久久九九 | 一区二区高清 | 日韩一区二区三区视频在线播放 | 国产成人精品综合 | 99精品国产一区二区三区 |