This system is a microcontroller temperature control system based on PID. I found a complete program on the Internet and made the corresponding proteus hardware simulation according to his program, but
It did not achieve the expected effect. It needs to be improved.
The procedure is as follows:
#include<reg51.h>
#include<intrins.h>
#include<math.h>
#include<string.h>
struct PID {
unsigned int SetPoint; // Set the target Desired Value
unsigned int Proportion; // Proportional Const
unsigned int Integral; // Integral constant Integral Const
unsigned int Derivative; // Derivative constant 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)
sbit data1=P1^0;
sbit clk=P1^1;
sbit plus=P2^0;
sbit subs=P2^1;
sbit stop=P2^2;
sbit output=P3^4;
sbit DQ=P3^3;
unsigned char flag,flag_1=0;
unsigned char high_time,low_time,count=0; //Duty cycle adjustment parameters
unsigned char set_temper=35;
unsigned char temper;
unsigned char i;
unsigned char j=0;
unsigned int s;
/***********************************************************
Delay subroutine, the delay time is based on the 12M crystal oscillator, the delay time is 30us×time
***********************************************************/
void delay(unsigned char time)
{
unsigned char m,n;
for(n=0;n<time;n++)
for(m=0;m<2;m++){}
}
/***********************************************************
Write a one-bit data subroutine
***********************************************************/
void write_bit(unsigned char bitval)
{
EA=0;
DQ=0; /*Pull DQ low to start a write sequence*/
if(bitval==1)
{
_nop_();
DQ=1; /*If you want to write 1, set the bus high*/
}
delay(5); /*Delay 90us for DA18B20 sampling*/
DQ=1; /*Release DQ bus*/
_nop_();
_nop_();
EA=1;
}
/***********************************************************
Write one byte data subroutine
***********************************************************/
void write_byte(unsigned char val)
{
unsigned char i;
unsigned char temp;
EA=0;
TR0=0;
for(i=0;i<8;i++) /*Write one byte of data, one bit at a time*/
{
temp=val>>i; /*Shift operation, move the bit to be written this time to the lowest bit*/
temp=temp&1;
write_bit(temp); /*Write this bit to the bus*/
}
delay(7); /*After delaying 120us*/
// TR0=1;
EA=1;
}
/***********************************************************
Read one bit of data subroutine
***********************************************************/
unsigned char read_bit()
{
unsigned char i,value_bit;
EA=0;
DQ=0; /*Pull DQ low to start reading timing*/
_nop_();
_nop_();
DQ=1; /*Release the bus*/
for(i=0;i<2;i++){}
value_bit=DQ;
EA=1;
return(value_bit);
}
/***********************************************************
Read one byte data subroutine
***********************************************************/
unsigned char read_byte()
{
unsigned char i,value=0;
EA=0;
for(i=0;i<8;i++)
{
if(read_bit()) /*Read one byte of data, read once in one sequence, and perform shifting processing*/
value|=0x01<<i;
delay(4); /*Delay 80us to complete this timing, and then read the next data*/
}
EA=1;
return(value);
}
/***********************************************************
reset subroutine
***********************************************************/
unsigned char reset()
{
unsigned char presence;
EA=0;
DQ=0; /*Pull the DQ bus low to start reset*/
delay(30); /*Keep low level for 480us*/
DQ=1; /*Release the bus*/
delay(3);
presence=DQ; /*Get response signal*/
delay(28); /*Delay to complete the entire sequence*/
EA=1;
return(presence); /*Return the response signal, if there is a chip, it returns 0, if there is no chip, it returns 1*/
}
/***********************************************************
Get temperature subroutine
***********************************************************/
void get_temper()
{
unsigned char i,j;
do
{
i=reset(); /*reset*/
}while(i!=0); /*1 is no feedback signal*/
i=0xcc; /*Send device positioning command*/
write_byte(i);
i=0x44; /*Send conversion command*/
write_byte(i);
delay(180); /*delay*/
do
{
i=reset(); /*reset*/
}while(i!=0);
i=0xcc; /*Device positioning*/
write_byte(i);
i=0xbe; /*Read buffer contents*/
write_byte(i);
j=read_byte();
i=read_byte();
i=(i<<4)&0x7f;
s=(unsigned int)(j&0x0f);
s=(s*100)/16;
j=j>>4;
temper=i|j; /*The obtained temperature is placed in temperature*/
}
/*====================================================================================================
Initialize PID Structure
=====================================================================================================*/
void PIDInit (struct PID *pp)
{
memset ( pp,0,sizeof(struct PID));
}
/*====================================================================================================
PID calculation part
=====================================================================================================*/
unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint )
{
unsigned int dError,Error;
Error = pp->SetPoint - NextPoint; // Deviation
pp->SumError += Error; // Points
dError = pp->LastError - pp->PrevError; // Current differential
pp->PrevError = pp->LastError;
pp->LastError = Error;
return (pp->Proportion * Error // Proportion term
+ pp->Integral * pp->SumError // Integral term
+ pp->Derivative * dError); // Differential term
}
/***********************************************************
Temperature comparison processing subroutine
***********************************************************/
compare_temper()
{
unsigned char i;
if(set_temper>temper)
{
if(set_temper-temper>1)
{
high_time=100;
low_time=0;
}
else
{
for(i=0;i<10;i++)
{
get_temper();
rin = s; // 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<=temper)
{
if(temper-set_temper>0)
{
high_time=0;
low_time=100;
}
else
{
for(i=0;i<10;i++)
{
get_temper();
rin = s; // 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);
}
}
// else
// {}
}
/*****************************************************
T0 interrupt service subroutine, used to control level flipping, 40us*100=4ms cycle
******************************************************/
void serve_T0() interrupt 1 using 1
{
if(++count<=(high_time))
output=1;
else if(count<=100)
{
output=0;
}
else
count=0;
TH0=0x2f;
TL0=0xe0;
}
/*****************************************************
Serial port interrupt service routine, used for host computer communication
******************************************************/
void serve_sio() interrupt 4 using 2
{
/* EA=0;
RI=0;
i=SBUF;
if(i==2)
{
while(RI==0){}
RI=0;
set_temper=SBUF;
SBUF=0x02;
while(TI==0){}
TI = 0;
}
else if(i==3)
{
TI = 0;
SBUF=temper;
while(TI==0){}
TI = 0;
}
EA=1; */
}
void disp_1(unsigned char disp_num1[6])
{
unsigned char n,a,m;
for(n=0;n<6;n++)
{
// k=disp_num1[n];
for(a=0;a<8;a++)
{
clk=0;
m=(disp_num1[n]&1);
disp_num1[n]=disp_num1[n]>>1;
if(m==1)
data1=1;
else
data1=0;
_nop_();
clk=1;
_nop_();
}
}
}
/*****************************************************
display subroutine
Function: Convert duty cycle temperature into a single character, display duty cycle and measured temperature
******************************************************/
void display()
{
unsigned char code number[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6};
unsigned char disp_num[6];
unsigned int k,k1;
k=high_time;
k=k%1000;
k1=k/100;
if(k1==0)
disp_num[0]=0;
else
disp_num[0]=0x60;
k=k%100;
disp_num[1]=number[k/10];
disp_num[2]=number[k%10];
k=temper;
k=k%100;
disp_num[3]=number[k/10];
disp_num[4]=number[k%10]+1;
disp_num[5]=number[s/10];
disp_1(disp_num);
}
/***********************************************************
main program
***********************************************************/
main()
{
unsigned char z;
unsigned char a,b,flag_2=1,count1=0;
unsigned char phil[]={2,0xce,0x6e,0x60,0x1c,2};;
TMOD=0x21;
TH0=0x2f;
TL0=0x40;
SCON=0x50;
PCON=0x00;
TH1=0xfd;
TL1=0xfd;
PS=1;
EA=1;
EX1=0;
ET0=1;
ES=1;
TR0=1;
TR1=1;
high_time=50;
low_time=50;
PIDInit ( &spid ); // Initialize Structure
spid.Proportion = 10; // Set PID Coefficients
spid.Integral = 8;
spid.Derivative =6;
spid.SetPoint = 100; // Set PID Setpoint
while(1)
{
if(plus==0)
{
EA=0;
for(a=0;a<5;a++)
for(b=0;b<102;b++){}
if(plus==0)
{
set_temper++;
flag=0;
}
}
else if(subs==0)
{
for(a=0;a<5;a++)
for(b=0;a<102;b++){}
if(subs==0)
{
set_temper--;
flag=0;
}
}
else if(stop==0)
{
for(a=0;a<5;a++)
for(b=0;b<102;b++){}
if(stop==0)
{
flag=0;
break;
}
EA=1;
}
get_temper();
b=temper;
if(flag_2==1)
{
a=b;
}
if((abs(a-b))>5)
{
temper=a;
}
else
{
temper=b;
}
a=temper;
flag_2=0;
if(++count1>30)
{
display();
count1=0;
}
compare_temper();
}
TR0=0;
z=1;
while(1)
{
EA=0;
if(stop==0)
{
for(a=0;a<5;a++)
for(b=0;b<102;b++){}
if(stop==0)
disp_1(phil);
// break;
}
EA=1;
}
}
Previous article:51 microcontroller learning: light up the first LED
Next article:The design of 51 microcontroller to display 0-7 in sequence on 8-bit digital tube
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- 【NUCLEO-L552ZE Review】- 7 : EXTI - One unexpected thing after another
- Issues that should be paid attention to when drawing PCB diagrams from the perspective of welding
- Can anyone help analyze the parameters of this DC-DC transformer?
- In the 5G era, IoT technology empowers smart healthcare
- 【TouchGFX Design】(2) Simple interface design
- Sony HT-Z9F speaker system disassembled with Rockchip RKNanoD chip
- [Rvb2601 Creative Application Development] lvgl Usage 2 - Drawing
- [DWIN Serial Port Screen] Nucleic Acid Sampling and Registration System - Three Links to DWIN Cloud
- Help! Why can the command sent by the microcontroller only display up to the fourth step?
- Future Outlook of IoT