找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机数字温度控制器的设计

[复制链接]
跳转到指定楼层
楼主
硬件 :DS18b20 at89c51 lcd1602
三个按键 key1,key2,key3 可分别实现加一,减一 ,温度上/下限的选择。
仿真图

单片机源程序如下:
  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. uchar code disp[]="0123456789";//定义字符数组显示数字
  5. uchar code disp2[]="Temp:";//说明显示的是温度
  6. uchar code disp3[]={0xdf,'C'};//温度单位
  7. uchar code disp4[]=" L:     H:     ";//温度上下限显示
  8. sbit lcden=P2^1;//液晶使能端
  9. sbit lcdrs=P2^0;//液晶命令/数据控制端
  10. sbit ds=P1^0;//DS18B20温度采集信号端
  11. sbit led=P1^1;
  12. sbit led1=P2^3;
  13. sbit beep=P1^2;
  14. sbit key1=P3^2;//加1键
  15. sbit key2=P3^3;//减1键
  16. sbit key3=P3^4;//上/下限选择键
  17. bit flag=0;
  18. uint temp; //定义无符号整型形参
  19. float f_temp;//定义浮点型形参
  20. uint TH=300;
  21. uint TL=200;

  22. void delay(uint z)//延时500ms程序
  23. { uint x,y;
  24.   for(x=z;x>0;x--)
  25.    for(y=125;y>0;y--);
  26. }

  27. void write_com(unsigned char com)
  28. {
  29. lcdrs=0;
  30. P0=com;
  31. delay(5);
  32. lcden=1;
  33. delay(5);
  34. lcden=0;
  35. delay(5);
  36. }

  37. void write_data(unsigned char data1)
  38. {
  39. lcdrs=1;
  40. P0=data1;
  41. delay(5);
  42. lcden=1;
  43. delay(5);
  44. lcden=0;
  45. delay(5);
  46. }
  47. void lcd_init( )
  48. {
  49. lcden=0;                   //使能端E清零
  50. write_com(0x38);  //显示模式设置
  51. write_com(0x0c);  //开显示,不显示光标
  52. write_com(0x06);  //当写一个字符后,地址指针自动加1,且光标加1,字符不动
  53. write_com(0x01);  //清屏
  54. }

  55. void temp_dis(uint value)//温度数据显示
  56. {
  57. uchar ge,shi,bai;
  58. bai=value/100;//十位
  59. shi=value%100/10;//个位
  60. ge=value%100%10;//小数位
  61. //write_com(0x80+7);
  62. write_data(disp[bai]);
  63. write_data(disp[shi]);
  64. write_data('.');
  65. write_data(disp[ge]);
  66. }

  67. void ds_init()//DS18B20复位,初始化
  68. {
  69. uint i;
  70. ds=0;
  71. i=90;//延时
  72. while(i>0)i--;//主机发出一个480~960μs的低电平脉冲
  73. ds=1;
  74. i=4;//延时
  75. while(i>0)i--;//释放总线后,以便从机18b20通过拉低总线来指示其是否在线,存在检测高电平时间:15~60μs
  76. }

  77. bit ds_read_bit()  //读一位DS18B20数据
  78. {
  79. uint i ;
  80. bit value_bit;
  81. ds=0;
  82. i++;//延时,读时隙起始于微处理器将总线拉低至少1μs
  83. ds=1;//拉低总线后接着释放总线,让从机18b20能够接管总线,输出有效数据
  84. i++;
  85. i++;//小延时一下,读取18b20上的数据,因为从ds18b20上输出的数据在读“时间隙”下降沿出现15μs内有效
  86. value_bit=ds;
  87. i=8;//延时
  88. while(i>0)i--;//所有读“时间隙”至少需要60μs
  89. return value_bit;
  90. }

  91. uchar ds_read_byte()//读一个字节DS18B20数据
  92. {
  93. uchar i,j,value_byte;
  94. value_byte=0;
  95. for(i=1;i<=8;i++)
  96. {
  97.    j=ds_read_bit();
  98.    value_byte=(j<<7)|(value_byte>>1);//将读取的数据位按读取先后顺序低位到高位(从右往左)排列保存到value_byte
  99. }
  100. return value_byte;
  101. }

  102. void ds_write_byte(uchar write_byte)//写一个字节数据到DS18B20
  103. {
  104. uint i;
  105. uchar j;
  106. bit write_bit;
  107. for(j=1;j<=8;j++)
  108. {
  109. write_bit=write_byte&0x01;//每次只写一位数据
  110. write_byte=write_byte>>1;
  111. if(write_bit)
  112. {
  113. ds=0;
  114. i++;//延时,至少延时1μs,才产生写“时间隙”
  115. ds=1;//写时间隙开始后15μs内允许数据线拉到高电平
  116. i=8;//延时
  117. while(i>0)i--;//所有写时间隙必须最少持续60μs
  118. }
  119. else
  120. {
  121. ds=0;
  122. i=8;//延时
  123. while(i>0)i--;//主机要生成一个写0时间隙,必须把数据线拉到低电平并保持至少60μs
  124. ds=1;//释放总线
  125. i++;//延时
  126. i++;
  127. }
  128. }
  129. }
  130. void temp_convert()//DS18B20开始获取温度并进行转换,先初始化,然后跳过ROM(跳过64位ROM地址,直接向ds18B20发温度转换命令),发送温度转换命令
  131. {
  132. ds_init();
  133. delay(1);
  134. ds_write_byte(0xcc);//跳过序列号命令
  135. ds_write_byte(0x44);//发转换命令44H
  136. }

  137. uint temp_get()//读取DS18B20寄存器中的温度数据
  138. {
  139. uchar temp_low,temp_high;
  140. ds_init();
  141. delay(1);
  142. ds_write_byte(0xcc);
  143. ds_write_byte(0xbe);
  144. temp_low=ds_read_byte();
  145. temp_high=ds_read_byte();
  146. temp=temp_high;
  147. temp<<=8;
  148. temp=temp|temp_low;
  149. f_temp=temp*0.0625;//精度为12位,所以分辨率为0.0625
  150. temp=f_temp*10+0.5;//乘以10,将实际温度扩大十倍,小数部分四舍五入
  151. return temp;//返回的temp是整型数据
  152. }

  153. void display()//静态文字显示
  154. {
  155. uchar i,j,k;
  156. write_com(0x80+2);
  157. for(i=0;i<5;i++)
  158. {
  159. write_data(disp2[i]);
  160. }
  161. write_com(0x80+0x0b);
  162. for(j=0;j<2;j++)
  163. {
  164. write_data(disp3[j]);
  165. }
  166. write_com(0x80+0x40);
  167. for(k=0;k<15;k++)
  168. {
  169. write_data(disp4[k]);
  170. }
  171. }

  172. void warn(uint warn)
  173. {
  174. if(warn<TL)
  175. {
  176. beep=1;//蜂鸣器响
  177. delay(1);//调用延时
  178. beep=0;//蜂鸣器不响
  179. delay(1);//调用延时
  180. led=~led;
  181. led1=0;
  182. }
  183. else if(warn>TH)
  184. {
  185. beep=1;        //蜂鸣器响
  186. delay(1);//调用延时
  187. beep=0;//蜂鸣器不响
  188. delay(1);//调用延时
  189. led=~led;
  190. led1=1;
  191. }
  192. }

  193. void timer0() interrupt 1
  194. {
  195. flag=~flag;
  196. }

  197. void int0() interrupt 0
  198. {
  199. if(flag==1)
  200. TH++;
  201. else
  202. TL++;
  203. }

  204. void int1() interrupt 2
  205. {
  206. if(flag==1)
  207. TH--;
  208. else
  209. TL--;
  210. }

  211. void main()//主函数
  212. {
  213. uchar i;
  214. uint wendu;
  215. TMOD=0x06;
  216. TH0=TL0=0xff;
  217. IE=0x87;
  218. IT0=1;
  219. IT1=1;
  220. TR0=1;
  221. lcd_init();
  222. display();
  223. while(1)
  224. {
  225. temp_convert();
  226. wendu=temp_get();
  227. write_com(0x80+7);
  228. temp_dis(temp_get());
  229. write_com(0x80+0x40+3);
  230. temp_dis(TL);
  231. write_com(0x80+0x40+10);
  232. temp_dis(TH);
  233. i=50;
  234. while(i-->0)
  235. warn(wendu);
  236. }
  237. }
复制代码


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

使用道具 举报

沙发
ID:803822 发表于 2020-7-16 18:32 | 只看该作者
您好 我们最近在做这个设计,我想问一下您的电路图上两个指示灯分别是高温指示灯和低温指示灯吗
回复

使用道具 举报

板凳
ID:868515 发表于 2020-12-30 15:07 | 只看该作者
嘻嘻嘻! 发表于 2020-7-16 18:32
您好 我们最近在做这个设计,我想问一下您的电路图上两个指示灯分别是高温指示灯和低温指示灯吗

他这个,按道理是的。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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