找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1740|回复: 0
打印 上一主题 下一主题
收起左侧

一个简单的单片机温度报警系统程序

[复制链接]
跳转到指定楼层
楼主


单片机源程序如下:
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #include <stdio.h>

  4. typedef unsigned int uint;
  5. typedef unsigned char uchar;

  6. /********************引脚定义********************/
  7. #define LCD_DATA P0
  8. sbit LCD_RS = P2^0;
  9. sbit LCD_RW = P2^1;
  10. sbit LCD_EN = P2^2;
  11. sbit KEY_1 = P1^7;                        //功能键
  12. sbit KEY_2 = P1^4;                        //减少键
  13. sbit KEY_3 = P1^2;                        //增加按键
  14. sbit DS18B20 = P2^6;
  15. /************************************************/

  16. /********************全局变量********************/
  17. #define KeyTime 200                                        //200 * 1ms = 200ms
  18. #define DispTime 100                                //100 * 1ms = 100ms
  19. #define UartTime 150                                //150 * 1ms = 150ms
  20. volatile uchar KEY_1ms = 0;
  21. volatile uchar Disp_1ms = 0;
  22. volatile uchar Uart_1ms = 0;
  23. volatile uchar Menu = 0;                //0(显示当前温度), 1(设置最低温度), 2(设置最低温度)
  24. volatile int MaxTemp = 40;
  25. volatile int MinTemp = -10;
  26. volatile float Temperature = 0;
  27. /************************************************/

  28. /********************函数声明********************/
  29. void Delay_us(uchar x);
  30. void Delay_ms(uchar x);
  31. void Timer0Init(void);
  32. void KEY_Proc(void);
  33. void DispTemp(void);
  34. void LCD_WriteCommand(uchar com);
  35. void LCD_WriteData(uchar dat);
  36. void LCD_Init(void);
  37. void LCD_Show_Home(void);
  38. void LCD_Show_Setting(void);
  39. void DS18B20_Init(void);
  40. uchar DS18B20_ReadByte(void);
  41. void DS18B20_WriteByte(uchar dat);
  42. float DS18B20_ReadTmp(void);
  43. void UartInit(void);
  44. void Uart_Proc(void);
  45. /************************************************/

  46. /*********************主函数*********************/
  47. int main(void)
  48. {
  49.         LCD_Init();
  50.         Temperature = DS18B20_ReadTmp();
  51.         Delay_ms(200);
  52.         Delay_ms(200);
  53.         UartInit();
  54.         Timer0Init();
  55.         LCD_Show_Home();
  56.         while(1)
  57.         {
  58.                 DispTemp();
  59.                 KEY_Proc();
  60.                 Uart_Proc();
  61.         }
  62. }
  63. /************************************************/

  64. /*****************延时函数******************/
  65. void Delay_us(uchar x)                //@12.000MHz
  66. {
  67.         while(x--)
  68.         {
  69.                 _nop_();
  70.                 _nop_();
  71.                 _nop_();
  72.                 _nop_();
  73.         }
  74. }

  75. void Delay_ms(uchar x)                //@12.000MHz
  76. {
  77.         uchar i, j;
  78.         while(x--)
  79.         {
  80.                 _nop_();
  81.                 _nop_();
  82.                 i = 12;
  83.                 j = 169;
  84.                 do
  85.                 {
  86.                         while (--j);
  87.                 } while (--i);
  88.         }
  89. }
  90. /************************************************/

  91. /*******************计数器0模块*******************/
  92. void Timer0Init(void)
  93. {
  94.         TMOD |= 0x01;        //选择为定时器0模式,工作方式1,仅用TR0打开启动。
  95.         TH0 = 0xFC;                //给定时器赋初值,定时1ms
  96.         TL0 = 0x18;        
  97.         ET0 = 1;                        //打开定时器0中断允许
  98.         EA = 1;                                //打开总中断
  99.         TR0 = 1;                        //打开定时器
  100. }

  101. void Timer0(void) interrupt 1
  102. {
  103.         TH0 = 0xFC;                //给定时器赋初值,定时1ms
  104.         TL0 = 0x18;
  105.         KEY_1ms ++;
  106.         Disp_1ms ++;
  107.         Uart_1ms ++;
  108. }
  109. /************************************************/

  110. /*****************按键模块******************/
  111. void KEY_Proc(void)
  112. {
  113.         if (KEY_1ms >= KeyTime)
  114.         {
  115.                 KEY_1ms = 0;
  116.                 if (KEY_1 == 0)
  117.                 {
  118.                         Menu ++;
  119.                         LCD_Show_Setting();
  120.                         if (Menu == 3)
  121.                         {
  122.                                 Menu = 0;
  123.                                 LCD_Show_Home();
  124.                         }
  125.                 }
  126.                 else if (KEY_2 == 0)
  127.                 {
  128.                         if (Menu == 1)
  129.                         {
  130.                                 MinTemp --;
  131.                         }
  132.                         else if (Menu == 2)
  133.                         {
  134.                                 MaxTemp --;
  135.                                 if ((MaxTemp - 1) == MinTemp)
  136.                                 {
  137.                                         MaxTemp ++;
  138.                                 }
  139.                         }
  140.                 }
  141.                 else if (KEY_3 == 0)
  142.                 {
  143.                         if (Menu == 1)
  144.                         {
  145.                                 MinTemp ++;
  146.                                 if ((MaxTemp - 1) == MinTemp)
  147.                                 {
  148.                                         MinTemp --;
  149.                                 }
  150.                         }
  151.                         else if (Menu == 2)
  152.                         {
  153.                                 MaxTemp ++;
  154.                         }
  155.                 }
  156.         }
  157. }
  158. /************************************************/

  159. /*****************温度显示函数******************/
  160. void DispTemp(void)
  161. {
  162.         if (Disp_1ms >= DispTime)
  163.         {
  164.                 uchar i;
  165.                 uchar Disp[6] = "      ";
  166.                 uchar Disp1[4] = "    ";
  167.                 Disp_1ms = 0;
  168.                 if (Menu == 0)
  169.                 {
  170.                         LCD_WriteCommand(0xC7);
  171.                         Temperature = DS18B20_ReadTmp();
  172.                         sprintf(Disp, "%.1f", Temperature);
  173.                         for(i=0; i<6; i++)
  174.                         {
  175.                                 LCD_WriteData(Disp[i]);
  176.                         }
  177.                 }
  178.                 else if (Menu == 1)
  179.                 {
  180.                         LCD_WriteCommand(0x80);
  181.                         LCD_WriteData('>');
  182.                         LCD_WriteCommand(0xC0);
  183.                         LCD_WriteData(' ');
  184.                         LCD_WriteCommand(0x8B);
  185.                         sprintf(Disp, "%d", MinTemp);
  186.                         for(i=0; i<4; i++)
  187.                         {
  188.                                 LCD_WriteData(Disp[i]);
  189.                         }
  190.                 }
  191.                 else if (Menu == 2)
  192.                 {
  193.                         LCD_WriteCommand(0x80);
  194.                         LCD_WriteData(' ');
  195.                         LCD_WriteCommand(0xC0);
  196.                         LCD_WriteData('>');
  197.                         LCD_WriteCommand(0xCB);
  198.                         sprintf(Disp, "%d", MaxTemp);
  199.                         for(i=0; i<4; i++)
  200.                         {
  201.                                 LCD_WriteData(Disp[i]);
  202.                         }
  203.                 }
  204.         }
  205. }
  206. /************************************************/

  207. /*******************LCD模块*******************/
  208. void LCD_WriteCommand(uchar com)
  209. {
  210.         LCD_EN = 0;     //使能
  211.         LCD_RS = 0;                  //选择发送命令
  212.         LCD_RW = 0;                   //选择写入
  213.         
  214.         LCD_DATA = com; //放入命令
  215.         Delay_us(1);                //等待数据稳定

  216.         LCD_EN = 1;            //写入时序
  217.         Delay_us(5);          //保持时间
  218.         LCD_EN = 0;
  219. }
  220.            
  221.            
  222. void LCD_WriteData(uchar dat)
  223. {
  224.         LCD_EN = 0;                        //使能清零
  225.         LCD_RS = 1;                        //选择输入数据
  226.         LCD_RW = 0;                        //选择写入

  227.         LCD_DATA = dat; //写入数据
  228.         Delay_us(1);

  229.         LCD_EN = 1;           //写入时序
  230.         Delay_us(5);          //保持时间
  231.         LCD_EN = 0;
  232. }

  233. void LCD_Init(void)
  234. {
  235.          LCD_WriteCommand(0x38);  //开显示
  236.         LCD_WriteCommand(0x0C);  //开显示不显示光标
  237.         LCD_WriteCommand(0x06);  //写一个指针加1
  238.         LCD_WriteCommand(0x01);  //清屏
  239.         LCD_WriteCommand(0x80);  //设置数据指针起点
  240. }

  241. void LCD_Show_Home(void)
  242. {
  243.         uchar i;
  244.         uchar Disp[16];
  245.         LCD_WriteCommand(0x80);
  246.         sprintf(Disp, " Current Temp:  ");
  247.         for(i=0; i<16; i++)
  248.         {
  249.                 LCD_WriteData(Disp[i]);
  250.         }
  251.         LCD_WriteCommand(0xC0);
  252.         sprintf(Disp, " Temp:        C ");
  253.         for(i=0; i<16; i++)
  254.         {
  255.                 LCD_WriteData(Disp[i]);
  256.         }
  257.         LCD_WriteCommand(0xCD);
  258.         LCD_WriteData(0xDF);
  259. }

  260. void LCD_Show_Setting(void)
  261. {
  262.         uchar i;
  263.         uchar Disp[16];
  264.         LCD_WriteCommand(0x80);
  265.         sprintf(Disp, " Min Temp: %d   ", MinTemp);
  266.         for(i=0; i<16; i++)
  267.         {
  268.                 LCD_WriteData(Disp[i]);
  269.         }
  270.         LCD_WriteCommand(0xC0);
  271.         sprintf(Disp, " Max Temp: %d   ", MaxTemp);
  272.         for(i=0; i<16; i++)
  273.         {
  274.                 LCD_WriteData(Disp[i]);
  275.         }
  276. }
  277. /************************************************/

  278. /*******************DS18B20模块*******************/
  279. void DS18B20_Init(void)
  280. {
  281.         DS18B20 = 1;
  282.         Delay_us(1);
  283.         DS18B20 = 0;
  284.         Delay_us(40);
  285.         DS18B20 = 1;
  286.         Delay_us(11);
  287. }

  288. uchar DS18B20_ReadByte(void)
  289. {
  290.          uchar i,dat=0;
  291.         DS18B20 = 1;
  292.         for(i=0;i<8;i++)
  293.         {
  294.                 DS18B20 = 1;
  295.                 Delay_us(1);
  296.                  DS18B20 = 0;
  297.                 dat >>= 1;
  298.                 DS18B20 = 1;
  299.                 if(DS18B20)
  300.                         dat |= 0X80;
  301.                 Delay_us(2);
  302.         }
  303.         return dat;
  304. }

  305. void DS18B20_WriteByte(uchar dat)
  306. {
  307.          uchar i;
  308.         for(i=0;i<8;i++)
  309.         {
  310.                  DS18B20 = 0;
  311.                 DS18B20 = dat& 0x01;
  312.                 Delay_us(2);
  313.                 DS18B20 = 1;
  314.                 dat >>= 1;
  315.         }
  316.         Delay_us(2);
  317. }

  318. float DS18B20_ReadTmp(void)
  319. {
  320.         float Temp;
  321.         uint Temp_Value[]={0, 0};
  322.         DS18B20_Init();
  323.         DS18B20_WriteByte(0xCC);
  324.         DS18B20_WriteByte(0x44);
  325.         Delay_us(20);
  326.         DS18B20_Init();
  327.         DS18B20_WriteByte(0xCC);
  328.         DS18B20_WriteByte(0xBE);
  329.         Temp_Value[0] = DS18B20_ReadByte();
  330.         Temp_Value[1] = DS18B20_ReadByte();
  331.         if((Temp_Value[1]&0xF8)==0xF8)
  332.         {
  333.                 Temp = -1 * (128 - 0.0625 * (Temp_Value[0] | ((Temp_Value[1]&0x07)<<8)));
  334.         }
  335.         else
  336.         {
  337.                 Temp = 0.0625 * (Temp_Value[0] | ((Temp_Value[1]&0x07)<<8));
  338.         }
  339.         return Temp;
  340. }
  341. /************************************************/

  342. /*******************串口通信模块*******************/
  343. void UartInit(void)
  344. {
  345.         SCON = 0x50;                //设置为工作方式1
  346.         TMOD |= 0x20;                //设置计数器工作方式2
  347.         PCON = 0x80;                //波特率加倍
  348.         TH1=0xF3;                                //计数器初始值设置,注意波特率是4800的
  349.         TL1=0xF3;
  350. //        ES=1;                                                //打开接收中断
  351. //        EA=1;                                                //打开总中断
  352.         TR1=1;                                        //打开计数器
  353. }

  354. void Uart_Proc(void)
  355. {
  356. //        if (Uart_1ms >= UartTime)
  357. //        {
  358. //                Uart_1ms = 0;
  359.                 if (Temperature < MinTemp)
  360.                 {
  361.                         SBUF = 'A';
  362.                         while(!TI);
  363.                         TI = 0;
  364.                 }
  365.                 else if (Temperature > MaxTemp)
  366.                 {
  367.                         SBUF = 'B';
  368.                         while(!TI);
  369.                         TI = 0;
  370.                 }
  371.                 else
  372.                 {
  373.                         SBUF = 'O';
  374.                         while(!TI);
  375.                         TI = 0;
  376.                 }
  377. //        }
  378. }
复制代码
Proteus仿真工程下载: TemperatureMonitor-master.rar (223.29 KB, 下载次数: 31)

评分

参与人数 1黑币 +20 收起 理由
admin + 20 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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