找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

程序求補全 帶日歷時鐘及TC72溫度顯示的單片機電子萬年歷仿真與源碼設計

  [復制鏈接]
跳轉到指定樓層
樓主
ID:304109 發(fā)表于 2018-4-8 23:47 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
分享一個單片機電子萬年歷
帶日歷時鐘TC72溫度傳感器顯示,是用的74hc595芯片驅動的數碼管.

完成本例設計后加入日期時間調節(jié)功能

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機源程序如下:
  1. //-----------------------------------------------------------------
  2. //  名稱: 帶日歷時鐘及溫度顯示的電子萬年歷
  3. //-----------------------------------------------------------------
  4. //  說明: 本例使用了DS1302讀取日期時間,用TC72獲取溫度數據
  5. //        通過74HC595驅動數碼管顯示.
  6. //
  7. //-----------------------------------------------------------------
  8. #include <reg51.h>
  9. #include <intrins.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #define INT8U  unsigned char
  13. #define INT16U unsigned int        
  14. const INT8U SEG_CODE[]=        //0~9的段碼,攝氏度段碼(2字節(jié)),黑屏段碼,負號段碼
  15. { 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90,0xC6,0x9C,0xFF,0xBF};
  16. INT8U DateTime[7] = {5,4,3,2,1,5,12};  //假定時間12年1月2日,3點,4分5秒
  17. sbit DS        = P3^0;                        //串行數據輸入
  18. sbit SH_CP = P3^1;                //移位時鐘脈沖
  19. sbit ST_CP = P3^2;                //輸出鎖存器控制脈沖
  20. extern void Init_DS1302();
  21. extern void GetDateTime();
  22. extern void SetDateTime();
  23. extern INT8U CurrDateTime[];
  24. extern void Config_TC72();
  25. extern float Read_TC72_Temperature();
  26. //所有數碼管的顯示緩沖(年有高2位固定為20),最后2位固定為攝氏度段碼索引
  27. INT8U disp_buff[21] = {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10};
  28. //-----------------------------------------------------------------
  29. // 延時函數
  30. //-----------------------------------------------------------------
  31. void delay_ms(INT16U x) { INT8U t; while(x--) for(t = 0; t<120; t++);}
  32. //-----------------------------------------------------------------
  33. // 1字節(jié)數據串行輸入595子程序
  34. //-----------------------------------------------------------------
  35. void Serial_Input_595(INT8U d)
  36. {


  37. }

  38. //-----------------------------------------------------------------
  39. // 595并行輸出子程序
  40. //-----------------------------------------------------------------
  41. void Parallel_Output_595()
  42. {


  43. }

  44. //------------------------------------------------------------------
  45. // 主程序
  46. //------------------------------------------------------------------
  47. void main()
  48. {



  49. }

  50. //-----------------------------------------------------------------
  51. // T0中斷函數(控制秒閃爍,每隔500ms關閉LED,開LED由主程序控制)
  52. //-----------------------------------------------------------------
  53. void LED_Flash() interrupt 1
  54. {



  55. }
復制代碼
  1. //-----------------------------------------------------------------
  2. //        名稱: SPI接口溫度傳感器TC72驅動程序
  3. //-----------------------------------------------------------------
  4. #include <reg51.h>
  5. #include <intrins.h>
  6. #include <stdio.h>
  7. #include <math.h>
  8. #define INT8U        unsigned char
  9. #define INT16U        unsigned int
  10. //TC72寄存器地址定義
  11. #define TC72_CTRL                0x80        //控制寄存器
  12. #define TC72_TEMP_LSB        0x01        //溫度低字節(jié)
  13. #define TC72_TEMP_MSB        0x02        //溫度高字節(jié)
  14. #define TC72_MANU_ID        0x03        //制造商ID
  15. //SPI接口引腳定義(模擬方式)
  16. sbit SCK = P3^4;                                //串行時鐘控制腳
  17. sbit CE  = P3^5;                                //片選
  18. sbit SDI  = P3^6;                                //串行數據輸入
  19. sbit SDO  = P3^7;                                //串行數據輸出
  20. INT8U Temp_Value[2];                        //兩字節(jié)溫度值原始數據
  21. extern void delay_ms(INT16U x);
  22. //-----------------------------------------------------------------
  23. // 從當前地址讀取一字節(jié)數據(模擬方式)
  24. //-----------------------------------------------------------------
  25. INT8U _ReadByte()
  26. {


  27. }

  28. //-----------------------------------------------------------------
  29. // 向當前地址寫入一字節(jié)數據(模擬方式)
  30. //-----------------------------------------------------------------
  31. void _WriteByte(INT8U dat)
  32. {


  33. }

  34. //-----------------------------------------------------------------
  35. // 向TC72寫入兩字節(jié)(地址,數據)(模擬方式)
  36. //-----------------------------------------------------------------
  37. void Write_TC72(INT8U addr, INT8U dat)
  38. {


  39. }

  40. //-----------------------------------------------------------------
  41. // 寫TC72配置數據
  42. //-----------------------------------------------------------------
  43. void Config_TC72()
  44. {
  45.         Write_TC72(TC72_CTRL,0x15);        //配置為單次轉換與關斷模式
  46. }

  47. //-----------------------------------------------------------------
  48. // 從TC72讀取兩字節(jié)溫度數據并轉換為浮點溫度值
  49. //-----------------------------------------------------------------
  50. float Read_TC72_Temperature()
  51. {


  52. }
復制代碼



所有資料51hei提供下載:
帶日歷時鐘及溫度顯示的電子萬年歷.zip (42.93 KB, 下載次數: 71)





評分

參與人數 1黑幣 +5 收起 理由
沐淵 + 5 贊一個!

查看全部評分

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

使用道具 舉報

沙發(fā)
ID:608971 發(fā)表于 2019-9-23 20:48 | 只看該作者
你這程序為什么都是空白
回復

使用道具 舉報

板凳
ID:752705 發(fā)表于 2020-5-17 07:54 | 只看該作者
提示:樓主刪掉了功能函數內的所有代碼,只提供的keil工程的框架和HEX 文件。
回復

使用道具 舉報

地板
ID:1111795 發(fā)表于 2024-2-29 15:24 | 只看該作者
感謝分享,學到了很多,但是打不開仿真圖是為什么呀
回復

使用道具 舉報

5#
ID:453974 發(fā)表于 2024-3-1 10:02 | 只看該作者
xiaxiake 發(fā)表于 2024-2-29 15:24
感謝分享,學到了很多,但是打不開仿真圖是為什么呀

一般打不開都是因為軟件版本不對
回復

使用道具 舉報

6#
ID:453974 發(fā)表于 2024-3-1 10:03 | 只看該作者
你這不是求補全,你這是求重做吧
回復

使用道具 舉報

7#
ID:712097 發(fā)表于 2024-3-2 11:32 | 只看該作者
  1. //-----------------------------------------------------------------
  2. //  名稱: 帶日歷時鐘及溫度顯示的電子萬年歷
  3. //-----------------------------------------------------------------
  4. //  說明: 本例使用了DS1302讀取日期時間,用TC72獲取溫度數據
  5. //        通過74HC595驅動數碼管顯示.
  6. //
  7. //-----------------------------------------------------------------
  8. #include <reg51.h>
  9. #include <intrins.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #define INT8U  unsigned char
  13. #define INT16U unsigned int        
  14. const INT8U SEG_CODE[]=        //0~9的段碼,攝氏度段碼(2字節(jié)),黑屏段碼,負號段碼
  15. { 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90,0xC6,0x9C,0xFF,0xBF};
  16. INT8U DateTime[7] = {5,4,3,2,1,5,12};  //假定時間12年1月2日,3點,4分5秒
  17. sbit DS        = P3^0;                        //串行數據輸入
  18. sbit SH_CP = P3^1;                //移位時鐘脈沖
  19. sbit ST_CP = P3^2;                //輸出鎖存器控制脈沖
  20. extern void Init_DS1302();
  21. extern void GetDateTime();
  22. extern void SetDateTime();
  23. extern INT8U CurrDateTime[];
  24. extern void Config_TC72();
  25. extern float Read_TC72_Temperature();
  26. //所有數碼管的顯示緩沖(年有高2位固定為20),最后2位固定為攝氏度段碼索引
  27. INT8U disp_buff[21] = {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10};
  28. //-----------------------------------------------------------------
  29. // 延時函數
  30. //-----------------------------------------------------------------
  31. void delay_ms(INT16U x) { INT8U t; while(x--) for(t = 0; t<120; t++);}
  32. //-----------------------------------------------------------------
  33. // 1字節(jié)數據串行輸入595子程序
  34. //-----------------------------------------------------------------
  35. void Serial_Input_595(INT8U d)
  36. {
  37.         INT8U i;
  38.         for(i=0;i<8;i++)
  39.         {        d<<=1;DS=CY;
  40.                 SH_CP=0;_nop_();_nop_();
  41.                 SH_CP=1;_nop_();_nop_();               
  42.         }
  43.         SH_CP=0;
  44. }

  45. //-----------------------------------------------------------------
  46. // 595并行輸出子程序
  47. //-----------------------------------------------------------------
  48. void Parallel_Output_595()
  49. {
  50.         ST_CP=0;_nop_();_nop_();
  51.         ST_CP=1;_nop_();_nop_();
  52.         ST_CP=0;_nop_();_nop_();
  53. }

  54. //------------------------------------------------------------------
  55. // 主程序
  56. //------------------------------------------------------------------
  57. void main()
  58. {
  59.         INT8U i,j,len;char t_buff[6],c;INT8U curr_second=0xFF;
  60.         TMOD=0x01;
  61.         TH0=(INT16U)(-11.0592/12*50000)>>8;
  62.         TL0=(INT16U)(-11.0592/12*50000)&0xFF;
  63.         IE=0x82;
  64.         Init_DS1302();
  65.         while(1)
  66.         {
  67.                 GetDateTime();
  68.                 disp_buff[2]=CurrDateTime[6]>>4;
  69.                 disp_buff[3]=CurrDateTime[6]&0x0F;
  70.                 disp_buff[4]=CurrDateTime[4]>>4;
  71.                 disp_buff[5]=CurrDateTime[4]&0x0F;
  72.                 disp_buff[6]=CurrDateTime[3]>>4;
  73.                 disp_buff[7]=CurrDateTime[3]&0x0F;
  74.                 disp_buff[8]=CurrDateTime[2]>>4;
  75.                 disp_buff[9]=CurrDateTime[2]&0x0F;
  76.                 disp_buff[10]=CurrDateTime[1]>>4;
  77.                 disp_buff[11]=CurrDateTime[1]&0x0F;
  78.                 disp_buff[12]=CurrDateTime[0]>>4;
  79.                 disp_buff[13]=CurrDateTime[0]&0x0F;
  80.                 disp_buff[14]=CurrDateTime[5]-1;
  81.                
  82.                 for(i=15;i<18;i++)disp_buff[i]=12;
  83.                 Config_TC72();
  84.                 sprintf(t_buff,"%5.1f",Read_TC72_Temperature());
  85.                 i=j=0;len=strlen(t_buff);
  86.                 for(i=len-1;i!=0xFF;i--)
  87.                 {
  88.                         c=t_buff[i];if(c=='.')continue;
  89.                         if(c>='0'&&c<='9')disp_buff[18-j]=c-'0';
  90.                         else if (c=='-')disp_buff[18-j]=13;
  91.                         j++;
  92.                 }
  93.                
  94.                 for(i=20;i!=0xFF;i--)
  95.                 {
  96.                         if(i!=17)Serial_Input_595(SEG_CODE[disp_buff[i]]);
  97.                         else Serial_Input_595(SEG_CODE[disp_buff[i]]&0x7F);
  98.                 }
  99.                
  100.                 Parallel_Output_595();
  101.                
  102.                 if(curr_second!=CurrDateTime[0])
  103.                 {
  104.                         curr_second=CurrDateTime[0];
  105.                         if(TR0==0)P0&=0xFC;TR0=1;
  106.                 }
  107.         }


  108. }

  109. //-----------------------------------------------------------------
  110. // T0中斷函數(控制秒閃爍,每隔500ms關閉LED,開LED由主程序控制)
  111. //-----------------------------------------------------------------
  112. void LED_Flash() interrupt 1
  113. {
  114.         static INT8U T_Count=0;
  115.         TH0=(INT16U)(-11.0592/12*50000)>>8;
  116.         TL0=(INT16U)(-11.0592/12*50000)&0xFF;
  117.         if(++T_Count==10)
  118.         {
  119.                 P0|=0x03;T_Count=0;TR0=0;
  120.         }


  121. }
復制代碼
//-----------------------------------------------------------------
//        名稱: SPI接口溫度傳感器TC72驅動程序
//-----------------------------------------------------------------
#include "STC15xxx.h"
#include <intrins.h>
#include <stdio.h>
#include <math.h>
#define u8        unsigned char
#define u16        unsigned int
//TC72寄存器地址定義
#define TC72_CTRL                        0x80        //控制寄存器
#define TC72_TEMP_LSB        0x01        //溫度低字節(jié)
#define TC72_TEMP_MSB        0x02        //溫度高字節(jié)
#define TC72_MANU_ID        0x03        //制造商ID
//SPI接口引腳定義(模擬方式)
sbit SCK = P3^4;                                //串行時鐘控制腳
sbit CE  = P3^5;                                //片選
sbit SDI  = P3^6;                                //串行數據輸入
sbit SDO  = P3^7;                                //串行數據輸出
u8 Temp_Value[2];                                //兩字節(jié)溫度值原始數據
extern void delay_ms(u16 x);
//-----------------------------------------------------------------
// 從當前地址讀取一字節(jié)數據(模擬方式)
//-----------------------------------------------------------------
u8 _ReadByte() {
        u8 i        ,d = 0x00;
        for(i = 0; i < 8; i++)                //串行讀取8位數據       
        {        //SCK下降沿讀取數據,讀取的位保存到左移以后的d的低位
                SCK = 1; SCK = 0; d = (d << 1) | SDO;
        }
        return d;                                         //返回讀取的字節(jié)
}
//-----------------------------------------------------------------
// 向當前地址寫入一字節(jié)數據(模擬方式)
//-----------------------------------------------------------------
void _WriteByte(u8 dat) {
        u8 i;
        for(i = 0; i < 8; i++) {        //串行寫入8位數據
                dat <<= 1; SDI = CY;                //dat左移位,高位被移入CY,發(fā)送高位
                SCK = 0; SCK = 1;                                //時鐘上升沿向存儲器寫入數據
        }
}
//-----------------------------------------------------------------
// 向TC72寫入兩字節(jié)(地址,數據)(模擬方式)
//-----------------------------------------------------------------
void Write_TC72(u8 addr, u8 dat) {
        CE = 1;                                                                        //SPI_EN();
        _WriteByte(addr);                                //SPI_SendData(addr);
        _WriteByte(dat);                                 //SPI_SendData(dat);
        CE = 0;                                                                        //SPI_DI();
}
//-----------------------------------------------------------------
// 寫TC72配置數據
//-----------------------------------------------------------------
void Config_TC72() {
        Write_TC72(TC72_CTRL,0x15);        //配置為單次轉換與關斷模式
}
//-----------------------------------------------------------------
// 從TC72讀取兩字節(jié)溫度數據并轉換為浮點溫度值
//-----------------------------------------------------------------
float Read_TC72_Temperature() {
        Config_TC72();
        delay_ms(50);
        CE = 1;                                                //SPI_EN();
        //發(fā)送讀溫度高字節(jié)命令
        _WriteByte(TC72_TEMP_MSB);        //SPI_SendData(TC72_TEMP_MSB);
        //連續(xù)讀取兩字節(jié)(連續(xù)讀取時先得到的是高字節(jié),后得到的是低字節(jié))
        Temp_Value[1] = _ReadByte();        //SPI_SendData(0xFF);//讀高字節(jié)
        Temp_Value[0] = _ReadByte();        //SPI_SendData(0xFF);//讀低字節(jié)
        CE = 0;                                                //SPI_DI();
        //還可以使用以下單字節(jié)讀取的方法
        //SPI_EN();
        //SPI_SendData(TC72_TEMP_LSB);        //發(fā)送讀溫度低字節(jié)命令
        //T[0] = SPI_SendData(0xFF);        //讀LSB
        //SPI_DI();
        //SPI_EN();
        //SPI_SendData(TC72_TEMP_MSB);        //發(fā)送讀溫度高字節(jié)命令
        //T[1] = SPI_SendData(0xFF);        //讀MSB
        //SPI_DI();
        return (int)(((int)((Temp_Value[1]<<8)|Temp_Value[0]))>>6) * 0.25;
}


回復

使用道具 舉報

8#
ID:712097 發(fā)表于 2024-3-2 11:38 | 只看該作者
//-------------------------- DS1302.c -----------------------------
//  名稱:1602字符液晶(HD44780)工作于4位模式顯示DS1302時鐘
//-----------------------------------------------------------------
#include "DS1302.h"
u8 DateTime[7];        //保存所讀取的日期時間數據
//-----------------------------------------------------------------
// 向DS1302寫入一字節(jié)
//-----------------------------------------------------------------
void Write_A_Byte_TO_DS1302(u8 x) {
        u8 i;
        for(i=0x01;i!=0x00;i<<=1){IO=x&i;SCLK=1;SCLK=0;}

}
//-----------------------------------------------------------------
// 從DS1302讀取一字節(jié)
//-----------------------------------------------------------------
u8 Get_A_Byte_FROM_DS1302() {
        u8 i,dat=0x00;
        for(i=0x01;i!=0x00;i<<=1)
        { if(IO) dat|= i; SCLK=1;SCLK=0;}
        return dat;//返回所讀取的BCD碼
        //將BCD碼轉換為十進制數返回時,使用下面的語句之一
        //return dat/16*10+dat%16;
        //return (dat>>4)*10+(dat&0x0F);
        //注意使用不同的編碼返回時,主程序中的格式化日期時間函數Format_DateTime要使用不同的語句進行分解
}
//-----------------------------------------------------------------
// 從DS1302指定位置讀取數據
//-----------------------------------------------------------------
u8 Read_Data(u8 addr) {
        u8 dat;
        RST=0;SCLK=0;RST=1;
        Write_A_Byte_TO_DS1302(addr);
        dat=Get_A_Byte_FROM_DS1302();
        SCLK=1;RST=0;
        return dat;
}
//-----------------------------------------------------------------
// 讀取當前日期時間
//-----------------------------------------------------------------
void GetDateTime() {
        u8 i,addr=0x81;
        for(i=0;i<7;i++,addr+=2) DateTime[i ]=Read_Data(addr);

}

DS1302的驅動
回復

使用道具 舉報

9#
ID:1141550 發(fā)表于 2024-12-26 20:11 | 只看該作者
樓上給程序的,受我一聲義父
回復

使用道具 舉報

10#
ID:1141550 發(fā)表于 2024-12-27 15:21 | 只看該作者

老哥,還是用不了啊你這程序
回復

使用道具 舉報

11#
ID:712097 發(fā)表于 2024-12-28 10:24 | 只看該作者
本帖最后由 chxelc 于 2024-12-28 11:48 編輯

純手工堆砌代碼,親測可用。
01 帶日歷時鐘及溫度顯示的電子萬年歷.rar (94.12 KB, 下載次數: 0)
回復

使用道具 舉報

12#
ID:437129 發(fā)表于 2025-1-3 13:18 | 只看該作者
謝謝前面幾位老師的分享!
樓上老師的程序可以正常顯示當前年、月、日、時、分、秒、星期、溫度,無調節(jié)功能。
回復

使用道具 舉報

13#
ID:641358 發(fā)表于 2025-1-8 15:24 | 只看該作者
你這還少了農歷顯示。2020年期間,放假無事,在家改裝過兩臺電子萬年歷。一臺因芯片損壞,一臺因顯示不過2020年。都用AT89S52作核心。能顯示陽歷、農歷、星期、時間、溫度。手工連了很多線,有的是漆包線、有的是塑料線,裁了一塊小面包板,焊上所示需元件,數碼管用的原機的。
回復

使用道具 舉報

14#
ID:641358 發(fā)表于 2025-1-24 21:29 | 只看該作者
我用proteus仿真TC72,在讀寫數據時,據資料介紹SCK(時鐘)先高后低,我寫成這樣卻不能讀出溫度數,而將其寫成先低后高時才能讀出溫度數,且讀寫都要如此才行。
SCK=1;
SCK=0;
這樣不能讀出溫度數。
SCK=0;
SCK=1;
這樣才能讀出溫度數來。
這是為什么?
還有就是,讀取溫度數時,如果TC72溫度設置成正數,讀出的數是正確的,而如果把TC72溫度設置成負數,如果設置的溫度數是負整數,那讀出的數正常,但有小數時一般讀出數會小一度。如-15.8,會讀出顯示為-16.25。這又是為什么。說明一下,我將小數點后加成了兩位。

無標題.png (168.44 KB, 下載次數: 0)

無標題.png
回復

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表