|
- #include<reg52.h>
- #include<serial.h>
- #include<math.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define target 65 //設(shè)定溫度目標(biāo)值
- int aa=0,bb=0; // aa,bb是用于顯示時(shí)間的變量
- signed long error=0,d_error=0,dd_error=0; //相當(dāng)于公式中的e(k),e(k-1),e(k-2);
- int k=14,ti=5;td=16,det_t,pwm,m=0;
- //unsigned char YSJS=0;
- float t;
- uint tmpvalue=0, value; //tmpvalue是暫時(shí)值 value是最終溫度值
- int high,low;
- sbit P23=P2^3;
- sbit P22=P2^2;
- sbit DQ = P2^1; //P2.1作為連接DS18B20的I/O口
- sbit p0=P1^0;
- sbit p1=P1^1;
- sbit p2=P1^2;
- sbit p3=P1^3; //P1.3和P1.4作為升溫電路的控制端
- sbit p4=P1^4;
- sbit p5=P1^5; //P1.5~P1.7控制八個(gè)七段數(shù)碼管的亮滅
- sbit p6=P1^6;
- sbit p7=P1^7;
-
- void delayms(int o) //用于數(shù)碼管顯示的延時(shí)
- {
- unsigned char a1,b1,c1;
- int x=o;
- for(;o>0;o--)
- for(c1=4;c1>0;c1--)
- for(b1=21;b1>0;b1--)
- for(a1=14;a1>0;a1--);
- }
- void init() //定時(shí)器初始化
- {
- TMOD=0x21;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- EA=1;
- ET0=1;
- TR0=1;
- }
-
- /***************八段管顯示碼***************/
- code uchar LEDmap[] ={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};
- code uchar BITaddr[] ={0x0f, 0x2f, 0x4f, 0x6f, 0x8f, 0xaf, 0xdf, 0xef}; //數(shù)碼管位選地址
- uchar code LEDmap1[] ={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //帶小數(shù)點(diǎn)數(shù)字編碼
- /***************ds18b20的程序***************/
- void delay(unsigned int i)
- {
- while(i--);
- }
- void Init_DS18B20(void)
- {
- unsigned char x=0;
- DQ = 1; //DQ復(fù)位
- delay(8); //稍做延時(shí)
- DQ = 0; //單片機(jī)將DQ拉低
- delay(80); //精確延時(shí) 大于 480us
- DQ = 1; //拉高總線
- delay(14);
- x=DQ; //稍做延時(shí)后 如果x=0則初始化成功 x=1則初始化失敗
- delay(20);
- }
- //讀一個(gè)字節(jié)
- int ReadOneChar()
- {
- unsigned char i=0;
- unsigned char dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; // 給脈沖信號(hào)
- dat>>=1;
- DQ = 1; // 給脈沖信號(hào)
- if(DQ)
- dat|=0x80;
- delay(4);
- }
- return(dat);
- }
- //寫一個(gè)字節(jié)
- void WriteOneChar(unsigned char dat)
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- delay(5);
- DQ = 1;
- dat>>=1;
- }
- }
- //DS18B20程序讀取溫度
- void ReadTemperature()
- {
- Init_DS18B20();
- WriteOneChar(0xCC); // 跳過讀序號(hào)列號(hào)的操作
- WriteOneChar(0x44); // 啟動(dòng)溫度轉(zhuǎn)換
- Init_DS18B20();
- WriteOneChar(0xCC); //跳過讀序號(hào)列號(hào)的操作
- WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個(gè)寄存器) 前兩個(gè)就是溫度
- low=ReadOneChar();
- high=ReadOneChar();
- tmpvalue = high;
- tmpvalue =(tmpvalue<<8);
- tmpvalue=tmpvalue | low;
- value=tmpvalue*0.0625;
- t=tmpvalue*0.625;
- }
- /***************主函數(shù)****************/
- void main()
- {
- int i=0;
- init(); //初始化子程序
- uart_init();
- P23 = 1;
- P22 = 1;
- delayms(9500);
- P23 = 0;
- P22 = 0;
- while(1)
- {
-
- if((bb%3)==0) //每三秒掃描一次 ,采樣周期3s
- {
- dd_error=d_error;
- d_error=error;
- error = (signed long)(target-value);//求e(k) //求e(k-1) //求e(k-2)
- det_t=k*(error-d_error)+(k*3/ti)*error+(k*td/3)*(error-2*d_error+dd_error); //增量公式 */
- // det_t=20*(error-d_error)+0.15*error+10*(error-2*d_error+dd_error); //增量公式 */
- pwm=det_t;
- if((error>10)||(pwm>60))pwm=60;
- }
- ReadTemperature();
- p5=0;p6=0;p7=0;P0=LEDmap[bb%10];delayms(1); //在數(shù)碼管上顯示時(shí)間
- p5=1;p6=0;p7=0;P0=LEDmap[bb%100/10];delayms(1);
- p5=0;p6=1;p7=0;P0=LEDmap[bb%1000/100];delayms(1);
- p5=1;p6=1;p7=0;P0=LEDmap[bb/1000];delayms(1); //
- p5=0;p6=0;p7=1;P0=LEDmap[(int)t%10];delayms(1); //溫度小數(shù)顯示
- p5=1;p6=0;p7=1;P0=LEDmap1[value%10];delayms(1); //溫度個(gè)位及小數(shù)點(diǎn)顯示
- p5=0;p6=1;p7=1;P0=LEDmap[value%100/10];delayms(1); //溫度十位顯示
- if(i++>100)
- {
- Uart_SendChar(0x5a);
- Uart_SendChar(value%100/10);
- Uart_SendChar(value%10);
- Uart_SendChar((int)t%10);
- Uart_SendChar(0);
- i=0;
- }
-
- }
- }
- void timer0() interrupt 1
- {
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- aa++;
- if(aa==20){aa=0;bb++;} //計(jì)時(shí)1s
- if(m<pwm){p3=1;p4=1;} //電機(jī)啟動(dòng),加熱
- if((m>=(pwm))||(value>=target)){p3=0;p4=0;} //電機(jī)關(guān)閉,停止加熱
- if(m==60)m=0;
- m++;
- }
復(fù)制代碼
從硬件電路開始學(xué)習(xí),然后編寫程序?qū)訜岜瓋?nèi)的水溫進(jìn)行控制。能夠完成水溫在65攝氏度的穩(wěn)定性實(shí)驗(yàn),并計(jì)算了超調(diào)和穩(wěn)態(tài)誤差。升溫速率可以為1--4度/分鐘,分階段升溫。編制了信號(hào)采樣程序,轉(zhuǎn)換顯示以及在數(shù)碼管上時(shí)鐘顯示(秒表)。達(dá)到設(shè)定溫度穩(wěn)定后加入擾動(dòng),控制加熱算法,使其快速達(dá)到溫度設(shè)定值。
|
|