找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5651|回复: 1
收起左侧

一个简单的温度记录仪制作(51单片机开发板+部分源程序)

[复制链接]
ID:407089 发表于 2020-2-27 14:31 | 显示全部楼层 |阅读模式
本帖最后由 brew9 于 2020-2-27 14:40 编辑

这里分享一个基于开发板的简温度记录系统,所有模块均为板载。
以下为实物等图片:
2020-02-27_142005.png

2020-02-27_142810.png
2020-02-27_142706.png
2020-02-27_130748.png

  1. /*
  2.    这是一个基于开发板的简易的温度记录系统,所有模块均为板载。
  3.    
  4.    用数码管显示温度和时间;
  5.    用时钟模块提供时基;
  6.    用24C02保存温度数据;
  7.    用蜂鸣器做操作提示;
  8.    用串口输出数据到电脑。

  9.    Key_1启动温度记录,Key_2输出温度数据。

  10.    注:如果没有时钟模块也可以用单片机定时器计时,不过计时精度要差很多。
  11. */

  12. #include "config.h"
  13. #include "timer.h"
  14. #include "ds18b20.h"
  15. #include "ds1302.h"
  16. #include "i2c.h"

  17. uint8 timer;        //定时器计数
  18. uint8 n = 0;        //24c02内存位置变量
  19. int16 temp;        //温度变量

  20. //共阴数码管0-9编码和位码
  21. uchar code seg_tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  22. uchar code bit_tab[] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};

  23. //用于保存数字对应数码管编码的数组
  24. uchar num_code[8] = {0};

  25. //启动记录和改变延时的位变量
  26. bit starting,bF;

  27. //保存当前时间的结构体
  28. struct sTime cTime;

  29. //串口通讯初始化
  30. void T_U_init()
  31. {
  32.         PCON = 0;        //正常波特率(不翻倍)
  33.         TMOD = 0X21;         //T0工作方式1,T1工作方式2
  34.         TH0 = 0xdc;
  35.         TL0 = 0x00;         //T0初值,10ms溢出
  36.         TH1 = 0xfd;
  37.         TL1 = 0xfd;        //设置波特率9600
  38.         IE = 0x82;        //打开总中断、T0中断。禁止T1、串口中断
  39.         SCON = 0x40;        //串口工作方式1
  40.         TCON = 0x50;        //启动定时器0、1
  41. }

  42. //拆分浮点数到num_code数组
  43. void float2code(float fnum)
  44. {
  45.         uint8 i = 0;
  46.         uint8 len, point_pos;
  47.         uchar str[8];

  48.         TI = 1;
  49.         sprintf(str, "%.1f", fnum*0.0625);
  50.         TI = 0;
  51.         len = strlen(str);
  52.         if (len>8) return;
  53.         point_pos = len - 2;
  54.         
  55.         //拆分整数部分
  56.         for (i=0; i<point_pos; i++)
  57.         {
  58.                 if (i < (point_pos-1)){
  59.                         if (str[i]=='-'){
  60.                                 num_code[i] = 0x40;
  61.                         }else{
  62.                                 num_code[i] = seg_tab[str[i]-0x30];
  63.                         }        
  64.                 }else{
  65.                         //小数点左边的数加上小数点编码
  66.                         num_code[i] = seg_tab[str[i]-0x30] + 0x80;        
  67.                 }
  68.         }
  69.         //拆分小数部分
  70.         for (i=point_pos; i<len-1; i++)
  71.         {
  72.                 num_code[i] = seg_tab[str[i+1]-0x30];
  73.         }
  74. }

  75. //刷新温度
  76. void ref_temp()
  77. {
  78.         static int16 backup = 0;
  79.         
  80.         DS18B20_get_temp(&temp);                //获取当前温度值
  81.         DS18B20_start();                        //启动下一次转换
  82.         
  83.         //温度无改变则不处理,减少计算量
  84.         if (backup!=temp)
  85.         {
  86.                 float2code(temp);                //刷新上次温度值
  87.                 backup = temp;
  88.         }
  89. }

  90. //刷新时间
  91. void ref_time()
  92. {
  93.          DS1302_get_time(&cTime);
  94.          //获取时间后把数据拆分到显示数组中
  95.          num_code[4] = seg_tab[BCD2Dat(cTime.min) / 10];
  96.          num_code[5] = seg_tab[BCD2Dat(cTime.min) % 10];
  97.          num_code[6] = seg_tab[BCD2Dat(cTime.sec) / 10];
  98.          num_code[7] = seg_tab[BCD2Dat(cTime.sec) % 10];
  99. }

  100. //8位数码管显示函数
  101. void display()
  102. {
  103.         uint8 j = 0;
  104.         for (j=0; j<8; j++)
  105.         {
  106.                 bit_sel = 1;
  107.                 DATA = bit_tab[j];
  108.                 bit_sel = 0;
  109.                 seg_sel = 1;
  110.                 DATA = num_code[j];
  111.                 delay_ms(1);
  112.                 DATA = 0x00;
  113.                 seg_sel = 0;
  114.         }
  115. }
  116. //保存当前温度
  117. void save_temp(int16 t,uint16 n)
  118. {
  119.         bit isACK1,isACK2;
  120.         uint8 tmp;

  121.         //将16位温度数据拆分为低8位和高8位,写入24c02中
  122.         tmp = t;
  123.         isACK1 = AT24C02_write_byte(n, tmp);

  124.         delay_ms(50);

  125.         tmp = t>>8;
  126.         isACK2 = AT24C02_write_byte(n+1, tmp);
  127.         
  128.         //记录成功则喇叭响一下
  129.         if (isACK1 && isACK2)
  130.         {
  131.                 beep = 0;
  132.                 delay_ms(10);
  133.                 beep = 1;
  134.         }
  135. }
  136. //串口输出保存的温度
  137. void sent_temp()
  138. {
  139.         uchar tmp,str[6];
  140.         uint16 j;
  141.         int16 t;
  142.         for(j=0; j<255; j=j+2)
  143.         {
  144.                 tmp = AT24C02_read_byte(j+1);
  145.                
  146.                 //初发读取24c02加大延时,之后减少延时加快处理速度
  147.                 //如果不进行此处理,则可能发生数据丢失
  148.                 if(bF)
  149.                 {        
  150.                         delay_ms(10);
  151.                 }else{
  152.                         delay_ms(1000);
  153.                         bF=1;
  154.                 }
  155.                
  156.                 //重组16位温度int数据
  157.                 t = tmp << 8;

  158.                 tmp = AT24C02_read_byte(j);
  159.                 delay_ms(10);
  160.                 t |= tmp;

  161.                 //数据转换及串口输出
  162.                 TI = 1;
  163.                 sprintf(str, "%.2f", t*0.0625);
  164.                 printf("%s \n",str);
  165.                 while(!TI);
  166.                 TI = 0;
  167.         }
  168. }

  169. void main()
  170. {
  171.         uchar s,ts=1;        //ts用于保存当前秒数,且必须赋值一个不等于0的值
  172.                
  173.         T_U_init();

  174.         while(1)
  175.         {
  176.                 display();

  177.                 //检测时基数据,定时记录温度
  178.                 if(starting)
  179.                 {
  180.                         s = BCD2Dat(cTime.sec);
  181.                         //只有当秒数变化时才进入判断步骤
  182.                         //此处每2秒记录一次(可加入ds1302的分钟数据加大间隔时间)
  183.                         if(s % 2 == 0 && s != ts)
  184.                         {
  185.                                 save_temp(temp,n);
  186.                                 n=n+2;
  187.                                 
  188.                                 //n初值为0,第一次记录数据后不再为0,所以不会进入结束。
  189.                                 //当n=254时,记录最后一次数据,再加2后n为0,结束。
  190.                                 if(n == 0)
  191.                                 {
  192.                                         starting = 0;

  193.                                         beep = 0;
  194.                                         delay_ms(10);
  195.                                         beep = 1;
  196.                                 }
  197.                         }
  198.                         ts = s;
  199.                 }
  200.                
  201.                 //按键设置
  202.                 if (KEY_1==0)
  203.                 {
  204.                         delay_ms(10);
  205.                         if (KEY_1==0)
  206.                         {
  207.                                 //初始化1302时把其分和秒对应内存清零
  208.                                 DS1302_init();
  209.                                 starting = 1;
  210.                         }
  211.                         while(!KEY_1);
  212.                 }
  213.                 if (KEY_2==0)
  214.                 {
  215.                         delay_ms(10);
  216.                         if (KEY_2==0)
  217.                         {
  218.                                 sent_temp();
  219.                         }
  220.                         while(!KEY_2);
  221.                 }
  222.         }
  223. }

  224. void timer0_service(void) interrupt 1
  225. {
  226.         TH0 = 0xdc;
  227.         TL0 = 0x00;
  228.         timer++;
  229.         if (timer == 100)
  230.         {
  231.                 timer = 0;
  232.                 ref_temp();
  233.                 ref_time();
  234.         }

  235. }
复制代码



回复

使用道具 举报

ID:27254 发表于 2021-3-4 08:10 | 显示全部楼层
楼主你好!能否把全部代码发上来参考一下,谢谢!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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