找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4779|回复: 7
收起左侧

程序求补全 带日历时钟及TC72温度显示的单片机电子万年历仿真与源码设计

[复制链接]
ID:304109 发表于 2018-4-8 23:47 | 显示全部楼层 |阅读模式
分享一个单片机电子万年历
带日历时钟TC72温度传感器显示,是用的74hc595芯片驱动的数码管.

完成本例设计后加入日期时间调节功能

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png 0.png

单片机源程序如下:
  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字节),黑屏段码,负号段码
  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字节数据串行输入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        //温度低字节
  13. #define TC72_TEMP_MSB        0x02        //温度高字节
  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];                        //两字节温度值原始数据
  21. extern void delay_ms(INT16U x);
  22. //-----------------------------------------------------------------
  23. // 从当前地址读取一字节数据(模拟方式)
  24. //-----------------------------------------------------------------
  25. INT8U _ReadByte()
  26. {


  27. }

  28. //-----------------------------------------------------------------
  29. // 向当前地址写入一字节数据(模拟方式)
  30. //-----------------------------------------------------------------
  31. void _WriteByte(INT8U dat)
  32. {


  33. }

  34. //-----------------------------------------------------------------
  35. // 向TC72写入两字节(地址,数据)(模拟方式)
  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读取两字节温度数据并转换为浮点温度值
  49. //-----------------------------------------------------------------
  50. float Read_TC72_Temperature()
  51. {


  52. }
复制代码

0.png 0.png

所有资料51hei提供下载:
带日历时钟及温度显示的电子万年历.zip (42.93 KB, 下载次数: 71)

评分

参与人数 1黑币 +5 收起 理由
沐渊 + 5 赞一个!

查看全部评分

回复

使用道具 举报

ID:608971 发表于 2019-9-23 20:48 | 显示全部楼层
你这程序为什么都是空白
回复

使用道具 举报

ID:752705 发表于 2020-5-17 07:54 | 显示全部楼层
提示:楼主删掉了功能函数内的所有代码,只提供的keil工程的框架和HEX 文件。
回复

使用道具 举报

ID:1111795 发表于 2024-2-29 15:24 | 显示全部楼层
感谢分享,学到了很多,但是打不开仿真图是为什么呀
回复

使用道具 举报

ID:453974 发表于 2024-3-1 10:02 | 显示全部楼层
xiaxiake 发表于 2024-2-29 15:24
感谢分享,学到了很多,但是打不开仿真图是为什么呀

一般打不开都是因为软件版本不对
回复

使用道具 举报

ID:453974 发表于 2024-3-1 10:03 | 显示全部楼层
你这不是求补全,你这是求重做吧
回复

使用道具 举报

ID:712097 发表于 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字节),黑屏段码,负号段码
  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字节数据串行输入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        //温度低字节
#define TC72_TEMP_MSB        0x02        //温度高字节
#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];                                //两字节温度值原始数据
extern void delay_ms(u16 x);
//-----------------------------------------------------------------
// 从当前地址读取一字节数据(模拟方式)
//-----------------------------------------------------------------
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;                                         //返回读取的字节
}
//-----------------------------------------------------------------
// 向当前地址写入一字节数据(模拟方式)
//-----------------------------------------------------------------
void _WriteByte(u8 dat) {
        u8 i;
        for(i = 0; i < 8; i++) {        //串行写入8位数据
                dat <<= 1; SDI = CY;                //dat左移位,高位被移入CY,发送高位
                SCK = 0; SCK = 1;                                //时钟上升沿向存储器写入数据
        }
}
//-----------------------------------------------------------------
// 向TC72写入两字节(地址,数据)(模拟方式)
//-----------------------------------------------------------------
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读取两字节温度数据并转换为浮点温度值
//-----------------------------------------------------------------
float Read_TC72_Temperature() {
        Config_TC72();
        delay_ms(50);
        CE = 1;                                                //SPI_EN();
        //发送读温度高字节命令
        _WriteByte(TC72_TEMP_MSB);        //SPI_SendData(TC72_TEMP_MSB);
        //连续读取两字节(连续读取时先得到的是高字节,后得到的是低字节)
        Temp_Value[1] = _ReadByte();        //SPI_SendData(0xFF);//读高字节
        Temp_Value[0] = _ReadByte();        //SPI_SendData(0xFF);//读低字节
        CE = 0;                                                //SPI_DI();
        //还可以使用以下单字节读取的方法
        //SPI_EN();
        //SPI_SendData(TC72_TEMP_LSB);        //发送读温度低字节命令
        //T[0] = SPI_SendData(0xFF);        //读LSB
        //SPI_DI();
        //SPI_EN();
        //SPI_SendData(TC72_TEMP_MSB);        //发送读温度高字节命令
        //T[1] = SPI_SendData(0xFF);        //读MSB
        //SPI_DI();
        return (int)(((int)((Temp_Value[1]<<8)|Temp_Value[0]))>>6) * 0.25;
}


回复

使用道具 举报

ID:712097 发表于 2024-3-2 11:38 | 显示全部楼层
//-------------------------- DS1302.c -----------------------------
//  名称:1602字符液晶(HD44780)工作于4位模式显示DS1302时钟
//-----------------------------------------------------------------
#include "DS1302.h"
u8 DateTime[7];        //保存所读取的日期时间数据
//-----------------------------------------------------------------
// 向DS1302写入一字节
//-----------------------------------------------------------------
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读取一字节
//-----------------------------------------------------------------
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=Read_Data(addr);

}
DS1302的驱动
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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