#include "config.h"
#include <math.h>
#define ADC_POWER 0x80
#define ADC_FLAG 0x10
#define ADC_START 0x08
#define ADC_SPEEDLL 0x00
#define ADC_SPEEDL 0x20
#define ADC_SPEEDH 0x40
#define ADC_SPEEDHH 0x60
unsigned char idata RsBuf[MAC_RX_BUF];
unsigned char data guc_RsPoint=0;
//unsigned char xdata Time0L1;
//unsigned char xdata Time0H1;
unsigned char xdata led_step=0;
unsigned char xdata led_show1;
unsigned char xdata led_show2;
unsigned char xdata led_show3;
unsigned char xdata led_show4;
unsigned int xdata Time_Show=0;
unsigned int xdata TimeMotor=0;
unsigned int xdata PwmBitVat=0;
//unsigned short xdata ADC_VAL[3];
//unsigned char xdata ADC_ch=0;
bit led_dian1;
bit led_dian2;
bit led_dian3;
bit led_dian4;
bit RsOver=0;
typedef struct _pid_t
{
float SetSpeed;//定义设定值
float ActualSpeed;//定义实际值
float err;//定义偏差值
float err_last;//定义上一个偏差值
float Kp,Ki,Kd;//定义比例、积分、微分系数
float voltage;//定义电压值(控制执行器的变量)
float integral;//定义积分值
float umax;
float umin;
} pid_t;
unsigned char code ledTab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x27,0x7f,0x6f};
void PID_init(pid_t *npid)
{
npid->SetSpeed=0.0;
npid->ActualSpeed=0.0;
npid->err=0.0;
npid->err_last=0.0;
npid->voltage=0.0;
npid->integral=0.0;
npid->Kp=0.2;
npid->Ki=0.015;
npid->Kd=0.2;
npid->umax=127;
npid->umin=-127;
}
float PID_realize(pid_t *npid ,float speed,float ActualSpeed)
{
float index;
npid->SetSpeed=speed;
npid->ActualSpeed=ActualSpeed;
npid->err=npid->SetSpeed-npid->ActualSpeed;
if(npid->voltage>npid->umax)
{
if(abs(npid->err)>200)//变积分过程
{
index=0.0;
}
else if(abs(npid->err)<180)
{
index=1.0;
if(npid->err<0)
{
npid->integral+=npid->err;
}
}
else
{
index=(200-abs(npid->err))/20;
if(npid->err<0)
{
npid->integral+=npid->err;
}
}
}
else if(npid->voltage<npid->umin)
{
if(abs(npid->err)>200)//变积分过程
{
index=0.0;
}
else if(abs(npid->err)<180)
{
index=1.0;
if(npid->err>0)
{
npid->integral+=npid->err;
}
}
else
{
index=(200-abs(npid->err))/20;
if(npid->err>0)
{
npid->integral+=npid->err;
}
}
}
else
{
if(abs(npid->err)>200)//变积分过程
{
index=0.0;
}
else if(abs(npid->err)<180)
{
index=1.0;
npid->integral+=npid->err;
}
else
{
index=(200-abs(npid->err))/20;
npid->integral+=npid->err;
}
}
npid->voltage=npid->Kp*npid->err+index*npid->Ki*npid->integral+npid->Kd*(npid->err-npid->err_last);
npid->err_last=npid->err;
return npid->voltage;
}
void Delay_n_ms(unsigned int dly)
{
unsigned int j;
do
{
j = MAIN_Fosc / 13000; //延时1ms, 主程序在此节拍下运行
while(--j) ;
}while(--dly);
}
void InitUart(void)
{
SCON = 0x50;//工作在串口模式
T2L = (65536 - (MAIN_Fosc/4/BAUD)); //设置波特率为重新装值
T2H = (65536 - (MAIN_Fosc/4/BAUD))>>8;
AUXR |= 0x14; //启用定时器T2为1T模式, 并启用定时器2
AUXR |= 0x01; //选择定时器2为串口1的波特率发生器
ES = 1; //使能串口1为中断
}
void InitTime0(void)
{
// #if 0
// AUXR |= (1<<7); // Timer0 set as 1T mode
// TMOD = 0x01; //16位,
// //Timer0_16bit();
// Time0L1=(65536-(MAIN_Fosc/1000000)*(TIME0_us1))%256;
// Time0H1=(65536-(MAIN_Fosc/1000000)*(TIME0_us1))/256;
// TL0=Time0L1;
// TH0=Time0H1;
// #endif
T0_Load_us_12T(TIME0_us1);
ET0 = 1; //Timer0 Interrupt Enable
PT0 = 1; //高优先级
TR0 = 1; //Timer0 Run
}
// ADC初始化函数
void ADC_Init(void)
{
// ADC_ch=0;
// P1ASF=0x30;//设置P1为ADC
// //P1ASF|=(1<<4)|(1<<5);
// ADC_RES=0; // 清除结果寄存器
// ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ADC_START|4;
// Delay_n_ms(20);
// EADC=1;// EADC=1 允许ADC中断
//查询方式
P1ASF=0x30;//设置P1为ADC
ADC_RES=0;
ADC_RESL=0;
ADC_CONTR=ADC_POWER|ADC_SPEEDLL;
Delay_n_ms(20);
}
void SendTxdBuf(unsigned char ASC) //发送-个ASCII
{
ES = 0; //关闭串口中断
SBUF = ASC;
while(TI ==0); //
TI = 0; //
ES = 1; //允许串口中断
}
void Rs_Do(void) interrupt 4 using 1 // 通讯中断接收程序
{
unsigned char data luc_temp;
if(RI==1)
{
RI=0;
luc_temp = SBUF;
if(guc_RsPoint>=MAC_RX_BUF)
guc_RsPoint=0;
if(luc_temp==0x0d)
{
RsBuf[guc_RsPoint] = 0x0d;
guc_RsPoint = 0;
RsOver = 1;
}
else
{
RsBuf[guc_RsPoint++]=luc_temp;
}
}
}
void ledTime()
{
switch(led_step)
{
case 0:
DIG1=1;
DIG2=0;
DIG3=0;
DIG4=0;
P2=ledTab[led_show1];
led_di=led_dian1;
led_step=1;
break;
case 1:
DIG1=0;
DIG2=1;
DIG3=0;
DIG4=0;
P2=ledTab[led_show2];
led_di=led_dian2;
led_step=2;
break;
case 2:
DIG1=0;
DIG2=0;
DIG3=1;
DIG4=0;
P2=ledTab[led_show3];
led_di=led_dian3;
led_step=3;
break;
case 3:
DIG1=0;
DIG2=0;
DIG3=0;
DIG4=1;
P2=ledTab[led_show4];
led_di=led_dian4;
led_step=0;
break;
}
}
void Time0Interrupt(void) interrupt 1 using 3
{
//TR0=0;
ledTime();
if(Time_Show>0)
Time_Show--;
if(PwmBitVat>TimeMotor)
{
MOTOR1=1;
}
else
{
MOTOR1=0;//低电平打开电机
}
if(PwmBitVat++>256)
{
PwmBitVat=0;
}
//TL0=Time0L1;
//TH0=Time0H1;
//TR0=1;
}
//void ADC_ISR() interrupt 5
//{
// ADC_CONTR &= ~ADC_FLAG;
// switch(ADC_ch)
// {
// case 0:
// ADC_ch=1;
// ADC_VAL[0]=(ADC_RES<<2)|(ADC_RESL&0x03);
//
// ADC_CONTR = ADC_POWER | ADC_SPEEDLL | 5 | ADC_START;
// break;
// case 1:
// ADC_ch=0;
// ADC_VAL[1]=(ADC_RES<<2)|(ADC_RESL&0x03);
//
// ADC_CONTR = ADC_POWER | ADC_SPEEDLL | 4 | ADC_START;
// break;
// }
//}
void led_showP(float fshowPa)
{
static float tmp_showPa=-1;
float tmp_show=fshowPa;
float temp_dian;
unsigned char shorteger,shordian;
if(fshowPa==tmp_showPa)
return;
tmp_showPa=fshowPa;
shorteger=(unsigned char)abs((int)fshowPa);
temp_dian=tmp_show-(float)shorteger;
led_show1=shorteger/10;
led_show2=shorteger%10;
led_dian1=0;
led_dian2=1;
//小数点后两位
shordian=(unsigned char)(temp_dian*100.0);
led_show3=shordian/10;
led_show4=shordian%10;
led_dian3=0;
led_dian4=0;
}
unsigned short GetADCResult(unsigned char ch)
{
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
while(!(ADC_CONTR&ADC_FLAG));
ADC_CONTR &= ~ADC_FLAG;
return (ADC_RES<<2)|(ADC_RESL&0x03);
}
|