#include
#include "i2c.h"
#include "delay.h"
#include "display.h"
#include "math.h"
#define uchar unsigned char
#define uint unsigned int
#define AddWr 0x90 //写数据地址
#define AddRd 0x91 //读数据地址
void timer0_init(); //定时器0初始化
void motor_run();
void control();
uchar time;
uint motor_pwm;
double count=0; //定义占空比,并初始占空比为26%
sbit PWM=P2^3;
sbit Motor_CW=P2^4;
sbit Motor_CCW=P2^5;
float angleset=50;
float angel;
uint nowerror;
long sumerror;
uint lasterror;
float output;
float kp=0.56,ki=0.008,kd=1;
extern bit ack;
bit flag;
//bit WriteDAC(unsigned char dat);
/*------------------------------------------------
主程序
------------------------------------------------*/
uchar ReadADC(uchar Chl)
{
uchar val;
Start_I2c();
SendByte(AddWr);
if(ack==0)return (0);
SendByte(Chl);
if(ack==0)return (0);
Start_I2c();
SendByte(AddRd);
if(ack==0)return (0);
val=RcvByte();
NoAck_I2c();
Stop_I2c();
return(val);
}
void motor_run(uint pwm)
{
if(time { PWM=1; }else { PWM=0; } if(time>100) { time=0; flag=1; } } /****************************pid*****************************/ void timer0_init() { TMOD=0x01; //定时器0工作于方式1 TH0=(65536-100)/256; TL0=(65536-100)%256; TR0=1; ET0=1; EA=1; } /**************定时0中断处理******************/ void timer0_int() interrupt 1 { TR0=0; //设置定时器初值期间,关闭定时器 TH0=(65536-100)/256; TL0=(65536-100)%256; TR0=1; time++; motor_run(motor_pwm); } uint XIANFU_Pwm(uint pwm) { if ( pwm <0) pwm = 0; if (pwm>=100) pwm= 100; return pwm; } float PID_Control(float angleset,float angel) { angel=ReadADC(0x40); nowerror=angleset-angel;//当前误差 sumerror+=nowerror; //误差求和 if(sumerror>2500) sumerror=2500;//限幅 output = kp*nowerror+ki*sumerror+kd*(lasterror-nowerror); lasterror=nowerror; return output;//增量输出 } void control() { motor_pwm=(uint) PID_Control(angleset,angel); motor_pwm= XIANFU_Pwm(motor_pwm); //motor_run(motor_pwm); } main() { float angleAD; Motor_CW=0; //电机正反转 Motor_CCW=1; timer0_init(); while(1) { if(flag==1) { flag=0; control(); } angleAD = ReadADC(0x40); //绝对角度数字值AD值 display(angleAD); //WriteDAC(angleAD); } }
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』