⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 叶风 - 利用pid算法和pwm调制实现温度自动控制的源程序.htm

📁 一个经典的PID算法实例 很有参考价值 C语言实现
💻 HTM
📖 第 1 页 / 共 3 页
字号:
            delay(5);&nbsp;&nbsp;&nbsp;/*延时90us供DA18B20采样*/<BR>&nbsp;&nbsp;&nbsp; 
            DQ=1;&nbsp;&nbsp;/*释放DQ总线*/<BR>&nbsp;&nbsp;&nbsp; 
            _nop_();<BR>&nbsp;&nbsp;&nbsp; _nop_();<BR>&nbsp;&nbsp; 
            EA=1;<BR>&nbsp;&nbsp; 
            }<BR>/***********************************************************<BR>写一字节数据子程序<BR>***********************************************************/<BR>void 
            write_byte(unsigned char val)<BR>&nbsp;{<BR>&nbsp; unsigned char 
            i;<BR>&nbsp; unsigned char temp;<BR>&nbsp; EA=0;<BR>&nbsp; 
            TR0=0;<BR>&nbsp; 
            for(i=0;i&lt;8;i++)&nbsp;&nbsp;/*写一字节数据,一次写一位*/<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            temp=val&gt;&gt;i;&nbsp;&nbsp;/*移位操作,将本次要写的位移到最低位*/<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            temp=temp&amp;1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            write_bit(temp);&nbsp;&nbsp;/*向总线写该位*/<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>&nbsp;&nbsp; 
            delay(7);&nbsp;&nbsp;&nbsp;/*延时120us后*/<BR>&nbsp;// TR0=1;<BR>&nbsp; 
            EA=1;<BR>&nbsp; 
            }<BR>/***********************************************************<BR>读一位数据子程序<BR>***********************************************************/<BR>unsigned 
            char read_bit()<BR>&nbsp;{<BR>&nbsp; unsigned char 
            i,value_bit;<BR>&nbsp; EA=0;<BR>&nbsp; 
            DQ=0;&nbsp;&nbsp;&nbsp;/*拉低DQ,开始读时序*/<BR>&nbsp; _nop_();<BR>&nbsp; 
            _nop_();<BR>&nbsp; DQ=1;&nbsp;&nbsp;&nbsp;/*释放总线*/<BR>&nbsp; 
            for(i=0;i&lt;2;i++){}&nbsp;</P>
            <P>&nbsp; value_bit=DQ;<BR>&nbsp; EA=1;<BR>&nbsp; 
            return(value_bit);<BR>&nbsp; 
            }<BR>/***********************************************************<BR>读一字节数据子程序<BR>***********************************************************/<BR>unsigned 
            char read_byte()<BR>&nbsp; {<BR>&nbsp;&nbsp; unsigned char 
            i,value=0;<BR>&nbsp;&nbsp; EA=0;<BR>&nbsp;&nbsp; 
            for(i=0;i&lt;8;i++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            if(read_bit())&nbsp;&nbsp;/*读一字节数据,一个时序中读一次,并作移位处理*/<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            value|=0x01&lt;&lt;i;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            delay(4);&nbsp;&nbsp;/*延时80us以完成此次都时序,之后再读下一数据*/<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>&nbsp;&nbsp; EA=1;<BR>&nbsp;&nbsp; return(value);<BR>&nbsp; 
            }<BR>/***********************************************************<BR>复位子程序<BR>***********************************************************/<BR>unsigned 
            char reset()<BR>&nbsp; {<BR>&nbsp;&nbsp; unsigned char 
            presence;<BR>&nbsp;&nbsp; EA=0;<BR>&nbsp;&nbsp; 
            DQ=0;&nbsp;&nbsp;&nbsp;/*拉低DQ总线开始复位*/<BR>&nbsp;&nbsp; 
            delay(30);&nbsp;&nbsp;&nbsp;/*保持低电平480us*/<BR>&nbsp;&nbsp; 
            DQ=1;&nbsp;&nbsp;&nbsp;/*释放总线*/<BR>&nbsp;&nbsp; 
            delay(3);&nbsp;&nbsp;&nbsp;</P>
            <P>&nbsp;&nbsp; 
            presence=DQ;&nbsp;&nbsp;&nbsp;/*获取应答信号*/<BR>&nbsp;&nbsp; 
            delay(28);&nbsp;&nbsp;&nbsp;/*延时以完成整个时序*/<BR>&nbsp;&nbsp; 
            EA=1;<BR>&nbsp;&nbsp; 
            return(presence);&nbsp;&nbsp;/*返回应答信号,有芯片应答返回0,无芯片则返回1*/<BR>&nbsp; 
            }<BR>/***********************************************************<BR>获取温度子程序<BR>***********************************************************/<BR>void 
            get_temper()<BR>&nbsp;{<BR>&nbsp; unsigned char i,j;<BR>&nbsp; 
            do<BR>&nbsp; {<BR>&nbsp;&nbsp;&nbsp; 
            i=reset();&nbsp;&nbsp;/*复位*/<BR>&nbsp; 
            }while(i!=0);&nbsp;&nbsp;/*1为无反馈信号*/<BR>&nbsp; 
            i=0xcc;&nbsp;&nbsp;/*发送设备定位命令*/<BR>&nbsp; write_byte(i);<BR>&nbsp; 
            i=0x44;&nbsp;&nbsp;/*发送开始转换命令*/<BR>&nbsp; write_byte(i);<BR>&nbsp; 
            delay(180);&nbsp;&nbsp;/*延时*/<BR>&nbsp; do<BR>&nbsp; {<BR>&nbsp; 
            i=reset();&nbsp;&nbsp;/*复位*/<BR>&nbsp; 
            }while(i!=0);&nbsp;&nbsp;<BR>&nbsp; 
            i=0xcc;&nbsp;&nbsp;/*设备定位*/<BR>&nbsp; write_byte(i);<BR>&nbsp; 
            i=0xbe;&nbsp;&nbsp;/*读出缓冲区内容*/<BR>&nbsp; write_byte(i);<BR>&nbsp; 
            j=read_byte();&nbsp;<BR>&nbsp; 
            i=read_byte();&nbsp;&nbsp;&nbsp;<BR>&nbsp; 
            i=(i&lt;&lt;4)&amp;0x7f;&nbsp;<BR>&nbsp; s=(unsigned 
            int)(j&amp;0x0f);<BR>&nbsp; s=(s*100)/16;<BR>&nbsp; 
            j=j&gt;&gt;4;<BR>&nbsp; temper=i|j;<BR>&nbsp; 
            }<BR>/*====================================================================================================<BR>Initialize 
            PID 
            Structure<BR>=====================================================================================================*/<BR>void 
            PIDInit (struct PID *pp)<BR>{<BR>&nbsp;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-&gt;SetPoint - NextPoint; // 偏差<BR>pp-&gt;SumError += 
            Error; // 积分<BR>dError = pp-&gt;LastError - pp-&gt;PrevError; // 
            当前微分<BR>pp-&gt;PrevError = pp-&gt;LastError;<BR>pp-&gt;LastError = 
            Error;<BR>return (pp-&gt;Proportion * Error // 比例项<BR>+ 
            pp-&gt;Integral * pp-&gt;SumError // 积分项<BR>+ pp-&gt;Derivative * 
            dError); // 微分项<BR>}</P>
            <P>/***********************************************************<BR>温度比较处理子程序<BR>***********************************************************/<BR>compare_temper()<BR>{<BR>&nbsp; 
            unsigned char i;<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
            if(set_temper&gt;temper)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            if(set_temper-temper&gt;1)&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            high_time=100;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            low_time=0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            for(i=0;i&lt;10;i++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            {&nbsp; 
            get_temper();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            rin = s; // Read 
            Input<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            rout = PIDCalc ( &amp;spid,rin ); // Perform PID 
            Interation<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            if 
            (high_time&lt;=100)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            high_time=(unsigned 
            char)(rout/800);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            high_time=100;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            low_time= 
            (100-high_time);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else 
            if(set_temper&lt;=temper)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            if(temper-set_temper&gt;0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            high_time=0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            low_time=100;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            for(i=0;i&lt;10;i++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            {&nbsp; 
            get_temper();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            rin = s; // Read 
            Input<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            rout = PIDCalc ( &amp;spid,rin ); // Perform PID 
            Interation<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            if 
            (high_time&lt;100)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            high_time=(unsigned 
            char)(rout/10000);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            high_time=0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            low_time= 
            (100-high_time);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp; 
            else<BR>&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            {}<BR>&nbsp;&nbsp;&nbsp; 
            }<BR>/*****************************************************<BR>T0中断服务子程序,用于控制电平的翻转&nbsp;,40us*100=4ms周期<BR>******************************************************/<BR>void 
            serve_T0() interrupt 1 using 1<BR>&nbsp; {<BR>&nbsp;&nbsp; 
            if(++count&lt;=(high_time))<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
            output=1;<BR>&nbsp;&nbsp; else 
            if(count&lt;=100)<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
            {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            output=0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp; 
            else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count=0;<BR>&nbsp;&nbsp; 
            TH0=0x2f;<BR>&nbsp;&nbsp; TL0=0xe0;<BR>&nbsp;&nbsp; 
            }<BR>/*****************************************************<BR>串行口中断服务程序,用于上位机通讯<BR>******************************************************/<BR>void 
            serve_sio() interrupt 4 using 2<BR>&nbsp; {<BR>/*&nbsp;&nbsp; 
            EA=0;<BR>&nbsp;&nbsp; RI=0;&nbsp;&nbsp;<BR>&nbsp;&nbsp; 
            i=SBUF;<BR>&nbsp;&nbsp; if(i==2)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            while(RI==0){}&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            RI=0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            set_temper=SBUF;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            SBUF=0x02;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            while(TI==0){}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            TI=0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>&nbsp;&nbsp;&nbsp; else 
            if(i==3)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            TI=0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            SBUF=temper;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            while(TI==0){}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            TI=0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -