找回密码
 立即注册

QQ登录

只需一步,快速开始

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

炉温控制系统+proteus仿真+程序

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




单片机源程序:
  1. #include<REG51.H>                                                                                                                                                  
  2. #include<math.h>
  3. #include<INTRINS.H>
  4. #include<string.h>  
  5. #define CIRCLE 100
  6. #define uchar unsigned char
  7. #define uint   unsigned int;
  8. struct PID {  
  9. unsigned int SetPoint; // 设定目标 Desired Value  
  10. unsigned int Proportion; // 比例常数 Proportional Const  
  11. unsigned int Integral; // 积分常数 Integral Const  
  12. unsigned int Derivative; // 微分常数 Derivative Const  
  13. unsigned int LastError; // Error[-1]  
  14. unsigned int PrevError; // Error[-2]  
  15. unsigned int SumError; // Sums of Errors  
  16. };  
  17. struct PID spid; // PID Control Structure  
  18. unsigned int rout; // PID Response (Output)  
  19. unsigned int rin; // PID Feedback (Input)  
  20. typedef unsigned char BYTE;
  21. typedef unsigned int WORD;
  22. typedef bit BOOL ;
  23. sbit key1=P3^2;   //定义按键位置
  24. sbit key2=P3^3;
  25. sbit rs = P1^0;
  26. sbit rw = P1^1;
  27. sbit ep = P1^2;
  28. sbit pwm=P1^5; //PWM输出端设置为P1.5输出
  29. sbit DQ=P1^3;//ds18b20 信号引脚即DQ
  30. sfr dataled=0x80;//显示数据端口 即P2口为段选码输入口
  31. uchar temp;//温度变量
  32. unsigned char set_temper=30;  
  33. unsigned char high_time;
  34. unsigned int s;   
  35. uchar flag_get,count,num,counter; //温度读取标志位、中断次数变量t0中断次数以读取温度值, t1中断次数以控制周期和PWM的占空比
  36. char const table[]={100,80,70,60,50,40,30,20,0};//高电平时间查表
  37. uchar
  38. code
  39. tab[]={0x28,0xEB,0x32,0xA2,0xE1,0xA4,0x24,0xEA,0x20,0xA0,0x60,0x25,0x3C,0x23,0x34,
  40. 0x74,0xF7,0xFF};//,0x88,0x83,0xC6,0xA1,0x86,0x8E};//共阳led显示段码115段码表
  41. uchar  shi,ge,danwei,dang,dang_dis;  // 定义温度十位、个位、摄氏度单位、及档位变量名称,及显示档位的查表变量

  42. void delay1(uchar MS);// 延时函数
  43. unsigned char ReadTemperature(void);//读温度子函数
  44. void Init_DS18B20(void);// DS18B20初始化
  45. unsigned char ReadOneChar(void);//读字节子函数
  46. void WriteOneChar(unsigned char dat);//写字节子函数
  47. void delay(unsigned int i);//延时
  48. //void del(unsigned int);
  49. void drive_moto();//由P1低四位输出控制信号
  50. void initial();
  51. unsigned int TempBuffer[5];
  52. BYTE code dis1[] = {"Temperature:"};
  53. BYTE code dis2[] = {"Set_Temper:"};
  54. BYTE code dis3[] = {"0123456789"};
  55. BYTE code dis4[] = 0xdf;
  56. BYTE code dis5[] = {"C"};



  57. //
  58. void init();




  59. void delay2(BYTE ms)
  60. {  
  61. BYTE i;
  62. while(ms--)
  63. {
  64.   for(i = 0; i< 250; i++)
  65.   {
  66.    _nop_();
  67.    _nop_();
  68.    _nop_();
  69.    _nop_();
  70.   }
  71. }
  72. }

  73. BOOL lcd_bz()
  74. {       // 测试LCD忙碌状态
  75. BOOL result;
  76. rs = 0;
  77. rw = 1;
  78. ep = 1;
  79. _nop_();
  80. _nop_();
  81. _nop_();
  82. _nop_();
  83. result = (BOOL)(P0 & 0x80);
  84. ep = 0;
  85. return result;  
  86. }

  87. void lcd_wcmd(BYTE cmd)
  88. {       // 写入指令数据到LCD
  89. while(lcd_bz());
  90. rs = 0;
  91. rw = 0;
  92. ep = 0;
  93. _nop_();
  94. _nop_();  
  95. P0 = cmd;
  96. _nop_();
  97. _nop_();
  98. _nop_();
  99. _nop_();
  100. ep = 1;
  101. _nop_();
  102. _nop_();
  103. _nop_();
  104. _nop_();
  105. ep = 0;   
  106. }
  107. void lcd_pos(BYTE pos)
  108. {       //设定显示位置
  109. lcd_wcmd(pos | 0x80);
  110. }
  111. void lcd_wdat(BYTE dat)  
  112. {       //写入字符显示数据到LCD
  113. while(lcd_bz());
  114. rs = 1;
  115. rw = 0;
  116. ep = 0;
  117. P0 = dat;
  118. _nop_();
  119. _nop_();
  120. _nop_();
  121. _nop_();
  122. ep = 1;
  123. _nop_();
  124. _nop_();
  125. _nop_();
  126. _nop_();
  127. ep = 0;  
  128. }
  129. void lcd_init()
  130. {       //LCD初始化设定
  131. lcd_wcmd(0x38);   //
  132. delay2(1);
  133. lcd_wcmd(0x0c);   //
  134. delay2(1);
  135. lcd_wcmd(0x06);   //
  136. delay2(1);
  137. lcd_wcmd(0x01);   //清除LCD的显示内容
  138. delay2(1);
  139. }
  140. void initial()
  141. {
  142. EA=1;
  143. TMOD=0x11;//定时器设置皆工作在16定时计数器模式
  144. TH0=0xef;//T0赋初值
  145. TL0=0xf0;
  146. TH1=(65536-1000)/256;//T1赋初值
  147. TL1=(65536-1000)%256;
  148. ET1=1;
  149. ET0=1;
  150. TR0=1;
  151. TR1=1;
  152. P2=0xff;   
  153. count=0;
  154. counter=0;//pwm占空比控制变量
  155. //IP=0x08; //T1优先级高于T0 ,后来证明此语句是多余的因为当加入此句后反/////而PWM调速和温度检测都变得有点不稳定
  156. }
  157. void delay(unsigned int i)//延时函数
  158. {
  159. while(i--);  
  160. }
  161. //18b20初始化函数检测总线上是否有从属器件DS的存在若存在则通讯成功
  162. void Init_DS18B20(void)
  163. {
  164. unsigned char x=0;
  165. DQ = 1;    //DQ复位
  166. delay(8);  //稍做延时
  167. DQ = 0;    //单片机将DQ拉低
  168. delay(80); //延时 大于 480us
  169. DQ = 1;    //拉高总线
  170. delay(10);
  171. x=DQ;      //稍做延时后 如果x=0则初始化成功 x=1则初始化失败因为DQ复位成功的回答信号即存在信号是低电平
  172. delay(5);
  173. }
  174. //读一个字节ROM
  175. unsigned char ReadOneChar(void)
  176. {
  177. unsigned char i=0;
  178. unsigned char dat = 0;
  179. for (i=8;i>0;i--)
  180. {
  181.   DQ = 0; // 给脉冲信号
  182.   dat>>=1;
  183.   DQ = 1; // 给脉冲信号
  184.   if(DQ)
  185.    dat|=0x80;//
  186.   delay(5);
  187. }
  188. return(dat);
  189. }

  190. //写一个字节
  191. void WriteOneChar(unsigned char dat)
  192. {
  193. unsigned char i=0;
  194. for (i=8; i>0; i--)
  195. {
  196.   DQ = 0;
  197.   DQ = dat&0x01;
  198.   delay(5);
  199.   DQ = 1;
  200.   dat>>=1;
  201. }
  202. delay(5);
  203. }
  204. //读取温度
  205. unsigned char ReadTemperature(void)
  206. {
  207. unsigned char a=0;
  208. unsigned char b=0;
  209. unsigned char t=0;

  210. Init_DS18B20();// 复位
  211. WriteOneChar(0xCC); // 跳过读序号列号的操作
  212. WriteOneChar(0x44); // 启动温度转换
  213. delay(100);
  214. Init_DS18B20();  //每次操作前都要进行复位
  215. WriteOneChar(0xCC); //跳过读序号列号的操作  
  216. WriteOneChar(0xBE); //读取温度寄存器等共可读9个寄存器 前两个就是温度
  217. a=ReadOneChar();
  218. b=ReadOneChar();
  219. s=(unsigned int)(a&0x0f);  
  220. b<<=4;//取高字节的第四位因为高四位为符号位1111为负0000为正
  221. b+=(a&0xf0)>>4;//忽略小数位取a的高四位与b的相加就是此时所测得到整数温度值
  222. t=b;
  223. return(t);//返回温度值给这个函数
  224. }

  225. void printf()
  226. {
  227. BYTE i;
  228. delay2(10);
  229. lcd_pos(0x00);    // 设置显示位置为第一行的第5个字符
  230. i = 0;
  231. while(dis1[i] != '\0')
  232. {      
  233.   lcd_wdat(dis1[i]);
  234.   i++;
  235. }
  236. lcd_pos(0x40);   // 设置显示位置为第二行第二个字符
  237. i = 0;
  238. while(dis2[i] != '\0')
  239. {
  240.   lcd_wdat(dis2[i]); // 显示字符
  241.   i++;
  242. }
  243. TempBuffer[0]=temp/10;  //十位
  244. TempBuffer[1]=temp%10;  //个位
  245. lcd_pos(0x0c);  
  246. lcd_wdat(dis3[TempBuffer[0]]); //测试温度十位
  247. lcd_pos(0x0d);  
  248. lcd_wdat(dis3[TempBuffer[1]]); //测试温度个位
  249. lcd_pos(0x0e);
  250. lcd_wdat(dis4[0]);  
  251. lcd_pos(0x0f);
  252. lcd_wdat(dis5[0]);

  253. TempBuffer[2]=set_temper/10;  //十位
  254. TempBuffer[3]=set_temper%10;  //个位
  255. lcd_pos(0x4c);  
  256. lcd_wdat(dis3[TempBuffer[2]]); //设置温度十位
  257. lcd_pos(0x4d);  
  258. lcd_wdat(dis3[TempBuffer[3]]); //设置温度个位
  259. lcd_pos(0x4e);
  260. lcd_wdat(dis4[0]);  
  261. lcd_pos(0x4f);
  262. lcd_wdat(dis5[0]);
  263. }
  264. void keyscan()
  265. {
  266. if(key1==0)
  267. {
  268.   delay(200);
  269.   if(key1==0)
  270.   {
  271.    set_temper++;
  272.   }
  273. }
  274. if(key2==0)
  275. {
  276.   delay(200);
  277.   if(key2==0)
  278.   {
  279.    set_temper--;
  280.   }
  281. }
  282. }
  283. void tim(void) interrupt 1 using 1//中断用于数码管扫描和温度检测间隔
  284. {
  285. // TH0=0xef;//定时器重装值
  286. // TL0=0xf0;
  287. // num++;
  288. // if (num==100)
  289. // {
  290. //  num=0;
  291. //  flag_get=1;//标志位有效
  292. // }
  293. }

  294. void into(void) interrupt 3 //T1定时中断服务程序  
  295. {   
  296.    
  297.     TH1=(65536-1000)/256;//初值重装
  298.     TL1=(65536-1000)%256;
  299. counter++;
  300.   if(counter>CIRCLE)  
  301. {
  302.   counter=0;////限定周期为T=100X0.01ms=10ms
  303. }  
  304. if(counter<=high_time)//取得查表参数以调节pwm的占空比
  305. pwm=1;//PWM高电平
  306. else   
  307. pwm=0;
  308. }



  309. void compare_temper()  
  310. {  
  311. // unsigned char i;  
  312. if(set_temper>temp)  
  313. {  
  314.   if(set_temper-temp>=10)  
  315.   {  
  316.    high_time=100;  
  317.   }  
  318.   else  
  319.   {  
  320. //   for(i=0;i<10;i++)  
  321. //   {  
  322. //    rin = s; // Read Input  
  323. //    rout = PIDCalc ( &spid,rin ); // Perform PID Interation  
  324. //   }  
  325.    if (set_temper-temp==9)  
  326.     high_time=90;
  327.    if (set_temper-temp==8)  
  328.     high_time=80;
  329.    if (set_temper-temp==7)  
  330.     high_time=70;
  331.    if (set_temper-temp==6)  
  332.     high_time=60;
  333.    if (set_temper-temp==5)  
  334.     high_time=50;
  335.    if (set_temper-temp==4)  
  336.     high_time=40;
  337.    if (set_temper-temp==3)  
  338.     high_time=30;
  339.    if (set_temper-temp==2)  
  340.     high_time=20;
  341.    if (set_temper-temp==1)  
  342.     high_time=10;
  343.   }  
  344. }  
  345. else if(set_temper<temp)  
  346. {  
  347. //  if(temp-set_temper>0)  
  348. //  {  
  349.    high_time=0;  
  350. //  }  
  351. }   
  352. }
  353. main()
  354. {
  355. initial();// 初始化个变量及定时器的初值开中断等
  356. lcd_init();    // 初始化LCD   
  357. while(1)
  358. {
  359.   compare_temper();  
  360.   printf();
  361.   temp=ReadTemperature();
  362.   keyscan();      
  363. }
  364. }
复制代码

所有资料打包下载:
炉温控制系统.rar (382.23 KB, 下载次数: 255)

评分

参与人数 4黑币 +66 收起 理由
Aaabin + 12 很给力!
花鼓灯 + 3 共享资料的黑币奖励!
潇洒聪哥ing + 1 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:1 发表于 2016-12-3 23:55 | 只看该作者
51黑有你更精彩!!!
回复

使用道具 举报

板凳
ID:195719 发表于 2017-5-2 19:58 | 只看该作者
请问你会编程这个课程设计的吗
回复

使用道具 举报

地板
ID:195719 发表于 2017-5-2 20:03 | 只看该作者
请问在此电路图修改些电路能编程吗
回复

使用道具 举报

5#
ID:194844 发表于 2017-5-4 20:24 | 只看该作者
请问你会编程这个课程设计的吗
回复

使用道具 举报

6#
ID:257829 发表于 2017-12-10 14:02 | 只看该作者
感觉程序不是很懂,看来我还得多学习
回复

使用道具 举报

7#
ID:106211 发表于 2018-1-11 15:48 | 只看该作者
先下载了  ,不知道是否可以使用在PTC做的温控台上
回复

使用道具 举报

8#
ID:254251 发表于 2018-1-11 18:07 | 只看该作者
学习学习
回复

使用道具 举报

9#
ID:87193 发表于 2018-1-15 15:02 | 只看该作者
学习了,谢谢分享
回复

使用道具 举报

10#
ID:241772 发表于 2018-4-16 22:47 | 只看该作者
学习了,谢谢分享
回复

使用道具 举报

11#
ID:314339 发表于 2018-4-23 11:58 来自手机 | 只看该作者
学习了,试试
回复

使用道具 举报

12#
ID:314339 发表于 2018-4-23 19:19 来自手机 | 只看该作者
是pid程序吗
回复

使用道具 举报

13#
ID:543692 发表于 2019-5-22 18:42 | 只看该作者
学习了,谢谢分享
回复

使用道具 举报

14#
ID:665375 发表于 2019-12-16 17:00 | 只看该作者
学习了,谢谢分享
回复

使用道具 举报

15#
ID:765945 发表于 2020-6-1 14:21 | 只看该作者
谢谢 学习学习
回复

使用道具 举报

16#
ID:51889 发表于 2020-6-17 15:03 | 只看该作者
谢谢啦
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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