#define uint unsigned int
#define uchar unsigned char
uchar num1 = 0
uint v_set = 40
xdata uint pcacap2
xdata uchar dutycycle
uint A=10//float D=0.04float C=5
//int xdata e0=0,e1=0,e2=0
float xdata PWM=0
bit isnewdata
bit DIRECTON
#define POSITIVE DIRECTON = 1
#define NEGATIVE DIRECTON = 0
void Oscillator_Init()
{
SFRPAGE = CONFIG_PAGE
OSCICN= 0x83
}
void Port_IO_Init()
{
SFRPAGE = 0x0F
XBR0 = 0xF7
XBR2 = 0x40
}
void PCA_Init()
{
SFRPAGE=0x00
PCA0CPM0=0x02
PCA0CPM1=0x02
PCA0CPM2=0x21
PCA0CPL2=0x00
PCA0CPH2=0x00
PCA0MD=0x00
PCA0CN=0x40
EIE1|=0x08
}
void PWM_set(uchar low)
{//占空比设置,高电平占空比为(256-low)/256
SFRPAGE = PCA0_PAGE
if (DIRECTON == 1) {PCA0CPH0 = lowPCA0CPM1 = 0x02PCA0CPM0 = 0x42}
else {PCA0CPH1 = lowPCA0CPM0 = 0x02PCA0CPM1 = 0x42}
}
void PCA_ISR(void) interrupt 9 using 1 {
static xdata uint tmpcnt=0
static xdata uint PCA0CP2=0
xdata uint tmpcnt2
if(CCF2){
tmpcnt2 = PCA0CPH2
tmpcnt2 = tmpcnt2<<8
PCA0CP2 = tmpcnt2 + PCA0CPL2
pcacap2 = PCA0CP2-tmpcnt
tmpcnt = PCA0CP2
CCF2=0
}
}
PID_SC(uint v)
{
int Uk_zint e
e = v - v_set
//e1 = v1 - v_set
//e2 = v2 - v_set
//v2 = v1
//v1 = v
Uk_z = A*e/*+ D*e0 + C*(e0 - 2*e1 + e2)*/
//Uk0 = Uk1 + Uk_z
//Uk1 = Uk0
//PWM = PWM - 256
dutycycle = 0.0256 * Uk_z
}
void main()
{
//Oscillator_Init()
WDTCN = 0x07
WDTCN = 0xDE
WDTCN = 0xAD
Port_IO_Init()
EA=1
num1=0
isnewdata=0
PCA_Init()
POSITIVE
while(1){PID_SC(pcacap2)PWM_set(dutycycle)}
}
二、硬件框图: 硬件部分主要由电位器、模数转换模块、 51单片机、显示模块、驱动电路和无刷直流电机(内置霍尔传感器)组成。其功能框图如下: 框图的基本原理: 通过键盘输入一个转速初值,调节旋转式电位计调节给定一个电压Un, DCOUT连接ADC0809的IN0通道,经ADC0809芯片连接到51单片机组成模数转换模块,得到的数字信号显示在LCD显示屏上。从单片机的P1.0口输出一个PWM脉冲信号经过驱动电路驱动直流电机,直流电机内部的霍尔传感器测定实际转速后,经过采用脉冲信号反馈到单片机与给定转速比较进行闭环控制转速达到给定速度时,LCD实时显示给定速度。 三、实现功能环节如下: 1、参数的设定 电机速度的给定是通过给定电位器来确定。电位器原理(如下图):当电位器中心触头C滑动在电位器上时可以得到一个电压信号,这个电压范围为0~VCC(+5V),属于模拟信号。 然后根据要求的速度值和实际的速度值来确定比例速度误差和积分速度误差。有了这两个值,就可以使用下面的公式计算出新的占空比:NewDutyCycle (新的占空比) = Kp ( 比例速度误差) + Ki ( 积分速度误差) 然后将10位的NewDutyCycle (新占空比值)装入所有的3个PWM占空比寄存器中。使用P I算法来计算新的DutyCycle (占空比)值,该值将被载入PDCx寄存器。 void CalculateDC ( void) { DesiredSpeed = DesiredSpeed3 3Flags. Minus = 0if (ActualSpeed >DesiredSpeed) SpeedError = ActualSpeed - DesiredSpeedelse { SpeedError = DesiredSpeed - ActualSpeedFlags. Minus = 1} Speed Integral + = SpeedErrorif ( Speed Integral >9000) Speed Integral = 0DutyCycle = ( ( ( long) Ksp 3 ( long) SpeedError + ( long) Ksi3 ( long) Speed Integral) >>12) DesiredSpeed = DesiredSpeed /3if ( Flags. Minus) DutyCycle = DesiredSpeed + DutyCycleelse DutyCycle = DesiredSpeed - DutyCycleif (DutyCycle <100) DutyCycle = 100if (DutyCycle >1250) {DutyCycle = 1250Speed Integral = 0} PDC1 = DutyCyclePDC2 = PDC1PDC3 = PDC1} 2、模数转换: 电位计传送的电压信号接到ADC0809的IN0通道,ADC0809进行采样。ADC0809由一个8路模拟开关、一个地址锁存与译码器、一个A/D转换器和一个三态输出锁存器组成。多路开关可选通8个模拟通道,允许8路模拟量分时输入,共用A/D转换器进行转换。ADC0809内部带有输出锁存器,可以与AT89S51单片机直接相连,初始化时,使ST和OE信号全为低电平, ST为转换启动信号。当ST上跳沿时,所有内部寄存器清零;下跳沿时,开始进行A/D转换;在转换期间,ST应保持低电平。EOC为转换结束信号。当EOC为高电平时,表明转换结束;否则,表明正在进行A/D转换。OE为输出允许信号,用于控制三条输出锁存器向单片机输出转换得到的数据。OE=1,输出转换得到的数据;OE=0,输出数据线呈高阻状态。D7-D0为数字量输出线。CLK为时钟输入信号线。因ADC0809的内部没有时钟电路,所需时钟信号必须由外界提供,通常使用频率为500KHZ,欢迎分享,转载请注明来源:内存溢出
评论列表(0条)