完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
茶叶自动烘焙系统的研究与实现,研究了茶叶自动烘焙系统的基本原理和系统框图,通过温度检测模块,能实时检测三个不同温度数据,并将数据通过蓝牙模块传输到电脑。利用温度控制电路,采用PID算法、51单片机进行控制及数据处理,能精确实时控制温度。系统主要51单片机最小系统、蓝牙模块、温度传感模块、驱动显示电路、输出控制电路、电源电路、储存电路、报警电路和按键电路输出等组成。利用所设计出的茶叶自动烘焙系统,对烘焙中的茶叶采集温度,当时温度过高时能自动控制停止加温。此系统具有易控制、工作可靠、测量精度高的优点,可实时检测、控制。
电路总体方案 电路总体框图。在设计时我发现蓝牙模块适合传输小数据,相对Wifi来说,使用蓝牙不需要使用网络,因此采用蓝牙模块设计。与电脑和手机的连接都很方便。 主程序 主程序的主要功能是负责读出温度值、处理温度值、在LCD液晶屏上显示温度值和并控制子程序输出。按键设定温度,当温度传感器故障时,蜂鸣器发声报警,如果没有故障则正常显示,控制继电器开关。如图3.1主程序流程图。 温度设定子程序 温度设定子程序用于处理按键,用于设定想要设置的温度值 系统测试 4.1 模块测试 温度采集模块的测试:当实际温度值变化时,LCD同步显示实际温度,采集模块正常工作。 LCD显示测试:首先观察LCD有无外部损坏,接着上电,LCD液晶屏会显示温度1、温度2、温度3的温度,按下按键,观察显示屏上显示出的设置set1是否变换set2、set3。经测试可LCD显示屏正常工作。 按键测试:按键长按时,数据变动一次,按键短按时数据根据按按键的次数改变,经检测按键正常工作。 蜂鸣器发声测试:将温度传感模块拔掉模拟温度传感器故障,蜂鸣器发出报警的声音,蜂鸣器正常工作。 温度控制模块的测试:设置好设定温度,当茶叶实际温度低于设定温度,继电器打开,模拟开始加热茶叶温度,当茶叶实际温度等于或高于设定温度,继电器关闭,结果说明温度控制模块工作正常。 蓝牙模块测试:通过串口能将数据传输到电脑和手机上,蓝牙模块正常工作。 4.2 系统功能 开机后再液晶屏上显示当前的状态,包括实际温度与状态。通过独立按键设置需要达到的温度值,s3是加键,s4是减键,s5是确定键,s6是设置键,按确定键后,当实际温度小于设置温度时,屏幕显示加热与实际温度,并打开加热管控制继电器,当实际温度高于设置温度时,显示恒温与实际温度,并关闭加热管。当温度传感器故障时,在屏幕上显示液位异常,并蜂鸣器报警。不管在任何时候都可以对温度值进行设置,设置后马上更新状态。该毕业设计是一个硬件,里面有包括了单片机最小系统、蓝牙模块、温度传感模块、驱动显示电路、输出控制电路、电源电路、储存电路、报警电路和按键电路输出等各个系统和电路。因此,系统功能还包括复位功能,储存功能,报警功能,显示功能等各项。外部继电器控制好连接了一个加热管,实际上是由热得快做出来的,把热得快剪成两份,一份带着插头,另一份带着加热管,分开装进输出控制电路里,加热管由继电器控制开关,插头插在220V电源上,给加热管提供能量,由于安全原因,并没有直接测试加热功能。 部分代码 #include "LCD1602.h" #include "UART.H" #include #include #include #include struct PID { unsigned int SetPoint; // 设定目标 Desired Value unsigned int Proportion; // 比例常数 Proportional Const unsigned int Integral; // 积分常数 Integral Const unsigned int Derivative; // 微分常数 Derivative Const unsigned int LastError; // Error[-1] unsigned int PrevError; // Error[-2] unsigned int SumError; // Sums of Errors }; struct PID spid; // PID Control Structure unsigned int rout; // PID Response (Output) unsigned int rin; // PID Feedback (Input) unsigned char high_time,low_time,count=0;//占空比调节参数 unsigned char high_time1,low_time1,count1=0;//占空比调节参数 unsigned char high_time2,low_time2,count2=0;//占空比调节参数 ***it bell=P3^6; //蜂鸣器 ***it temper_relay=P2^3; //加热电磁阀 ***it temper_relay1=P2^4; //加热电磁阀 ***it temper_relay2=P2^5; //加热电磁阀 uint real_temper=0; //实际温度值 uint real_temper1=0; //实际温度值 uint real_temper2=0; //实际温度值 uchar eeprom_value=0,set_temper=0;//eeprom值与设置温度值 uchar eeprom_value1=0,set_temper1=0;//eeprom值与设置温度值 uchar eeprom_value2=0,set_temper2=0;//eeprom值与设置温度值 uchar Temper_Flag=0,keep_temp_flag=0; //温度检测与恒温标志 uchar Temper_Flag1=0,keep_temp_flag1=0; //温度检测与恒温标志 uchar Temper_Flag2=0,keep_temp_flag2=0; //温度检测与恒温标志 uchar select_set=0; uchar set_flag=0; //设置温度标志 uchar bell_count; //蜂鸣器报警数 uchar time_flag=0; //定时器初始化 50ms void Time_Init(void) { TMOD=0X01; TH0=(65536-1000)/256; TL0=(65536-1000)/256; ET0=1; EA=1; TR0=1; } void PIDInit (struct PID *pp) { memset ( pp,0,sizeof(struct PID)); } //PID计算部分 unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint ) { unsigned int dError,Error; Error = pp->SetPoint - NextPoint; // 偏差 pp->SumError += Error; // 积分 dError = pp->LastError - pp->PrevError; // 当前微分 pp->PrevError = pp->LastError; pp->LastError = Error; return (pp->Proportion * Error // 比例项 + pp->Integral*pp->SumError // 积分项 + pp->Derivative*dError); // 微分项 } //温度比较处理子程序 void compare_temper1(void) { unsigned char i; if((set_temper)>(real_temper/10)) { if((set_temper)-(real_temper/10)>1) //相差1度是开始PID调节 { high_time=100; //实际温度与设置温度低一度以上时一直开启加热 low_time=0; } else { for(i=0;i<10;i++) //计算10次 { EA=0; //关中断,防止影响读取数据 real_temper=DS18B20_Read_Tempereture(1); EA=1; rin = real_temper; // Read Input rout = PIDCalc ( &spid,rin ); // Perform PID Interation } if (high_time<=100) //换算调整值 high_time=(unsigned char)(rout/800); else high_time=100; low_time= (100-high_time); } } else if((set_temper)<=(real_temper/10)) //实际温度比设置温度高时关闭加热 { if((set_temper)-(real_temper/10)>0)//来回调整 { high_time=0; low_time=100; } else { for(i=0;i<10;i++) { EA=0; real_temper=DS18B20_Read_Tempereture(1); EA=1; rin = real_temper; // Read Input rout = PIDCalc ( &spid,rin ); // Perform PID Interation } if (high_time<100) high_time=(unsigned char)(rout/10000); else high_time=0; low_time= (100-high_time); } } } //温度比较处理子程序 //void compare_temper1(void) //{ // unsigned char i; // if((set_temper1)>(real_temper1/10)) // { // if((set_temper1)-(real_temper1/10)>1) //相差1度是开始PID调节 // { // high_time1=100; //实际温度与设置温度低一度以上时一直开启加热 // low_time1=0; // } // else // { // for(i=0;i<10;i++) //计算10次 // { // EA=0; //关中断,防止影响读取数据 // real_temper1=DS18B20_Read_Tempereture(2); // EA=1; // rin = real_temper1; // Read Input // rout = PIDCalc ( &spid,rin ); // Perform PID Interation // } // if (high_time1<=100) //换算调整值 // high_time1=(unsigned char)(rout/800); // else // high_time1=100; // low_time1= (100-high_time1); // } // } // else if((set_temper1)<=(real_temper1/10)) //实际温度比设置温度高时关闭加热 // { // if((set_temper1)-(real_temper1/10)>0)//来回调整 // { // high_time1=0; // low_time1=100; // } // else // { // for(i=0;i<10;i++) // { // EA=0; // real_temper1=DS18B20_Read_Tempereture(2); // EA=1; // rin = real_temper1; // Read Input // rout = PIDCalc ( &spid,rin ); // Perform PID Interation // } // if (high_time1<100) // high_time1=(unsigned char)(rout/10000); // else // high_time1=0; // low_time1= (100-high_time1); // } // } // } // //温度比较处理子程序 //void compare_temper1(void) //{ // unsigned char i; // if((set_temper2)>(real_temper2/10)) // { // if((set_temper2)-(real_temper2/10)>1) //相差1度是开始PID调节 // { // high_time2=100; //实际温度与设置温度低一度以上时一直开启加热 // low_time2=0; // } // else // { // for(i=0;i<10;i++) //计算10次 // { // EA=0; //关中断,防止影响读取数据 // real_temper2=DS18B20_Read_Tempereture(3); // EA=1; // rin = real_temper2; // Read Input // rout = PIDCalc ( &spid,rin ); // Perform PID Interation // } // if (high_time2<=100) //换算调整值 // high_time2=(unsigned char)(rout/800); // else // high_time2=100; // low_time2= (100-high_time2); // } // } // else if((set_temper2)<=(real_temper2/10)) //实际温度比设置温度高时关闭加热 // { // if((set_temper2)-(real_temper2/10)>0)//来回调整 // { // high_time2=0; // low_time2=100; // } // else // { // for(i=0;i<10;i++) // { // EA=0; // real_temper2=DS18B20_Read_Tempereture(3); // EA=1; // rin = real_temper2; // Read Input // rout = PIDCalc ( &spid,rin ); // Perform PID Interation // } // if (high_time2<100) // high_time2=(unsigned char)(rout/10000); // else // high_time2=0; // low_time2= (100-high_time2); // } // } // } // //从EEPROM中读取温度设置值 void Read_Set_EEPROM_Value(void) { set_temper=X24C02_Read(10); set_temper1=X24C02_Read(11); set_temper2=X24C02_Read(12); } //按键处理 温度值设定 void Set_Temper_Value(void) { uchar value_temp; value_temp=P3&0x3C; //根据按键连接口获取是否有按键按下 if(value_temp!=0x3c) { _delay_ms(5); //消抖 if(value_temp!=0x3c) //再次确认是否有键按下 { switch(value_temp) { case 0x38: //加键 if(set_flag==1) //只有在设置按键按下后有效 { if(select_set==1) { if(eeprom_value<99) //温度值上限99度 eeprom_value++; //设置温度值加 LCD_write_Num_1(13,1,eeprom_value,2); //显示设置温度值 } else if(select_set==2) { if(eeprom_value1<99) //温度值上限99度 eeprom_value1++; //设置温度值加 LCD_write_Num_1(13,1,eeprom_value1,2); //显示设置温度值 } else if(select_set==3) { if(eeprom_value2<99) //温度值上限99度 eeprom_value2++; //设置温度值加 LCD_write_Num_1(13,1,eeprom_value2,2); //显示设置温度值 } } break; case 0x34: //减键 if(set_flag==1) //只有在设置按键按下后有效 { if(select_set==1) { if(eeprom_value>0)//小于下限时 eeprom_value--; //设置温度值减 LCD_write_Num_1(13,1,eeprom_value,2); //显示设置温度值 } else if(select_set==2) { if(eeprom_value1>0)//小于下限时 eeprom_value1--; //设置温度值减 LCD_write_Num_1(13,1,eeprom_value1,2); //显示设置温度值 } else if(select_set==3) { if(eeprom_value2>0)//小于下限时 eeprom_value2--; //设置温度值减 LCD_write_Num_1(13,1,eeprom_value2,2); //显示设置温度值 } } break; case 0x2c: //确定 if(set_flag==1) //只有在设置按键按下后有效 { set_flag=0; //退出设置 LCD_write_str(8,1,"S: "); if(select_set==1) { X24C02_Write(10,eeprom_value); //将设置值写入EEPROM _delay_ms(5); //延迟EEPROM在写入后不能马上读,需要等待一定时间 Read_Set_EEPROM_Value(); //读取EEPROM 重新赋值设置比较值 } else if(select_set==2) { X24C02_Write(11,eeprom_value1); //将设置值写入EEPROM _delay_ms(5); //延迟EEPROM在写入后不能马上读,需要等待一定时间 Read_Set_EEPROM_Value(); //读取EEPROM 重新赋值设置比较值 } else if(select_set==3) { X24C02_Write(12,eeprom_value2); //将设置值写入EEPROM _delay_ms(5); //延迟EEPROM在写入后不能马上读,需要等待一定时间 Read_Set_EEPROM_Value(); //读取EEPROM 重新赋值设置比较值 } select_set=0; } break; case 0x1c: //设置 select_set++; if(select_set==4)select_set=1; set_flag=1; //进度设置 if(select_set==1) { LCD_write_str(8,1,"Set1: "); eeprom_value=X24C02_Read(10); //读取EEPROM中的值进行设置 LCD_write_Num_1(13,1,eeprom_value,2); //显示设置初始值 } else if(select_set==2) { LCD_write_str(8,1,"Set2: "); eeprom_value1=X24C02_Read(11); //读取EEPROM中的值进行设置 LCD_write_Num_1(13,1,eeprom_value1,2); //显示设置初始值 } else if(select_set==3) { LCD_write_str(8,1,"Set3: "); eeprom_value2=X24C02_Read(12); //读取EEPROM中的值进行设置 LCD_write_Num_1(13,1,eeprom_value2,2); //显示设置初始值 } break; } } while(value_temp!=0x3c)value_temp=P3&0x3C; //松手检测 } } //故障检测 void InDetect(void) { if(DS18B20_Init(1)!=0) //温度传感器故障 { Temper_Flag=1; //置标志 } else { Temper_Flag=0; } if(DS18B20_Init(2)!=0) //温度传感器故障 { Temper_Flag1=1; //置标志 } else { Temper_Flag1=0; } if(DS18B20_Init(3)!=0) //温度传感器故障 { Temper_Flag2=1; //置标志 } else { Temper_Flag2=0; } if((real_temper/10) keep_temp_flag=0; } else { keep_temp_flag=1; } if((real_temper1/10) keep_temp_flag1=0; } else { keep_temp_flag1=1; } if((real_temper2/10) keep_temp_flag2=0; } else { keep_temp_flag2=1; } } //状态显示 void State_Display(void) { InDetect(); //故障检测 if(set_flag==0)//没有设置时显示 { if((Temper_Flag==1)||(Temper_Flag1==1)||(Temper_Flag2==1)) { LCD_write_str(10,1,"Error "); //温度异常 } else { if((keep_temp_flag==0)||(keep_temp_flag1==0)||(keep_temp_flag2==0)) { LCD_write_str(10,1,"Hot ");//加热 } else { LCD_write_str(10,1,"Normal"); //正常 } } } } //输出蜂鸣器与继电器控制 void Output_Control(void) { if((Temper_Flag==1)||(Temper_Flag1==1)||(Temper_Flag2==1))//温度故障时报警 { bell_count=4; } else bell_count=0; } //设备初始化函数 void Device_Init(void) { Time_Init(); Init_uart(); LCD_init(); DS18B20_Init(1); DS18B20_Init(2); DS18B20_Init(3); LCD_write_str(0,0,"T1:"); LCD_write_str(9,0,"T2:"); LCD_write_str(0,1,"T3:"); LCD_write_str(8,1,"S: "); Read_Set_EEPROM_Value(); } //主函数 int main(void) { Device_Init(); //设备初始化 PIDInit ( &spid ); // 初始化PID spid.Proportion = 10; // Set PID Coefficients spid.Integral = 8; spid.Derivative =6; spid.SetPoint = 100; // Set PID Setpoint while(1) { if(time_flag==1) { time_flag=0; if((Temper_Flag==0)) //温度传感器无故障时 { EA=0; real_temper=DS18B20_Read_Tempereture(1); //读取温度值 EA=1; LCD_write_Num(3,0,real_temper,4); //显示温度值 printf("Temper1_Value=%frn",real_temper/10.0); } else { LCD_write_str(3,0,"Eor "); //温度传感器有故障时 printf("Temper1_Value=Error!rn"); } if((Temper_Flag1==0)) //温度传感器无故障时 { EA=0; real_temper1=DS18B20_Read_Tempereture(2); //读取温度值 EA=1; LCD_write_Num(12,0,real_temper1,4); //显示温度值 printf("Temper2_Value=%frn",real_temper1/10.0); } else { LCD_write_str(12,0,"Eor "); //温度传感器有故障时 printf("Temper2_Value=Error!rn"); } if((Temper_Flag2==0)) //温度传感器无故障时 { EA=0; real_temper2=DS18B20_Read_Tempereture(3); //读取温度值 EA=1; LCD_write_Num(3,1,real_temper2,4); //显示温度值 printf("Temper3_Value=%frn",real_temper2/10.0); } else { LCD_write_str(3,1,"Eor "); //温度传感器有故障时 printf("Temper3_Value=Error!rn"); } printf("==================================rn"); } State_Display(); Set_Temper_Value(); compare_temper1(); //compare_temper2(); //compare_temper3(); Output_Control(); } } //定时器中断 void Time0(void) interrupt 1 { static uchar count=0; static uint m=0; TH0=(65536-1000)/256; TL0=(65536-1000)/256; m++; count++; //count1++; //count2++; if(m==1000) //1S计时 { m=0; time_flag=1; if(bell_count>0) { bell=~bell;//蜂鸣器标志取反 bell_count--;//次数减少 } else bell=1;//次数到达时关闭蜂鸣器 } if(count<=(high_time)) temper_relay=0; else if(count<=100) { temper_relay=1; } else count=0; // if(count1<=(high_time1)) // temper_relay1=0; // else if(count<=100) // { // temper_relay1=1; // } // else // count1=0; // // if(count2<=(high_time2)) // temper_relay2=0; // else if(count2<=100) // { // temper_relay2=1; // } // else // count2=0; 电路图 系统设计图和电源模块: 温度控制模块 |
|
|
|
只有小组成员才能发言,加入小组>>
2513 浏览 0 评论
1085浏览 2评论
700浏览 1评论
453浏览 0评论
194浏览 0评论
330浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 11:58 , Processed in 1.394777 second(s), Total 81, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号