找回密码
 立即注册

QQ登录

只需一步,快速开始

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

模拟粮仓温度检测报警系统设计

[复制链接]
跳转到指定楼层
楼主
这是我们的免试题目,有仿真原理图,源代码没希望能给大家提供帮助


仿真文件下载:
模拟粮仓温度检测报警系统-董晓臣.rar (115.09 KB, 下载次数: 58)

源程序:
  1. #include <reg52.h>
  2. #include<intrins.h>
  3. #include <math.h>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. sbit RW = P2^1;          //定义LCD的读、写选择端
  7. sbit RS = P2^0;           //定义LCD的数据、命令选择端
  8. sbit EN = P2^2;                 //定义LCD的使能信号端
  9. sbit DS = P3^5;                 //定义DS18B20的IO口





  10. sbit L=P1^3;                 //绿灯
  11. sbit H=P1^4;                 //红灯
  12. sbit LS=P3^4;                 //蜂鸣器
  13. sbit k1=P2^7;                 //显示64位的ROM
  14. sbit k2=P2^6;                 //显示当前温度
  15. sbit k3=P2^3;                 //显示温度上限及下线,并支持调节
  16. sbit k4=P2^4;                 //        上限加
  17. sbit k5=P2^5;                  //        下限减
  18. uchar k=2;                         //当前温度显示标志位
  19. uchar table0[] = " Current Temp : ";         //当前温度
  20. uchar table1[] = " -- ROM CODE -- ";         //显示DS18B20的ROM
  21. uchar table2[] = "ALARM TEMP Hi Lo";         //显示上下限温度
  22. uchar table3[] = "Hi:    Lo:      ";
  23. uchar table4[] = {0,0,0,0,0,0,0,0};
  24. uchar tempHL[] = { 40, 10};                                 //上下限温度的初始值                                                                                   
  25. void delayms(uint ms)     //延时函数1
  26. {
  27.     uint i;
  28.     while(ms--)
  29.         {
  30.                 for(i=0;i<120;i++);
  31.         }
  32. }



  33. void writecom(uchar com)  //写地址,也就是显示的数据的位置
  34. {
  35.         RS = 0;                 
  36.         P0 = com;
  37.         EN = 1;
  38.         delayms(1);
  39.         EN = 0;
  40. }
  41. void writedata(uchar dat) //写数据,也就是显示的数据
  42. {
  43.         RS = 1;
  44.         P0 = dat;
  45.         EN = 1;
  46.         delayms(1);
  47.         EN = 0;
  48. }
  49. void init()                   //LCD初始化
  50. {
  51.         RW = 0;
  52.         writecom(0x38);          //16*2显示,5*7点阵
  53.         writecom(0x0c);
  54.         writecom(0x06);
  55.         writecom(0x01);   //清除LCD的显示内容
  56. }

  57. void writestring(uchar * str, uchar length)           //写数据的过度函数。length:长度
  58. {
  59.     uchar i;
  60.     for(i = 0; i < length; i++)
  61.     {
  62.          writedata(str[i]);
  63.      }
  64. }
  65. void delay(uint num)        //延时函数
  66. {
  67.   while( --num );
  68. }

  69. DSinit(void)        //初始化ds1820  
  70. {  
  71.      DS= 1;      //DS复位
  72.      delay(8);    //稍做延时
  73.      DS= 0;      //将DS拉低
  74.      delay(90);   //精确延时 大于 480u
  75.      DS= 1;       //拉高总线
  76.      delay(110);
  77.      DS= 1;

  78. }

  79. uchar read_bit(void)     //读一位(bit)
  80. {
  81. uchar i;
  82. DS= 0;                      //将DS拉低开始读时间隙
  83. DS= 1;                         // then return high
  84. for (i=0; i<3; i++);         // 延时15μs
  85. return(DS);                         // 返回 DS线上的电平值
  86. }

  87. uchar readbyte()        // 读一个字节  
  88. {
  89. uchar i = 0;
  90. uchar dat = 0;
  91. for (i=0;i<8;i++)
  92. {                                  // 读取字节,每次读取一个字节
  93. if(read_bit()) dat|=0x01<<i;           // 然后将其左移
  94.     delay(4);
  95.   }
  96.     return (dat);
  97. }

  98. void write_bit(char bitval)       //写一位  
  99. {
  100. DS= 0;                                        // 将DS拉低开始写时间隙
  101. if(bitval==1) DS=1;          // 如果写1,DS返回高电平
  102. delay(5);                                       // 在时间隙内保持电平值,
  103. DS= 1;                      // delay函数每次循环延时16μs,因此delay(5) = 104μs
  104. }        

  105. void writebyte(uchar dat)  //写一个字节
  106. {
  107.   uchar i = 0;
  108.   uchar temp;
  109.    for (i=0; i<8; i++)         // 写入字节, 每次写入一位
  110.    {

  111.    temp = dat>>i;                 
  112.    temp &= 0x01;                 
  113.    write_bit(temp);

  114.   }
  115.   delay(5);
  116. }         
  117. void sendchangecmd()           //DS18B20?开始获取温度并转换
  118. {
  119.     DSinit();                         //DS18B20复位
  120.     delayms(1);                       
  121.     writebyte(0xcc);           //写跳过读ROM指令
  122.     writebyte(0x44);           //写温度转换指令
  123. }

  124. void sendreadcmd()                   //读取寄存器中存储的温度数据
  125. {
  126.     DSinit();                           //DS18B20复位
  127.     delayms(1);
  128.     writebyte(0xcc);            //写跳过读ROM指令
  129.     writebyte(0xbe);            //读取暂存器的内容
  130. }         

  131. int gettmpvalue()
  132. {
  133.     uint tmpvalue;
  134.     float t;
  135.     uchar low, high;
  136.     sendreadcmd();                   //读取寄存器中存储的温度数据
  137.     low = readbyte();            //读取低八位
  138.     high = readbyte();           //读取高八位
  139.     tmpvalue = high;
  140.     tmpvalue <<= 8;                   //高八位左移八位
  141.     tmpvalue |= low;       //两个字节组合为1个字
  142.     t = tmpvalue * 0.0625 * 100;   //分辨率为0.0625,在此将值扩大100倍
  143.     return t;
  144. }

  145. void display(int v)            //显示子函数
  146. {
  147.     uchar i;
  148.     uchar datas[] = {0, 0, 0, 0, 0, 0, 0, 0};  //定义缓存数组datas
  149.     uint tmp = abs(v);                                                   //abs是求绝对值函数
  150.     datas[0] = tmp % 10000 / 1000;
  151.     datas[1] = tmp % 1000 / 100;
  152.     datas[2] = tmp % 100 / 10;
  153.     datas[3] = tmp % 10;
  154.         datas[4] = 80;                                                //空格的前30的ASCALL码
  155.         datas[5] = 175;                                                //温度符号的前30的ASCALL码
  156.         datas[6] = 19;                                                //C的前30的ASCALL码
  157.     writecom(0xc0+3);
  158.     if(v < 0)                                  //当V小于0则输出负号
  159.     {
  160.         writestring("- ", 2);
  161.    }
  162.     else
  163.     {
  164.        writestring("+ ", 2);          //当V大于0则输出正号
  165.     }
  166.     for(i = 0; i != 7; i++)
  167.     {
  168.         writedata('0'+datas[i]);   //显示温度
  169.         if(i == 1)
  170.         {
  171.            writedata('.');                  //显示温度的小数点
  172.         }
  173.     }

  174. }

  175. void Read_RomCord()                   //读取64位序列码
  176. {
  177.      unsigned char j;
  178.      DSinit();
  179.      writebyte(0x33);      // 读序列码的操作
  180.      for (j = 0; j < 8; j++)
  181.          {
  182.           table4[j] = readbyte();
  183.          }
  184. }

  185. void Disp_RomCode()                           //数据转换与显示
  186. {
  187.    uchar j,i;
  188.    writecom(0xc0);         //LCD第二行初始位置
  189.    for(j=0;j<8;j++)
  190.    {
  191.     i=((table4[j]&0xf0)>>4);
  192.     if(i>9)
  193.      { i=i+0x37;}
  194.     else{i=i+0x30;}         
  195.     writedata(i);        //高位数显示
  196.     i=(table4[j]&0x0f);
  197.     if(i>9)
  198.      {i=i+0x37;}
  199.     else {i=i+0x30;}         
  200.     writedata(i);        //低位数显示
  201.    }
  202. }

  203. void lcd_display()                 //按键扫描
  204. {
  205.   uchar i,m;
  206.   uchar hl[]={0, 0, 0, 0, 0};
  207.   if(k1 == 0) k = 1;
  208.   if(k2 == 0) k = 2;                                                                                                                                                                                          
  209.   if(k3 == 0) k = 3;
  210.   if(tempHL[0]<=gettmpvalue()/100)
  211.        delayms(100),LS=!LS,H=~H;
  212.   else
  213.        LS=1,H=1;
  214.   if(m==1)
  215. {
  216.           if(tempHL[1]>=gettmpvalue()/100)
  217.                delayms(100),LS=!LS,L=~L;
  218.           else
  219.                LS=1,L=1;
  220.   }
  221.   switch(k)
  222.   {
  223.         case 1:                                                       //显示64位的ROM
  224.                    writecom(0x01);
  225.                    writecom(0x80);
  226.                    writestring(table1, 16);
  227.                    Read_RomCord();           //读取64位序列码
  228.                    Disp_RomCode();                 //显示64位序列
  229.                    delayms(500);                         //温度转换时间需要750ms以上
  230.                    break;
  231.         case 2:                                                 //显示当前温度
  232.                    delayms(750);                         //温度转换时间需要750ms以上
  233.                    sendchangecmd();
  234.                    writecom(0x01);
  235.                    writecom(0x80);
  236.                    writestring(table0, 16);
  237.                    display(gettmpvalue());
  238.                    break;
  239.         case 3:                                                     //显示温度上限及下线,并支持调节
  240.                    writecom(0x80);
  241.                    writestring(table2, 16);
  242.                    writecom(0xC0);
  243.                    writestring(table3, 16);
  244.                    if(k4==0) {tempHL[0]++;if(m==1) tempHL[1]++;if(m==0){tempHL[1]--;if(tempHL[1]==0)m=1;}delayms(100);}
  245.                    if(k5==0) {tempHL[0]--;if(m==0) tempHL[1]++;if(m==1){tempHL[1]--;if(tempHL[1]==0)m=0;}delayms(100);}
  246.                    hl[0]=tempHL[0]/10;
  247.                    hl[1]=tempHL[0]%10;
  248.                    if(m==1) hl[2]=80;
  249.                    if(m==0) hl[2]=128;
  250.                    hl[3]=tempHL[1]/10;
  251.                    hl[4]=tempHL[1]%10;
  252.                    writecom(0xC0+4);
  253.                    for(i = 0; i != 2; i++)
  254.                     {
  255.                         writedata('0'+hl[i]);        //显示上限温度
  256.                          }
  257.                    writecom(0xC0+11);
  258.                    for(i = 2; i != 5; i++)
  259.                     {
  260.                         writedata('0'+hl[i]);         //显示下限温度
  261.                          }
  262.                    break;
  263.   }
  264. }
  265. void main()
  266. {
  267.     sendchangecmd();                        //读取寄存器中存储的温度数据
  268.     init();                                                //LCD初始化
  269.     writecom(0x80);                                //选择LCD第一行
  270.     writestring(table0, 16);        //显示当前温度的英文字母
  271.     while(1)
  272.     {
  273.         lcd_display();                         //扫描按键
  274.     }
  275. }
复制代码


评分

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

查看全部评分

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

使用道具 举报

沙发
ID:1 发表于 2016-12-6 17:00 | 只看该作者
你这个压缩包里面有程序啊.
回复

使用道具 举报

板凳
ID:154229 发表于 2016-12-12 20:24 | 只看该作者
好棒好棒!!!
回复

使用道具 举报

地板
ID:154229 发表于 2016-12-12 20:32 | 只看该作者
可是黑币不够 = =
回复

使用道具 举报

5#
ID:154229 发表于 2016-12-12 20:54 | 只看该作者
请问又没有什么元件介绍什么的啊。谢谢拉
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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