仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png (31.12 KB, 下載次數: 68)
下載附件
2021-5-25 21:08 上傳
51hei.png (32.17 KB, 下載次數: 58)
下載附件
2021-5-25 21:08 上傳
51hei截圖20210525142227.png (32.31 KB, 下載次數: 56)
下載附件
Proteus圖
2021-5-25 14:27 上傳
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
51hei截圖20210525142500.png (162.56 KB, 下載次數: 53)
下載附件
原理圖
2021-5-25 14:28 上傳
51hei.png (31.94 KB, 下載次數: 54)
下載附件
2021-5-25 21:09 上傳
PCB圖.jpg (347.51 KB, 下載次數: 53)
下載附件
2021-5-25 21:09 上傳
單片機源程序如下:
- #include <REGX51.H>
- #define Kp 5 //比例系數
- #define Ki 2 //積分系數
- #define Kd 1 //微分系數
- unsigned char m,n,p; //溫度的十位 個位 小數
- unsigned char test_temp; //溫度檢定標志
- unsigned char key_set_flag; //按鍵設定進入標志
- unsigned char flag=1; //按鍵保持標志
- unsigned char Change_step=1,e; //溫度設置步進
- unsigned char T0_H = 0,T0_L = 0,T1_H=0,T1_L=0;
- int Real_temp; //實際溫度值
- int Set_temp; //設置溫度
- int Disp_temp; //顯示溫度
- int last_error; //上次誤差
- float I_term; //前面溫差和
- bit key_hold;
- int PID_MAX;
- unsigned int out,PWMT,counter,kk,outp,dz;
- int time; //脈沖觸發時刻
- sbit DQ=P2^4; //定義DS18b20的管腳
- sbit RS = P2^0; //定義液晶屏定義端口
- sbit RW = P2^1; //定義液晶屏定義端口
- sbit EN = P2^2; //定義液晶屏定義端口
- sbit k1=P1^0;
- sbit k2=P1^1;
- sbit k3=P1^2;
- sbit PWM=P2^7; //PWM控制腳
- sbit led1=P3^5;
- sbit led2=P3^6;
- sbit led3=P3^7;
- sbit beep=P1^3;
- #define RS_CLR RS=0
- #define RS_SET RS=1
- #define RW_CLR RW=0
- #define RW_SET RW=1
- #define EN_CLR EN=0
- #define EN_SET EN=1
- unsigned char aa[]={' ',' ','S','e','t','u','p',':',' ',' ','.',' ',' ',' ',' ',' '}; //Distance
- unsigned char bb[]={' ',' ',' ',' ',' ',' ',' ','.',' ',' ',' ',' ',' ',' ',' ',' '};
- void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s);
- void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data);
- void init(); //初始化
- /*------------------------------------------------
- uS延時函數,含有輸入參數 unsigned char t,無返回值
- unsigned char 是定義無符號字符變量,其值的范圍是
- 0~255 這里使用晶振12M,精確延時請使用匯編,大致延時
- 長度如下 T=tx2+5 uS
- ------------------------------------------------*/
- void DelayUs2x(unsigned char t)
- {
- while(--t);
- }
- /*------------------------------------------------
- mS延時函數,含有輸入參數 unsigned char t,無返回值
- unsigned char 是定義無符號字符變量,其值的范圍是
- 0~255 這里使用晶振12M,精確延時請使用匯編
- ------------------------------------------------*/
- void DelayMs(unsigned char t)
- {
- while(t--) //大致延時1mS
- {
- DelayUs2x(245);
- DelayUs2x(245);
- }
- }
- /*****延時子程序*****/
- void delay(unsigned int t)
- {
- for(;t>0;t--);
- }
- void delay_50us(unsigned int t)
- {
- unsigned char j;
- for(;t>0;t--)
- for(j=19;j>0;j--);
- }
- /*****初始化DS18B20*****/
- unsigned char Init_DS18B20(void)
- {
- unsigned char x=0;
- DQ = 1; //DQ復位
- delay(8); //稍做延時
- DQ = 0; //單片機將DQ拉低
- delay(80); //精確延時,大于480us
- DQ = 1; //拉高總線
- delay(8);
- x = DQ; //稍做延時后,如果x=0則初始化成功,x=1則初始化失敗
- delay(4);
- return x;
- }
- /*****讀一個字節*****/
- unsigned char ReadOneChar(void)
- {
- unsigned char i=0;
- unsigned char dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; // 給脈沖信號
- dat>>=1;
- DQ = 1; // 給脈沖信號
- if(DQ)
- dat|=0x80;
- delay(4);
- }
- return(dat);
- }
- /*****寫一個字節*****/
- void WriteOneChar(unsigned char dat)
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- delay(4);
- DQ = 1;
- dat>>=1;
- }
- delay(4);
- }
- /*****讀取溫度*****/
- int ReadTemperature(void)
- {
- unsigned char a=0;
- unsigned char b=0;
- unsigned int t=0;
- t=Init_DS18B20();
- if(t) return Real_temp;
- WriteOneChar(0xCC); //跳過讀序號列號的操作
- WriteOneChar(0x44); //啟動溫度轉換
- t=Init_DS18B20();
- if(t) return Real_temp;
- WriteOneChar(0xCC); //跳過讀序號列號的操作
- WriteOneChar(0xBE); //讀取溫度寄存器
- a=ReadOneChar(); //讀低8位
- b=ReadOneChar(); //讀高8位
- t=b;
- t<<=8;
- t=t|a;
- if(t<=0||t>0x900)
- return Real_temp;
- t=t*0.625+0.5;
- return(t);
- }
- void key_set(void)
- {
- if(k1==0)
- {
- delay(10);
- while(!k1);
- key_hold=~key_hold;
- }
- if(key_hold==0)
- {
- if(k2==0)
- {
- delay(10);
- while(!k2);
- Set_temp=Set_temp+1;
- if(Set_temp>99)
- Set_temp=99;
- }
- if(k3==0)
- {
- delay(10);
- while(!k3);
- Set_temp=Set_temp-1;
- if(Set_temp<1)
- Set_temp=1;
- }
- aa[8]=10*Set_temp/100+'0';
- aa[9]=10*Set_temp/10%10+'0';
- aa[11]=10*Set_temp%10+'0';
- LCD_Write_String(0,0,aa);
- }
- }
- int PID(int Set_value,int Real_value) //標準PID溫度控制算法
- {
- float uk ,uk1 ,duk;
- int pid_out,e ,e1 ,e2;
- e=Set_value-Real_value;//誤差量
- duk=Kp*(e-e1)+Ki*e+Kd*(e-2*e1+e2); //+Kd*(e-2e1+e2)
- uk=uk1+duk;
- pid_out=(int)uk;
- uk1=uk;
- e2=e1;
- e1=e;
- if(pid_out>1000)
- {
- pid_out=998;
- }
- else if(pid_out<2)
- {
- pid_out=2;
- }
- outp=pid_out;
- return(pid_out);
-
- }
- void T0_int(void) interrupt 1
- {
- T0_H = (65535-2000)/256; //PWM=1高位初值計算
- T0_L = (65535-2000)%256; //PWM=1低位初值計算
- TH0 = T0_H; //通的初值高位
- TL0= T0_L; //通的初值低位
- kk++;
- if(kk>1000)
- kk=0;
- if(kk>outp)
- PWM=1;
- else PWM=0;
- // }
- }
- void main()
- {
- PWMT=128; //128級步進PWM控制
- PID_MAX=PWMT;
- counter=0;
- out=0;
- PWM=1;
- I_term=0;
- last_error=0;
- Set_temp=30; //初始設定溫度為30度
- init();
- Real_temp=Set_temp*10;
- key_hold=1;
- Init_DS18B20();
- WriteOneChar(0xCC); //跳過讀序號列號的操作
- WriteOneChar(0x44); //啟動溫度轉換
- delay_50us(150); //等待溫度測量 delay_50us(15000);
- TMOD=0x01; //定時器0模式1
- TR0=1;
- ET0=1;
- IT0=1;
- EX0=1;
- EA=1;
- aa[12]=0xdf;
- aa[13]=0x43;
- bb[9]=0xdf;
- bb[10]=0x43;
- aa[8]=10*Set_temp/100+'0';
- aa[9]=10*Set_temp/10%10+'0';
- aa[11]=10*Set_temp%10+'0';
- LCD_Write_String(0,0,aa);
- while(1)
- {
- counter++;
- DelayMs(500);
- if(counter>4)
- {
- test_temp=1; //進行一次溫度檢定
- counter=0;
- }
- if(test_temp) //溫度檢定標志置位,進入溫度PID調節
- {
- Real_temp=ReadTemperature(); //采集當前實際溫度
- test_temp=0; //檢定完成,清溫度檢定標志
- bb[5]=Real_temp/100+'0';
- bb[6]=Real_temp/10%10+'0';
- bb[8]=Real_temp%10+'0';
- LCD_Write_String(0,1,bb);
- if((Real_temp/10)<(Set_temp))
- {
- beep=~beep;
- led1=~led1;
- led2=1;
- }
- else if((Real_temp/10)>(Set_temp))
- {
- beep=~beep;
- led3=~led3;
- led2=1;
- }
- else
- {
- beep=1;
- led1=1;
- led2=0;
- led3=1;
- }
- }
- if((Real_temp/10)<(Set_temp-1))
- {
- outp=998;
- }
- else if((Real_temp/10)>(Set_temp+1))
- {
- outp=2;
- }
- else
- {
- PID(Set_temp*10,Real_temp); //PID程序
- }
-
- key_set(); //按鍵溫度設置
- }
- }
- ///////////////////////////////////////////////////
- // 液晶屏顯示處理
- ///////////////////////////////////////////////////
- void write_com(unsigned char com) //寫命令
- {
- RS_CLR;
- RW_CLR;
- P0=com;
- DelayMs(1);
- EN_SET;
- DelayMs(1);
- EN_CLR;
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
51hei.png (13.73 KB, 下載次數: 53)
下載附件
2021-5-25 21:10 上傳
所有資料51hei提供下載:
程序仿真.zip
(426.9 KB, 下載次數: 305)
2021-5-25 14:31 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|