"); //-->
#include <C8051F020.H>
#include <string.h>
#include <math.h>
//void PIDInit(PID *PP);
/*定义结构体和公用体*/
#define N 8
typedef struct PID{
unsigned int setpoint; /*设定值*/
unsigned int proportion; /*比例系数*/
unsigned int integral; /*积分系数*/
unsigned int derivative; /*微分系数 */
unsigned int lasterror; /*前一拍误差*/
unsigned int preerror; /*前两拍误差*/
}PID;
union stu{
unsigned int value;
unsigned char num[2];
}laser;
union dat{
unsigned char dd[2];
unsigned int number;
}collect;
/*函数声明部分*/
unsigned int PIDcal(PID *pp,int thiserror);
void PIDInit(PID *PP);
void PortInit(void);
unsigned int get_ad(void);
unsigned int filter_valve(void);
void Delayms(void);
/*主函数部分*/
void main(void)
{
PID vPID; /*定义结构体变量名*/
unsigned int verror;
unsigned int Error;
unsigned int tempi;
unsigned char LASERH,LASERL; /*误差的高低字节变量*/
WDTCN=0xde;
WDTCN=0xad;
//portinit();
PIDInit(&vPID);
vPID.proportion=10; /*设置PID比例系数为10*/
vPID.integral=10; /*设定PID积分系数 为10*/
vPID.derivative=10; /*设定PID微分系数为10*/
vPID.setpoint=50; /*根据实际情况设定*/
IE= 0x80;
while(1)
{
verror=filter_valve(); /*得到AD的滤波输出值 */
Error=vPID.setpoint-verror; /*得到误差值*/
tempi=PIDcal(&vPID,Error); /*调用PID算法函数 得到误差增量*/
laser.value+=tempi;
LASERH=laser.num[0]; /*value与num[2]为共同体,变量名为laser*/
LASERL=laser.num[1]; /*存放高低字节*/
}
}
/*PID算法函数,返回误差增量*/
unsigned int PIDcal(PID *pp,int thisError){
unsigned int pError,dError,iError;
unsigned int templ;
pError=thisError-pp->lasterror;
iError=thisError;
dError=thisError-2*(pp->lasterror)+pp->preerror;
templ=pp->proportion*pError+pp->integral*iError+pp->derivative*dError; /*增量计算*/
pp->preerror=pp->lasterror; /*存放误差用于下次运算*/
pp->lasterror=thisError;
return ((int)(templ>>8));
}
/*测量值*/
/*float measure(void) 已知A B 角为锐角
{ /* COSA=1/7 SIN(A+B)=14分之5倍根号3 */
/*long float value; /*求COSB*/
/*float A,B;
A=acos(1/7);
B=asin((5/14)*sqrt(3))-A;
if((0<A<pi/2)&&(0<B<pi/2)) return cos(B);
} */
/*得到ADC转换值*/
unsigned int get_ad(void)
{
while(AD0INT==0);
{
AD0INT=0;
collect.dd[1]=ADC0H;
collect.dd[0]=ADC0L;
return (collect.number);
}
}
void Timer3_ISR(void) interrupt 14
{
TMR3CN=0x7f;
//AMUX0SL=0x00;
AD0BUSY=1;
}
void Timer3_Init(unsigned char Highcounts,unsigned char Lowcounts)
{
TMR3CN=0x01; /*禁止定时器3;清TF3,采用SYSCLK为时基*/
TMR3RLH=-Highcounts; /*初始化重装载值*/
TMR3RLL=-Lowcounts;
TMR3L=0xff; /*设置为立即重装在*/
TMR3H=0xff;
EIE2|= 0x01; /*允许定时3中断*/
TMR3CN|=0x06; /*启动定时器3*/
}
void ADCInit(void)
{
ADC0CF=0x00; /*选择ADC0的转换始终为系统时钟,增益为1*/
ADC0CN=0xc0; /*允许ADC0准备转换,定义低功耗跟踪方式,置AD0BUSY位为1启动ADC,寄存器数据右对齐*/
AMX0CF=0x01; /*选择AIN0和AIN!为通道0差分输入的正负端*/
}
/*PID初始化*/
void PIDInit(PID *PP)
{
memset(PP,0,sizeof(PID));
}
/*数字算术滤波子程序*/
unsigned int filter_valve(void)
{
unsigned char i,j,temp;
unsigned char count;
unsigned int valve_buf[N];
unsigned int sum=0;
for(count=0;count<N;count++)
{
valve_buf[count]=get_ad();
Delayms();
}
for(j=0;j<N-1;j++)
{ for(i=0;i<N-j;i++)
{
if(valve_buf[i]>valve_buf[i+1])
{
temp=valve_buf[i];
valve_buf[i]=valve_buf[i+1];
valve_buf[i+1]=temp;
}
}
}
for(count=1;count<N-1;count++)
{
sum+=valve_buf[count];
return (unsigned int)(sum/(N-2));
}
}
/*延时子程序*/
void Delayms(void)
{
unsigned int ms;
unsigned char i;
while(ms--)
{
for(i=0;i<120;i++);
}
}
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。