void ad_init() // 单片机AD 初始化函数
{ P1ASF=0x01; //1111,1111, 将 P1 置成模AD AUXR1 &= ~0x04; //0000,0100, 令 ADRJ=0 ADC_CONTR |= 0x80; //1000,0000 打开 A/D 转换电源 }
void pwm_init()
// 单片机PWM相关寄存器 初始化函数
{ CCON=0; CL=0; CH=0; CMOD=0x00;
PCA_PWM0=0x00; CCAPM0=0x42; EPCnL=1, CCAPnL=FFH 时PWM固定输出低 */;
PCA_PWM1=0x00;
CCAPM1=0x42; CR=1; }
void PWM(INT8 a)
{ INT8 xx; xx=256-a;
CCAP0H=CCAP0L=0+xx; //P13 CCAP1H=CCAP1L=256-xx-5; //P14 }
INT8 ceshu() { if(caiji==0)
{ n1=1; }
//速度脉冲检测函数
if((caiji==1)&&(n1==1)) //脉冲上升沿检测 }
void UART(INT8 a,INT8 b,float c) { if(flag_uart==1)
//串口函数
{ shudu++; n1=0; } return shudu;
//串口显示标志判断
{ flag_uart=0; ES=0; TI=1;
switch(flag_on)
//显示模式及电机状态控制命令判断
{ case 0: puts(\
led0=0;led1=1; TR0=1; _nop_();_nop_();_nop_();_nop_();break;
case 1: _nop_();_nop_();
led0=0;led1=0; _nop_();_nop_(); led0=1;led1=0; break;
case 2: _nop_();_nop_();
led0=0;led1=0; _nop_();_nop_(); led0=0;led1=1; break; case 3: printf(\ led0=0;led1=0; TR0=0;
break;
}
case 4: puts(\ break;
while(!TI); TI=0; ES=1; }
if(flag_xianshi==1) //串口显示标志判断 { flag_xianshi=0; ES=0; TI=1;
printf(\ }
void main()
//主函数部分
while(!TI);
TI=0; ES=1; }
{ INT8 shedin=180;
INT8 shesu1=0,uk1,uk=180,k1=0,uk2=0; ad_init();
// 单片机AD 初始化
// 单片机定时器 串口等寄存器 初始化
//
单片机PWM相关寄存器 初始化
//电压与速度拟合曲线的相关参数初始化
timer_init();
pwm_init();
a1=34.5178; a2=0.67373;
b1=28.91; b2=28.8715; P0=0xFF; cont2=0; led0=0;
led1=0;
//设置电机初始状态为停止
while(1)
{ moto_speed=ceshu(); if(flag_ad==1) { flag_ad=0;
ad_val=get_AD_result(0);
shedin=(INT8)(ad_val*a2-b2);
//AD采集设定电机两端电压
//频率脉冲检测与存储
//判断采样标志
shesu1=shedin;
if(cont2>=4)
{ if(shisu<=shedin)
{ k1=1; uk1=shedin-shisu; } else
{ uk1=shisu-shedin;
k1=0; //反馈速度偏差量ek }
if(k1==1)
{ if((shisu<=115)||(shisu>=60))
//设置不同速度范围内的偏差调整量
uk2=ad_val+uk1+3;
else
uk2=ad_val+uk1;
}
else if(k1==0)
{ if((shisu<=115)||(shisu>=65)) uk2=ad_val-uk1-3;
else
uk2=ad_val-uk1;
} }
//设置不同速度范围内的偏差调整量
else
{ uk2=ad_val; }
uk=uk2; ad_vall=ad_val; //经反馈校正后的pwm输出值 ad_fl=(float)ad_vall*5.0/256.0;
}
PWM(uk);
//pwm输出控制电机转速
UART(shisu,shesu1,ad_fl); //调用串口显示函数 } }
void delay0(INT8U delay_time) // 延时函数 void timer0()interrupt 1 //T0定时计数器中断 { TH0=(65536-50000)/256; TL0=(65536-50000)%6; cont++; if(cont==20)
//1秒定时计数 设定
//50ms计数初值
{ cont=0;
cont2++; flag_xianshi=1; flag_ad=1; shisu=moto_speed/4;
//将采集的频率换算成转速
moto_speed=0; shudu=0;
} }
void UART0()interrupt 4
//串口中断函数
{ RI=0; flag_uart=1; if(rec==1) flag_on=0; else if(rec==2) flag_on=1; else if(rec==3)
flag_on=2;
else if(rec==4)
flag_on=3;
else flag_on=4;
rec=SBUF;