?? 葉風 - 利用pid算法和pwm調制實現溫度自動控制的源程序.htm
字號:
delay(5); /*延時90us供DA18B20采樣*/<BR>
DQ=1; /*釋放DQ總線*/<BR>
_nop_();<BR> _nop_();<BR>
EA=1;<BR>
}<BR>/***********************************************************<BR>寫一字節數據子程序<BR>***********************************************************/<BR>void
write_byte(unsigned char val)<BR> {<BR> unsigned char
i;<BR> unsigned char temp;<BR> EA=0;<BR>
TR0=0;<BR>
for(i=0;i<8;i++) /*寫一字節數據,一次寫一位*/<BR>
{<BR>
temp=val>>i; /*移位操作,將本次要寫的位移到最低位*/<BR>
temp=temp&1;<BR>
write_bit(temp); /*向總線寫該位*/<BR>
}<BR>
delay(7); /*延時120us后*/<BR> // TR0=1;<BR>
EA=1;<BR>
}<BR>/***********************************************************<BR>讀一位數據子程序<BR>***********************************************************/<BR>unsigned
char read_bit()<BR> {<BR> unsigned char
i,value_bit;<BR> EA=0;<BR>
DQ=0; /*拉低DQ,開始讀時序*/<BR> _nop_();<BR>
_nop_();<BR> DQ=1; /*釋放總線*/<BR>
for(i=0;i<2;i++){} </P>
<P> value_bit=DQ;<BR> EA=1;<BR>
return(value_bit);<BR>
}<BR>/***********************************************************<BR>讀一字節數據子程序<BR>***********************************************************/<BR>unsigned
char read_byte()<BR> {<BR> unsigned char
i,value=0;<BR> EA=0;<BR>
for(i=0;i<8;i++)<BR>
{<BR>
if(read_bit()) /*讀一字節數據,一個時序中讀一次,并作移位處理*/<BR>
value|=0x01<<i;<BR>
delay(4); /*延時80us以完成此次都時序,之后再讀下一數據*/<BR>
}<BR> EA=1;<BR> return(value);<BR>
}<BR>/***********************************************************<BR>復位子程序<BR>***********************************************************/<BR>unsigned
char reset()<BR> {<BR> unsigned char
presence;<BR> EA=0;<BR>
DQ=0; /*拉低DQ總線開始復位*/<BR>
delay(30); /*保持低電平480us*/<BR>
DQ=1; /*釋放總線*/<BR>
delay(3); </P>
<P>
presence=DQ; /*獲取應答信號*/<BR>
delay(28); /*延時以完成整個時序*/<BR>
EA=1;<BR>
return(presence); /*返回應答信號,有芯片應答返回0,無芯片則返回1*/<BR>
}<BR>/***********************************************************<BR>獲取溫度子程序<BR>***********************************************************/<BR>void
get_temper()<BR> {<BR> unsigned char i,j;<BR>
do<BR> {<BR>
i=reset(); /*復位*/<BR>
}while(i!=0); /*1為無反饋信號*/<BR>
i=0xcc; /*發送設備定位命令*/<BR> write_byte(i);<BR>
i=0x44; /*發送開始轉換命令*/<BR> write_byte(i);<BR>
delay(180); /*延時*/<BR> do<BR> {<BR>
i=reset(); /*復位*/<BR>
}while(i!=0); <BR>
i=0xcc; /*設備定位*/<BR> write_byte(i);<BR>
i=0xbe; /*讀出緩沖區內容*/<BR> write_byte(i);<BR>
j=read_byte(); <BR>
i=read_byte(); <BR>
i=(i<<4)&0x7f; <BR> s=(unsigned
int)(j&0x0f);<BR> s=(s*100)/16;<BR>
j=j>>4;<BR> temper=i|j;<BR>
}<BR>/*====================================================================================================<BR>Initialize
PID
Structure<BR>=====================================================================================================*/<BR>void
PIDInit (struct PID *pp)<BR>{<BR> memset ( pp,0,sizeof(struct
PID));<BR>}<BR>/*====================================================================================================<BR>PID計算部分<BR>=====================================================================================================*/</P>
<P>unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint
)<BR>{<BR>unsigned int dError,Error;</P>
<P>Error = pp->SetPoint - NextPoint; // 偏差<BR>pp->SumError +=
Error; // 積分<BR>dError = pp->LastError - pp->PrevError; //
當前微分<BR>pp->PrevError = pp->LastError;<BR>pp->LastError =
Error;<BR>return (pp->Proportion * Error // 比例項<BR>+
pp->Integral * pp->SumError // 積分項<BR>+ pp->Derivative *
dError); // 微分項<BR>}</P>
<P>/***********************************************************<BR>溫度比較處理子程序<BR>***********************************************************/<BR>compare_temper()<BR>{<BR>
unsigned char i;<BR>
if(set_temper>temper)<BR>
{<BR>
if(set_temper-temper>1) <BR>
{<BR>
high_time=100;<BR>
low_time=0;<BR>
}<BR>
else<BR>
{<BR>
for(i=0;i<10;i++)<BR>
{
get_temper();<BR>
rin = s; // Read
Input<BR>
rout = PIDCalc ( &spid,rin ); // Perform PID
Interation<BR>
}<BR>
if
(high_time<=100)<BR>
high_time=(unsigned
char)(rout/800);<BR>
else<BR>
high_time=100;<BR>
low_time=
(100-high_time);<BR>
}<BR>
}<BR> else
if(set_temper<=temper)<BR>
{<BR>
if(temper-set_temper>0)<BR>
{<BR>
high_time=0;<BR>
low_time=100;<BR>
}<BR>
else<BR>
{<BR>
for(i=0;i<10;i++)<BR>
{
get_temper();<BR>
rin = s; // Read
Input<BR>
rout = PIDCalc ( &spid,rin ); // Perform PID
Interation<BR>
}<BR>
if
(high_time<100)<BR>
high_time=(unsigned
char)(rout/10000);<BR>
else<BR>
high_time=0;<BR>
low_time=
(100-high_time);<BR>
}<BR>
}<BR> //
else<BR> //
{}<BR>
}<BR>/*****************************************************<BR>T0中斷服務子程序,用于控制電平的翻轉 ,40us*100=4ms周期<BR>******************************************************/<BR>void
serve_T0() interrupt 1 using 1<BR> {<BR>
if(++count<=(high_time))<BR>
output=1;<BR> else
if(count<=100)<BR>
{<BR>
output=0;<BR> }<BR>
else<BR> count=0;<BR>
TH0=0x2f;<BR> TL0=0xe0;<BR>
}<BR>/*****************************************************<BR>串行口中斷服務程序,用于上位機通訊<BR>******************************************************/<BR>void
serve_sio() interrupt 4 using 2<BR> {<BR>/*
EA=0;<BR> RI=0; <BR>
i=SBUF;<BR> if(i==2)<BR>
{<BR>
while(RI==0){} <BR>
RI=0;<BR>
set_temper=SBUF; <BR>
SBUF=0x02; <BR>
while(TI==0){}<BR>
TI=0;<BR>
}<BR> else
if(i==3) <BR>
{<BR>
TI=0;<BR>
SBUF=temper;<BR>
while(TI==0){}<BR>
TI=0;<BR>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -