找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于89c1单片机的温控程序

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


  1. sbit DS=P3^7;//定义 DS18B20 接口
  2. sbit buzz=P3^6;//定义蜂鸣器
  3. sbit key1=P3^5;//选择调整上限或者下限温度
  4. sbit key2=P3^4;//温度增加
  5. sbit key3=P3^3;//温度减少
  6. sbit key4=P3^2;//显示实际温度并与上、 下限温度比较
  7. sbit p23=P2^3;
  8. sbit p22=P2^2;
  9. sbit p21=P2^1;
  10. sbit p20=P2^0;
  11. uchar flag=1;
  12. uchar flag1=0;
  13. uchar flag2=0;
  14. static uint tmpH=5;
  15. static uint tmpL=-5;
  16. int tmp;//十六位
  17. uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};//7 段数码管
  18. 段码表共阳,0~9 和熄灭, 负的段码值
  19. uchar data disp_buf[]={0x00,0x00,0x00,0x00}; //保存各个位上的数值
  20. //引脚及标志变量初始化
  21. void init()
  22. {
  23. key1=1;
  24. key2=1;
  25. key3=1;
  26. key4=1;
  27. flag1=0;
  28. flag2=0;
  29. }
  30. //串口初始化
  31. void init_com()
  32. {
  33. TMOD=0x20;//设置定时器方式 1, 用定时器设置串口波特率
  34. TH1=0xfd;// 装入初值
  35. TL1=0xfd;
  36. TR1=1;//启动定时器 1;TR1 为 TCON 中的第六位
  37. REN=1;//串口初始化, 运行串口接收
  38. SM0=0;
  39. SM1=1;//这两行设置串口方式 1
  40. EA=1;//开启总中断
  41. ES=1;//打开串口中断开关
  42. }
  43. void delay(uint x)
  44. {
  45. for(x;x>0;x--);
  46. }
  47. void Init_ds18b20()//初始化
  48. {
  49. unsigned char x=0;
  50. DS = 1; //DS 复位
  51. delay(8); //稍做延时
  52. DS = 0; //单片机将 DQ 拉低
  53. delay(80); //精确延时 大于 480us
  54. DS = 1; //拉高总线
  55. delay(5);
  56. x=DS; //稍做延时后 如果 x=0 则初始化成功 x=1 则初始化失败
  57. delay(20);
  58. }
  59. void Write_ds18b20(uchar dat)
  60. {
  61. uchar i;
  62. for(i=0;i<8;i++)
  63. {
  64. DS=0;
  65. //_nop_();
  66. //_nop_();//启动写时许开始, 延时 2us
  67. if(dat&0x01)
  68. {
  69. DS=1;//发 1 状态
  70. delay(10);//延时 60us
  71. }
  72. else //发 0 状态
  73. {
  74. DS=0;
  75. delay(10);//延时 60us
  76. DS=1;//释放总线
  77. _nop_();//回复时间延时 2us
  78. _nop_();
  79. }
  80. dat>>=1;
  81. }
  82. //delay(4);
  83. }
  84. uchar Read_ds18b20()
  85. {
  86. uchar i,dat=0;
  87. for(i=0;i<8;i++)
  88. {
  89. DS=1; //特别注意此处
  90. //_nop_();//延时 1us //特别注意此处
  91. delay(1); //特别注意此处
  92. DS=0;//启动读开始 //特别注意此处
  93. dat>>=1;
  94. DS=1;//释放总线
  95. //delay(8);//延时 16us
  96. if(DS)
  97. dat=dat|0x80;
  98. delay(5);
  99. }
  100. return dat;
  101. }
  102. int ReadTemperature(void)
  103. {
  104. uchar a,b;//uchar 八位
  105. int temp; //十六位
  106. Init_ds18b20();
  107. Write_ds18b20(0xCC);// 跳过读序号列号的操作
  108. Write_ds18b20(0x44);// 启动温度转换
  109. delay(200);
  110. Init_ds18b20();
  111. Write_ds18b20(0xCC);//跳过读序号列号的操作
  112. Write_ds18b20(0xBE);//读取温度寄存器等(共可读 9 个寄存器) 前两个就是温度
  113. a=Read_ds18b20();//低 8 位
  114. b=Read_ds18b20();//高 8 位
  115. temp=b;
  116. temp=temp<<8;
  117. temp=temp+a;
  118. return temp;
  119. }
  120. void change()
  121. {
  122. int tp;
  123. if((tmp&0xf800)==0xf800)//温度小于零度时
  124. {
  125. tp=tmp;
  126. tp=~tp+1;
  127. tmp=tp&0x000f;
  128. disp_buf[0]=(tmp&0x000f)*0.625+0.5;
  129. tp=tp>>4;
  130. tp=tp%100;
  131. disp_buf[2]=tp/10;
  132. disp_buf[1]=tp%10;
  133. if(disp_buf[2]==0)
  134. {
  135. disp_buf[3]=10;
  136. disp_buf[2]=11;
  137. }
  138. else
  139. {
  140. disp_buf[3]=11;
  141. }
  142. }
  143. else
  144. {
  145. disp_buf[0]=(tmp&0x000f)*0.625+0.5;//小数部分
  146. tp=tmp>>4;//整数部分
  147. disp_buf[3]=tp/100;//百位
  148. tp=tp%100;
  149. disp_buf[2]=tp/10;//十位
  150. disp_buf[1]=tp%10;//个位
  151. if(!disp_buf[3])
  152. {
  153. disp_buf[3]=10;
  154. if(!disp_buf[2])
  155. {
  156. disp_buf[2]=10;
  157. }
  158. }
  159. }
  160. }
  161. void delayms(uint v)//延时, 实现数码管的动态显示
  162. {
  163. uint m,n;
  164. for(m=v;m>0;m--)
  165. for(n=73;n>0;n--);
  166. }
  167. void display()//温度显示函数
  168. {
  169. p20=0;//开百位显示
  170. P0=tab[disp_buf[3]];//显示百位
  171. delayms(5);//延时
  172. p20=1;//关百位显示
  173. p21=0;
  174. P0 =tab[disp_buf[2]];//显示十位
  175. delayms(5);
  176. p21=1;
  177. p22=0;
  178. P0=tab[disp_buf[1]]&0x7f;//显示个位,并带小数点
  179. delayms(5);
  180. p22=1;
  181. p23=0;
  182. P0 =tab[disp_buf[0]];//显示小数位
  183. delayms(5);
  184. p23=1;
  185. }
  186. int main()
  187. {
  188. uchar data pc[6];
  189. uint i;
  190. init();
  191. init_com();
  192. tmp=ReadTemperature();
  193. change();
  194. pc[1]=disp_buf[2]+'0';
  195. pc[2]=disp_buf[1]+'0';
  196. pc[3]='.';
  197. pc[4]=disp_buf[0]+'0';
  198. while(1)
  199. {
  200. if(flag==1)
  201. {
  202. ES=0;
  203. for(i=1;i<5;i++)
  204. {
  205. SBUF=pc[ i];
  206. while(!TI);
  207. TI=0;
  208. }
  209. ES=1;
  210. flag=0;
  211. }
  212. while((flag1==0)&&(flag2==0))//flag1=1 时调上限。flag1=2 时调下限
  213. {
  214. tmp=ReadTemperature();
  215. change();
  216. display();
  217. if(key1==0)//按下 1 键
  218. {
  219. delayms(100);
  220. flag1=1;
  221. key1 = 1;
  222. }
  223. }
  224. while(flag1==0&&flag2==1)
  225. {
  226. buzz=1;
  227. tmp=ReadTemperature();
  228. change();
  229. display();
  230. while(tmp>=tmpH||tmp<=tmpL)
  231. {
  232. tmp=ReadTemperature();
  233. change();
  234. display();
  235. buzz=0;
  236. }
  237. }
  238. while(flag1==1)
  239. {
  240. tmp=(tmpH<<4);
  241. change();
  242. while(flag1==1)
  243. {
  244. display();
  245. if(key2==0)//上限升高
  246. {
  247. tmpH++;
  248. tmp=(tmpH<<4);
  249. change();
  250. while(!key2)
  251. display();
  252. }
  253. if(key3==0)//上限降低
  254. {
  255. tmpH--;
  256. tmp=(tmpH<<4);
  257. change();
  258. while(!key3)
  259. display();
  260. }
  261. if(key1 == 0)//切换到调整下限模式
  262. {
  263. delayms(5);
  264. flag1=2;
  265. tmp=(tmpH<<4);
  266. while(!key1);
  267. }
  268. if(key4==0)//按下 key4,实际温度与上限、 下限比较
  269. {
  270. flag1=0;
  271. flag2=1;
  272. //tmp=tmpH;
  273. while(!key4);
  274. }
  275. }
  276. }
  277. while(flag1==2)//调下限
  278. {
  279. tmp=(tmpL<<4);
  280. change();
  281. while(flag1==2)
  282. {
  283. display();
  284. if(key2==0)
  285. {
  286. tmpL++;
  287. tmp=(tmpL<<4);
  288. change();
  289. while(!key2)
  290. display();
  291. }
  292. if(key3==0)
  293. {
  294. tmpL--;
  295. tmp=(tmpL<<4);
  296. change();
  297. while(!key3)
  298. display();
  299. }
  300. if(key1==0)
  301. {
  302. flag1=1;
  303. tmp=(tmpL<<4);
  304. while(!key1);
  305. }
  306. if(key4==0)
  307. {
  308. flag1=0;
  309. flag2=1;
  310. //tmp=tmpL;
  311. while(!key4);
  312. }
  313. }
  314. }
  315. }
  316. return 0;
  317. }
复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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