首页资源分类电子电路模拟及混合电路 > 温度自动控制

温度自动控制

已有 445025个资源

下载专区

电子电路热门资源

本周本月全部

文档信息举报收藏

标    签:DS18B20自动控制电赛题目

分    享:

文档简介

DS18B20  自动控制 电赛题目

文档预览

温度自动控制系统 摘要:本温度自动控制系统采用PWM温度控制系统控制一封闭木盒内的温度, 温度可调节范围为5℃~35℃,最小设定分度为1℃, 温度显示分辨率为0.1℃, 当温度达到某一设定值并稳定后,盒内温度的波动控制在±2℃以内,当温度调控达到稳定状态时,可以给出声或光提示信号,当设定的调节温差为15℃时, 可以达到稳定状态的调节时间小于等于3分钟,稳定状态下的温度波动在±2℃以内。当温度达到稳定状态的提示信号出现后能立即检测调控的温度值,是理想的温度自动控制系统的解决方案。 关键词: 温度 PWM DS18B20 PID Abstract:System has made a temperature autocontrol system according to the request , the function it can realize has been: Control the temperature once closing the wooden box inner, the temperature may adjust range for 5 °C ~ 35 °C, the minimum sets up scale division being 1°C , the temperature shows 0.1 °C a resolution ratio , think that the temperature reaches some one setting value and stabilizes the day afer tomorrow, the box inner temperature fluctuation controls within +/-2 °C, think that the temperature regulates and controls when reaching stable state , can be uttered or while the adjustment difference in temperature setting up is 15 °C up the hint signal,the adjustment time being able to reach stable state is equal or less than 3 minutes, The lower temperature of stable state undulates within +/-2 °C. The temperature value that check regulates and controls immediately the day after tomorrow appears on the hint signal thinking that the temperature reaches stable state finally ,detecting time continues 60 ses every time. 一、系统方案 根据题目要求,有两种控制方案。 方案(一):常规温度自动控制系统 系统框图如下图: 该部分温度检测部分检测部分采用热电偶,它需要冷端补偿电路与其配套,并且热电偶输出电压只有几毫负,必须经过放大处理才能A/D转换和D/A转换器接口,若采用8位A/D转换器,CADC0809则输人端需采用仪用放大器,把几毫伏的电压信号放大到5伏左右。由于热电偶属于非线性器件,因此每个温度值都必须通过分度表,查表才能获得,这给软件编程和数据处理增加了难度。 这种系统通过继电器控制温度的变化在显示在单片机上但控制不方便构成系统复杂,抗干扰能力不强。 方案(二):PWM数字温度控制系统 系统框图如下: 该方案采用数字温度传感器DS18B20,它的最高分辨率为12位,可识别0.0625摄氏度的温度。它具有直接输出数字信号和数据处理,并且它和单片机接口只需要一位I/O口,因此由它构成的系统简单使用,由于DS18B20,按照工业设计要求设计,抗干扰性能强。但温度测量范围从-55摄氏度—-125摄氏度,综上所诉:比较方案(一)和方案(二),因为只在常温下使用,并且经济合理,因此选择了方案(二)。 二.理论分析与计算 1. 温度控制算法 对温度的控制算法,采用技术成熟的P ID算法,对于时间常数比较大的系统来说,其近似于连续变化,因此用数字PID完全可以得到比较好的控制效果 增量法计算公式:Pdlt(t)=Kp*e(t)-e(t-1)+Ki*e(t)+Kd*(e(t)-2*e(t-1)+e(t-2)); 根据观察结果我们的降温时间在0~3分钟,我将每分钟分成100等分,所以每一个基本单位的具体时间是:To=60*2/200=600(ms)。 其中PID仿真结果如下图: 图一 2.温度自动控制系统电路设计计算 2.1 电桥的选择 经过变压器的降压,PWM调压电路的输入电压为18V,因为制冷片的额定电流为6A,这个电路的输出电压理论值为24V功率为P=U*I=144W,所以所选电桥的额定电压应为14V,即选择了I=20A的电桥。 2.2 电容的选择 在PWM调压电路中输入电压经过电桥放大使得电路电压为36V所以电容需选择耐压值为4700uf/50V的电容。 二、电路与程序设计 1、 系统总体结构设计及说明 图二 系统总体结构框图 图三 系统控制框图 如图一该系统实现了首先通过MSP430F149芯片中的PWM模块控制调压电路→制冷片→温度传感器,最后通过LED显示把温度显示出来。软件运行如图三,其中决策函数中的输入输出符合图一PID仿真结果,以上就是完成这个题目的大体思路和方法。 2、电路设计 2.1、 电源部分 图四 电源电路 通过双变压器让电路得到更大的驱动电流,从而使驱动功率变大 2.2、PWM调压电路 图五 PWM调压电路 PWM控制这个电路的电压值继而通过电路的输出电压来控制制冷片 2.3、TEC 图六 TEC(制冷制热电路) 通过2个继电器的双向控制使得制冷片制冷制热,其中Px0、Px1不能同时为逻辑‘1’或逻辑‘0’。 3.程序设计 主控制芯片为MSP430F149,测量周期为128ns,由于处理器速度较快,所以采用c语言编程方便简单.软件流程图如下: 三.测试方案与测试结果 当前温度 (℃) 给定温度 (℃) 稳定时间 (s) 超调量 (℃) 温度波动误差(℃) 31.2 15 148 1.8 ±0.5 33.0 18 170 2.1 ±0.8 29.4 14 168 1.6 ±0.7 31.2 12 160 2.5 ±0.6 26.2 9 148 2.2 ±0.5 21.9 6 130 1.5 ±0.4 结果分析: 参考文献 1、《单片机应用系统设计》 何立民 北京航空航天大学出版社 2、《MSP430单片机常用模块与综合系统实例精讲》 秦龙 电子工业出版社 3、《数字电子技术基础》 阎石著 高等教育出版社 4、《信号与系统》 ALAN V.OPPENHEIM 西安交通大学出版社 5、《MSP430单片机C程序设计与实践》 曹磊 北京航空航天大学出版社 附录 附1 元器件清单 单片机最小系统板(仅含单片机芯片、键盘与显示装置、存储器、A/D、D/A)?.Dr1?μ(www.hbeda.com[2[1]?e¥&{ù 可编程逻辑器件及其下载板?.Dr1?μ(www.hbeda.com[2[1]?e¥&{ù 直径0.1~0.2mm的漆包线?.Dr1?μ(www.hbeda.com[2[1]?e¥&{ù 环氧树脂或其它粘接材料?.Dr1?μ(www.hbeda.com[2[1]?e¥&{ù 南大703硅橡胶?.Dr1?μ(www.hbeda.com[2[1]?e¥&{ù 1米(有厘米、毫米刻度)塑料卷尺直径不小于2.5mm的漆包线或有绝缘外皮的导线 中频变压器(465~520)kHz 隔离变压器(>150W,220V/18V) 陶瓷平板型半导体致冷器TEC1-12705 附2 程序清单 *******************************************************#include #include "init.h" //定义DS18B20的接口 #define DS18B20_DIR P1DIR #define DS18B20_IN P1IN #define DS18B20_OUT P1OUT #define DS18B20_DQ BIT1 + BIT2 + BIT3 // DS18B20 ROM命令宏定义 #define ReadRom 0x33 #define MatchRom 0x55 #define SearchRom 0xf0 #define AlertSearch 0xec #define CopyScratchpad 0x48 #define SkipRom 0xcc #define ReadPower 0xb4 // DS18B20 功能命令宏定义 #define ConvertTemperature 0x44 #define ReadScratchpad 0xbe #define WriteScratchpad 0x4e #define RecallE 0xb8 // 温度的十进制编码(查表用) unsigned char decimalH[16]={00,06,12,18,25,31,37,43,50,56,62,68,75,81,87,93}; unsigned char decimalL[16]={00,25,50,75,00,25,50,75,00,25,50,75,00,25,50,75}; // 变量定义 unsigned char GetScratchpad[9]; unsigned char ResultTemperatureH; //温度的整数部分 unsigned char ResultTemperatureLH; //温度的小数部分(高位) unsigned char ResultTemperatureLL; //温度的小数部分(低位) unsigned char ResultSignal; //温度符号 unsigned char temp_num,t_flag=1,i,adc_flag; //传感器的序列 uchar extern count=0; uint results[10]; long int ad_temp=0; void DS18B20_WriteBit(unsigned char oww_dat); void DS18B20_WriteByte(unsigned char oww_dat); void DS18B20_ReadTemp(unsigned char BIT_px); unsigned char DS18B20_Init(void); unsigned char DS18B20_ReadBit(void); unsigned char DS18B20_ReadByte(unsigned char BIT_px); unsigned char Verify_CRC8(); //数码管变量 uchar LED_count=0 ;//LED数码的显示当前位 uchar LED_DATA[8];//数码管 各位上的数据 uchar LED_segment[21]={ 0XFC,/*0*/ 0X60,/*1*/ 0XDA,/*2*/ 0XF2,/*3*/ 0X66,/*4*/ 0XB6,/*5*/ 0XBE,/*6*/ 0XE0,/*7*/ 0XFE,/*8*/ 0XF6,/*9*/ //0-9数据编码 0XFD,/*0.*/ 0X61,/*1.*/ 0XDB,/*2.*/ 0XF3,/*3.*/ 0X67,/*4.*/ 0XB7,/*5.*/ 0XBF,/*6.*/ 0XE1,/*7.*/ 0XFF,/*8.*/ 0XF7,/*9.*/ //0.-9.数据编 0X02/*-*/ }; uchar LED_didg[8]={0xf7,0xfb,0xfd,0xfe,0x7f,0xbf,0xdf,0xef}; //位选 编码 uchar LED_stat[8]={1,1,1,1,1,1,1,1};//数码管该位状态数据 0为熄灭 1为亮 2 为闪亮 uchar flash_ctrl=1; //闪烁控制标志 uint time_count=0,t1; //控制闪烁速度的 //键盘变量 uchar KEY_segment[8]={KEY5,KEY6,KEY7,KEY8,KEY1,KEY2,KEY3,KEY4}; uchar KEY_stat; //键盘状态 uchar KEY_code; //键盘码 输入缓存队列 uchar KEY_count; //确认按键计数 控制按键确认次数 //全局变量 uchar INT_count;//中断次序 long time_count1; uchar t_flag; uchar flash_stat=0; uchar LED_enable=1; uchar T_count=0; //任务循环标志 uchar KEY_count2,KEY_temp[2]; uchar KEY_enable=1; uchar over_count = 0; //溢出次数 uchar temp_flag = 0; //温度转换标志 void KEY_task(void);//键盘任务分配 void clear_LED(void);//LED清零 //初始化PWM void int_pwm(void) { P1SEL |= BIT2;//选择P12作为PWM输出 P1DIR |= BIT2; TACTL |= TASSEL1 + MC0/* + TAIE*/; //MCLK,不分频,增计数模式 TACCR0 = 400;//PWM信号周期20KHz TACCR1 = 1;//占空比1:1 TACCTL1 = OUTMOD0 + OUTMOD1 + OUTMOD2; //输出模式选择 } //改变占空比 void change_pwm(unsigned int t0,unsigned int t1) { TACCR0 = t0;//PWM信号周期 TACCR1 = t1;//占空比t1:(t1+t0) } /*******************************MAIN enter port*********************************/ int main( void ) { unsigned char a1,a2,a3,a4,a5; //作为LED_DATA[]的临时数据 //***** 2 -start-在执行主任务前的一些初始化和其他设置***********************// WDTCTL = WDTPW + WDTHOLD; //关看门狗 flash_stat = 0; LED_enable = 1; int_clk(); //初始化时钟 int_LED_port(); //初始化LED int_BUTTON_port();//初始化BUTTON端口 int_timerA(); //初始化TimerA int_timerB(); //初始化TimerB int_pwm(); //初始化PWM int_adc();//初始化ADC //ADC12CTL0 |= ADC12SC; // 开启转换 _EINT();//打开中断 开始正式工作 adc_flag=0; close_LED();//关闭发光二级管 //***** 2-end-初始化和设置结束********************************************// //****-3-start-用户可执行代码-------------------------------------------*/ while(1) { switch(T_count) { case 0://任务一 if(temp_flag == 20) { temp_flag = 0; if(temp_num == 1) { DS18B20_ReadTemp(BIT1); } if(temp_num == 2) { DS18B20_ReadTemp(BIT2); } { a1 = ResultTemperatureH /100; a2 = ResultTemperatureH %100/10; a3 = 10 + ResultTemperatureH %10; a4 = ResultTemperatureLH %100/10; a5 = ResultTemperatureLH %10; // if(ResultTemperatureH==0) LED_DATA[5]=6; } } break; case 1://任务二 if(KEY_code==1) { if(ResultSignal == 1) //为零下则显示负号 { LED_DATA[0] = 21; } else { LED_DATA[0] = a1; } LED_DATA[1]=a2; LED_DATA[2]=a3; LED_DATA[3]=a4; LED_DATA[4]=a5; //LED_DATA[5]=10; } if(KEY_code==4) { // ADC12CTL0 |= ADC12SC; //************ LED_DATA[0] = (ad_temp)/10000;//ad_temp LED_DATA[1] = (ad_temp)%10000/1000+10;//ad_temp LED_DATA[2] = (ad_temp)%1000/100;//ad_temp LED_DATA[3] = (ad_temp)%100/10;//ad_temp LED_DATA[4] = 0;//ad_temp //KEY_code=0xff; // ADC12CTL0 &= ~ADC12SC;//********** } if(KEY_code == 5) { t1++; change_pwm(400,t1); //LED[1] = t1*10/t0; // LED[2] = t1*100/t0%10+10; LED_DATA[5] = t1/100; LED_DATA[6] = t1%100/10; LED_DATA[7] = t1%10; //LED[7] = key; KEY_code=0xff; t1 %= 400; } if(KEY_code==6) { t1 +=10; change_pwm(400,t1); //LED[1] = t1*10/t0; // LED[2] = t1*100/t0%10+10; LED_DATA[5] = t1/100; LED_DATA[6] = t1%100/10; LED_DATA[7] = t1%10; // LED[7] = key; KEY_code=0xff; t1 %= 400; } if(KEY_code==7) { if(t1<10) break; else { t1 -=5; change_pwm(400,t1); //LED[1] = t1*10/t0; //LED[2] = t1*100/t0%10+10; LED_DATA[5] = t1/100; LED_DATA[6] = t1%100/10; LED_DATA[7] = t1%10; //LED[7] = key; KEY_code=0xff; t1 %= 400; } } if(t1>=50) t1=1; break; case 2://任务三 KEY_task(); break; case 3: //LED显示 break; } T_count++; T_count%=4; //***-3-end-------------------------------------------------------------*/ } } #pragma vector=ADC_VECTOR __interrupt void ADC12ISR (void) { adc_flag=1; results[count] = ADC12MEM2; // 读取A2转换结果 count++; if(count==8) { ad_temp=0; //ad9_temp清零 for(i=0;i<8;i++) { ad_temp += results[i];} ad_temp=ad_temp/8; ad_temp=ad_temp*6105/10000; count = 0; } //LED_DATA[7]=3; } /***************************************************************************** 定时器A中断函数 多中断源:CC1~2 TA ******************************************************************************/ #pragma vector=TIMERA1_VECTOR __interrupt void Timer_A(void) { switch(TAIV) { case 2://捕获/比较1中断 { break; } case 4://捕获/比较2中断 break; case 10: //TAIFG定时器溢出中断 temp_flag ++ ; break; } } /***************************************************************************** 定时器B中断函数 多中断源:CC1~6 TB ******************************************************************************/ #pragma vector=TIMERB1_VECTOR __interrupt void TimerB1() { switch (__even_in_range(TBIV, 14)) { case 2: //捕获/比较1中断 break; case 4: //捕获/比较2中断 break; case 6://捕获/比较3中断 break; case 8://捕获/比较4中断 break; case 10://捕获/比较5中断 break; case 12://捕获/比较6中断 break; case 14: //TBIFG定时器溢出中断 //-start-溢出中断代码执行段----------------------------------------// switch(INT_count) { case 0: //数码管显示 if(LED_enable==1) { LED_L_OUT=LED_didg[LED_count]; if(LED_stat[LED_count]!=0&&flash_ctrl==1) //如果不为熄灭且闪烁控制标志为1 LED_H_OUT=LED_segment[LED_DATA[LED_count]]; else LED_H_OUT=0x00; } break; case 1: //数码管闪烁控制 if(flash_stat==1) { time_count++; if(LED_stat[LED_count]==1) flash_ctrl=1; if(LED_stat[LED_count]==2) { if(time_count<250) flash_ctrl=0; else flash_ctrl=1; } time_count%=500; if(t_flag==1) { time_count1++; time_count1 %= 0xFFFF; } } break; case 2: //键盘扫描 if((BUTTON_IN&BIT0)==0&&KEY_enable==1)//当有按键按下的时候 { KEY_temp[KEY_count]=KEY_segment[LED_count]; KEY_count++; KEY_count%=2; if(KEY_temp[1]==KEY_temp[0]) { KEY_count2++; if(KEY_count2==3) { KEY_stat=KEY_DOWN; KEY_code=KEY_query(KEY_temp[1]); } if(KEY_count2==8) { KEY_count2=0; KEY_stat=KEY_UP; KEY_temp[1]=0x00; KEY_temp[0]=0xff; } } } KEY_count%=320; LED_count++; LED_count%=8; break; } INT_count++; INT_count%=3; //-end-溢出中断代码执行段-----------------------------------------// break; } //LPM3_EXIT; //退出中断后退出低功耗模式。若退出中断后要保留低功耗模式,将本句屏蔽 } /***************************************************************************** 比较器A中断函数 ******************************************************************************/ #pragma vector=COMPARATORA_VECTOR __interrupt void ComparatorA() { //capA_flag = 1; //比较器标志置位 _NOP(); } /*****************************************************************************/ //键盘任务分配 void KEY_task(void) { if(KEY_stat==KEY_DOWN) { switch(KEY_code) { case 1: temp_num = 1; //DS18B20_ReadTemp(BIT0); clear_LED(); // LED_DATA[7]=1; KEY_stat=KEY_UP; break; case 2: temp_num = 2; //DS18B20_ReadTemp(BIT0); clear_LED(); //LED_DATA[7]=2; KEY_stat=KEY_UP; break; case 3: //clear_LED(); // LED_DATA[7]=3; //KEY_stat=KEY_UP; break; case 4: //clear_LED(); //LED_DATA[7]=4; // KEY_stat=KEY_UP; break; case 5: break; case 6: break; case 7: break; case 8: break; default: break; } } } //LED清零 void clear_LED(void) { uchar i; for(i = 0; i < 8; i++) { LED_DATA[i] = 0; } } //********************* DS18B20功能函数定义***********************************// // DS18B20 初始化 //Intialization the 1-wire devices; unsigned char DS18B20_Init(void) { unsigned char result; DS18B20_DIR |= DS18B20_DQ; // ow output DS18B20_OUT &= ~DS18B20_DQ; // DS18B20_DQ=0; delay_us(480); //Delay480us; // Bus master pulling low 480us minimum; DS18B20_OUT |= DS18B20_DQ; // DS18B20_DQ=1; delay_us(60); //Delay60us; // Resister pull up 15-60us; DS18B20_DIR &= ~DS18B20_DQ; // ow input result = DS18B20_IN & DS18B20_DQ; DS18B20_DIR |= DS18B20_DQ; // ow output delay_us(480); //Delay480us; // End of timeslot total 480us; return(result); // any 1 wire device ?result:=1 no devide; ?result:=0 have device; } //Read a bit on the 1-wire bus; unsigned char DS18B20_ReadBit(void) { unsigned char result; DS18B20_DIR |= DS18B20_DQ; // ow output DS18B20_OUT &= ~DS18B20_DQ; // DS18B20_DQ=0; _NOP(); _NOP(); _NOP(); _NOP(); // Start of timeslot; DS18B20_OUT |= DS18B20_DQ; // DS18B20_DQ=1; _NOP(); _NOP(); _NOP(); _NOP(); // Wait from the start; DS18B20_DIR &= ~DS18B20_DQ; // ow input result = DS18B20_IN & DS18B20_DQ; DS18B20_DIR |= DS18B20_DQ; // ow output return(result); // return the result of the 1-wire devide; } //Write a bit to the 1-wire bus; void DS18B20_WriteBit(unsigned char oww_dat) { DS18B20_DIR |= DS18B20_DQ; // low output DS18B20_OUT &= ~DS18B20_DQ; // DS18B20_DQ=0; if (oww_dat == 1) { DS18B20_OUT |= DS18B20_DQ; // DS18B20_DQ=1; } else { DS18B20_OUT &= ~DS18B20_DQ; // DS18B20_DQ=0; } delay_us(100); //Delay100us; // Remain the state for 100us; DS18B20_OUT |= DS18B20_DQ; // DS18B20_DQ=1; } //Read a byte from the 1-wire bus; unsigned char DS18B20_ReadByte(unsigned char BIT_px) { unsigned char i; unsigned char result = 0; unsigned char result_temp; for(i = 0; i < 8; i++) { result_temp = DS18B20_ReadBit(); if(result_temp & BIT_px) { result |= 0x01 << i; } delay_us(120); //Delay120us; } return(result); // return the result of the 1-wire device; } //Write a byte to the 1-wire bus; void DS18B20_WriteByte(unsigned char oww_dat) { unsigned char i,temp; for(i = 0; i < 8; i++) { temp = oww_dat >> i; temp &= 0x01; DS18B20_WriteBit(temp); } delay_us(70); //Delay70us; } void DS18B20_ReadTemp(unsigned char BIT_px) { unsigned char tempH,tempL; DS18B20_Init(); DS18B20_WriteByte(SkipRom); _NOP(); //There is just one DS1820 on the bus; DS18B20_WriteByte(ConvertTemperature); delay_us(100); //Delay100us; //Start to convert temperature; DS18B20_Init(); DS18B20_WriteByte(SkipRom); _NOP(); DS18B20_WriteByte(ReadScratchpad); GetScratchpad[0]=DS18B20_ReadByte(BIT_px); //Master samples the LSB temperature from the scratchpad; GetScratchpad[1]=DS18B20_ReadByte(BIT_px); //Master samples the MSB temperature from the scratchpad; GetScratchpad[2]=DS18B20_ReadByte(BIT_px); //Master samples the TH register or userbyte1 from the scratchpad; GetScratchpad[3]=DS18B20_ReadByte(BIT_px); //Master samples the TL register or userbyte0 from the scratchpad; GetScratchpad[4]=DS18B20_ReadByte(BIT_px); //Master samples the configuration register from the scratchpad; GetScratchpad[5]=DS18B20_ReadByte(BIT_px); //Master samples the reservedbyte from the scratchpad; GetScratchpad[6]=DS18B20_ReadByte(BIT_px); //Master samples the reservedbyte from the scratchpad; GetScratchpad[7]=DS18B20_ReadByte(BIT_px); //Master samples the reservedbyte from the scratchpad; GetScratchpad[8]=DS18B20_ReadByte(BIT_px); //Master samples the CRC from the scratchpad; if(Verify_CRC8() == GetScratchpad[8]) //CRC校验 { tempH=(GetScratchpad[1] << 4) | (GetScratchpad[0] >> 4); tempL=(GetScratchpad[0] & 0x0f); DS18B20_Init(); //Issue a reset to terminate left parts; if(tempH & 0x80) { tempH=~tempH; tempL=~tempL+1; ResultSignal=1; //Negative temperature; } ResultTemperatureH = tempH; ResultTemperatureLL = decimalL[tempL]; ResultTemperatureLH = decimalH[tempL]; //Result of temperature; } } //CRC校验 unsigned char Verify_CRC8() //效验成功则crc返回0 { unsigned char i,x,crc,crcbuff; crc=0; for(x = 0; x <8; x++) { crcbuff = GetScratchpad[x]; for(i = 0; i < 8; i++) // { if(((crc ^ crcbuff)&0x01)==0) // crc >>= 1; else { //0001 1000 crc ^= 0x18; // crc >>= 1; crc |= 0x80; //1000 0000 // } crcbuff >>= 1; } } return crc; }

Top_arrow
回到顶部
EEWORLD下载中心所有资源均来自网友分享,如有侵权,请发送举报邮件到客服邮箱bbs_service@eeworld.com.cn 或通过站内短信息或QQ:273568022联系管理员 高员外,我们会尽快处理。