该项目是本人在刚结束的一学期中的一门课的一个小小的课程设计。
基本功能是能够控制被控对象的温度,我完成后是一定程度上可以控制水温。项目整体较为简单。下面分别讲解硬件部分和软件部分。
上图是该项目的大致方案描述。项目整体较为简单。下面分别讲解硬件部分和软件部分。
该部分对主要硬件部分简单描述:
开发板 :项目中使用的是正点原子NANOSTM32开发板;该开发板功能较为齐全,适合初学者使用。
K型热点偶:温度采集模块,项目采用的是K型热电偶,其线性度较好,测温范围宽且价格低廉。K型热电偶的输出一般非常微弱,常为毫伏级,需要放大处理。
DS18B20温度传感器:测量温度范围为-55~+125℃ ,精度为±0.5℃。现场温度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性。本项目中使用DS18B20测量环境温度来做冷端补偿。
ADS1230:ADS1230是一种精度为20位的模数转换器(ADC),其同时也有信号放大功能,放大增益可设置为64和128两种。
继电器与加热片:本项目使用继电器与陶瓷加热片组成温控系统的执行器部分,继电器通过控制陶瓷加热片的通断从而控制陶瓷加热片是否在加热。
unsigned long Read_ADS1230(u8 Cal)
{
u8 Bit_count;
unsigned long AD_data=0;
Dir_out();
SCLK_0;
delayad(20);
DOUT_1;
Dir_in();
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0));//wait DRDY goto LOW 等待DRDY变低
for(Bit_count=0;Bit_count<20;Bit_count++)//20bit retrieval 读取20位AD数据
{
AD_data<<=1;//left move 1 bit 左移一位
SCLK_1;
delayad(1);
SCLK_0;
delayad(1);
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0))//判断数据口电平,获取一位数据
{AD_data|=0x00000001 ;
}
else
AD_data&=0xFFFFFFFE;
}
if(Cal==1)//offset calibration校准
{
DOUT_1;
for(Bit_count=21;Bit_count<26;Bit_count++)//空跑4个时钟
{
SCLK_1;
delayad(1);
SCLK_0;
delayad(1);
}
}
return AD_data;
}
以上部分代码为读取ADS1230模数转换器将模拟电压量转换成数字电压量的数字量。
#define N 12
u32 filter()
{
vu32 sum=0;
for(count=0;count<N;count++)
{
ADC_VALUE=Read_ADS1230(1);//读取ADS1230 ADC数据并执行校准
ADC_VALUE&=0X000FFFFF;
if(ADC_VALUE>=0x80000) ADC_VALUE=0;
sum+=ADC_VALUE;
}
return (sum/N);
}
以上代码为软件滤波部分,本次项目中采用的是限制均值滤波,当ADS1230每采集12次数字电压量后,将数字电压量取均值,将其均值作为一次采集的数字电压量,且限制ADC采集的数字量值在其最大值以下。这样的滤波对于偶然出现的脉冲干扰,可消除由于脉冲干扰所引起的采样偏差。这样就可以得到较为稳定的电压值。
shuju=filter();
zhenshi=(0.5*3.3*shuju/524287/64)*1000;
这两句代码通过公式将数字电压值传变为模拟电压值。从而得到数字电压对应的模拟电压值。
while(DS18B20_Init()) //DS18B20初始化
{
delay_ms(200);
LED3=!LED3;//LED3闪烁表示DS18B20初始化失败
}
temp_t++;
if(temp_t==500) //DS18B20 1S采样
{
temp_t=0;
temperature=DS18B20_Get_Temp();//获取温度值
if(temperature<0)//若温度为负数
{
temperature=-temperature;
flag=1;
}else flag=0;
}
delay_us(1000);
temp=temperature;
temp=temp/10;
以上代码为DS18B20温度传感器测得环境温度值temp。
float fendubiao[60]={0.000,0.397,0.789,1.203,1.612,2.023,2.436,2.851,3.267,3.682,4.096,4.509,4.920,5.328,5.735,6.138,6.540,6.941,7.340,7.739,8.138,8.539,8.940,9.343,9.747,10.153,10.561,10.971,11.382,11.795,12.209,12.624,13.040,13.457,13.874,14.293,14.713,15.133,15.554,15.975,16.397,16.820,17.243,17.667,18.091,18.516,18.941,19.366,19.792,20.218,20.644,21.071,21.497,21.924,22.350,22.776,23.203,23.629,24.055,24.480};//镍铬-镍硅热电偶分度表。
for(i=0;i<60;i++)
{
if(temp>=(i*10.0)&&temp<=(i+1)*10.0)
{
fendudianya1=((fendubiao[i+1]-fendubiao[i])/10.0)*(temp-(i*10.0))+fendubiao[i];
dianya=zhenshi+fendudianya1;
break;
}
}
delay_us(2);
for(i=0;i<60;i++)
{
if(dianya>=fendubiao[i]&&dianya<=fendubiao[i+1])
{
wendu1=(10.0/(fendubiao[i+1]-fendubiao[i]))*(dianya-fendubiao[i]);
wendu2=i*10.0+wendu1;
celiangwendu=wendu2;
break;
}
}
delay_us(2);
以上代码为通过DS18B20温度传感器测得的室温进行热电偶冷端补偿后测得的最终的准确的热电偶测量温度。具体过程为,将DS18B20测得的室温在K型热电偶分度表中进行查表得到补偿电势,将补偿电势与热电偶直接测得模拟电压取和,之后将和值进行反查表,得到最终的热电偶测量温度。
LCD_Clear(WHITE);
Display_ALIENTEK_LOGO(0, 0);
POINT_COLOR = RED;
BACK_COLOR = WHITE;
sprintf(aa,"%5.2f",temp);
sprintf(bb,"%5.2f",celiangwendu);
LCD_ShowString(0,100,100,16,16,"Ambient T:");
LCD_ShowString(0,140,100,16,16,"Observed T:");
LCD_ShowString(100,95,200,32,24,aa);
LCD_ShowString(100,135,200,32,24,bb);
if(m==500) {LCD_Fill(100,100,200,123,WHITE);LCD_Fill(100,140,200,173,WHITE);m=0; }
以上代码为液晶屏显示部分,可以设置背景颜色,字体颜色,字体大小等。
此代码可以将DS18B20测得的室温及最后冷端补偿过后热电偶测得的最终的测量温度动态显示在显示屏上面。根据需求,可以将自己设计的logo放置在显示屏上面。
switch(smg_wei)
{
case 0: num = smg_num[0]; break;//电压整数值
case 1: num = smg_num[zhenshi_z/10/10/10%10];break;
case 2: num = smg_num[zhenshi_z/10/10%10];break;
case 3: num = smg_num[zhenshi_z/10%10];break;
case 4: num = smg_num[zhenshi_z%10]+smg_num[16]; break;
case 5: num = smg_num[zhenshi_x/10/10%10]; break; //电压小数值
case 6: num = smg_num[zhenshi_x/10%10]; break;
case 7: num = smg_num[zhenshi_x%10]; break;
}
LED_Write_Data(num,smg_wei);//数码管显示
LED_Refresh();//刷新显示
smg_wei++;
if(smg_wei==8) smg_wei=0;
此部分代码为数码管显示部分,其功能为将热电偶直接的到的电压值显示在数码管上面,起着检测热电偶工作情况的辅助作用。
关于串口的上位机程序,是使用LABVIEW写出来的上位机程序,我参考了其他博主上面的例程,LABVIEW程序链接
可以得到下位机通过串口传输过来的实际测量温度的值,以及得到实时的测量温度曲线。为监测温度变化提供了极大的便利。
GPIOC->CRH&=0XFFFFFFF0;
GPIOC->CRH|=0X00000006;//PC08
PCout(8)=1; //初始化部分代码
#define kongzhiliang 33.0
if(celiangwendu<kongzhiliang)
{
PCout(8)=0;
}
else
PCout(8)=1;//控制通断部分代码
以上部分代码为将PC8引脚作为继电器的数据输入引脚。通过引脚输出的高低电平从而控制继电器的通断,硬件上使用继电器将陶瓷加热片进行连接,从而通过输出的高低电平控制加热片是否加热。本代码为当测量温度小于控制量时继电器闭合,加热片开始加热,测量温度大于控制量时,加热片停止加热。
1.若有侵权,联系删除。
2.软件代码部分,不建议直接复制,因为我并没有写出全部代码,且讲述是按照逻辑顺序讲述。完整项目代码(包括单片机代码和上位机的LABVIEW代码),我会在之后的评论中分享。
3.文章中若存在错误,请各路高手予以指出。
4.第一次写博客,还请多多支持。