Circuitos y programas para controlar motores paso a paso mediante el algoritmo pid del microcontrolador
//P0.4:Tx
//P0.5:Rx
# incluir & ltc 8051f 310 . h & gt; //Declaración SFR
# include & ltstdio.h & gt//Archivo de definición de E/S estándar
# include & ltmath.h & gt // archivo de la biblioteca de matemáticas
# incluir & ltintrins.h & gt
# include & ltabsacc.h & gt
unsigned int j, i; p>
char a = 0;
Entero sin signo t = 0;
//sbit led=p0^2;
/ /P0. 0(PWM0): Dada la velocidad de la rueda izquierda.
sbit vls=p0^4; //P0.4 (GPIO): Da la dirección de la rueda izquierda.
sbit vlf=p0^6; //P0.6(T0): retroalimentación de velocidad de la rueda izquierda.
sbit dlf=p1^0; //P1.0 (GPIO): retroalimentación dirección de la rueda izquierda.
//P0.2 (PWM0): Dada la velocidad adecuada de la rueda.
sbit vrs=p0^5; //P0.5 (GPIO): da la dirección correcta de la rueda.
sbit vrf=p0^7; //P0.7(T0): Velocidad de retroalimentación de la rueda derecha.
sbit drf=p1^1; //P1.1 (GPIO): retroalimenta la dirección derecha de la rueda.
int ol//Valor dado de la rueda izquierda
int len
int len_1, len _ 2
int lyn_1, Lyn _; 2;
int vl1, vl2//Valor de velocidad de la rueda izquierda de retroalimentación (número de ondas cuadradas en el período de muestreo)
int lfz//El valor asignado a PWM después de la operación p>
int lyn, lynn
int lun=0, LUN_1 = 0; //El valor de corrección de desviación es la salida PWM corregida.
International Lump, Rooney, Lund; //Valor de corrección PID
int o; //Valor dado de la rueda derecha
int ren
int ren_1, ren_2;
int ryn_1, ryn_2;
int vr1, vr2//Valor de velocidad de la rueda derecha de retroalimentación (onda cuadrada dentro del número del período de muestreo)
int rfz//El valor asignado a PWM después de la operación
int ryn, rynn
int run=0, run_1 = 0;/ /El valor de corrección de desviación es el PWM corregido producción.
int runp, runi, rund//Valor de corrección PID
Punto flotante kp = 2,0//Coeficiente proporcional 1,8
float kd = 0,2//Coeficiente diferencial 0.4
lki flotante//coeficiente integral
void Pio _ init(void);
void sys _ init(void); >void t 01 _ init(void);
tiempo vacío 3 _ INT(void
void PID(void);
void interrupción _ init); (void);
retraso de vacío (unsigned int x);
void PWM 1 _ 1 (void); >
p>
{
PCA0MD & amp= ~ 0x40//Close
Pio _ init() //P11 es la entrada de alcance.
sys_init();
t 01_init();
PWM 1_1();
hora 3 _ INT();
Interrupt_Initialization();
vls = 1; VRS = 0;
mientras(1)
{
ol = 50
o = 50
Retraso(1000);
ol = 100;
o = 100; p>
Retraso(1000);
ol =-50;
o = 50
Tiempo de retraso(1000);
}
}
PID no válido (no válido)
{
/* * * * * * * * * * * *Ajuste PID de rueda izquierda* * * * * * * * * * * * * *
if(dlf==1)
{
Lyn = (vl2 * 256+VL 1); //dlf es la dirección de retroalimentación de la rueda izquierda, 0 significa avance vl=TL0.
}
Otros
{
Lyn =-(vl2 * 256+VL 1); //dlf=1 significa Después de eso, la velocidad debería ser negativa.
}
len = ol-Lyn; //Error = velocidad dada - velocidad de retroalimentación (número de ondas cuadradas en el período de muestreo)
if(ABS (len)<8)//30
{
lki = 1.4 //Determinar //valor ki 1.4
}
Otros
{
lki = 0.05//Coeficiente integral: si |el valor de retroalimentación dado es demasiado grande|.
}//No se pueden introducir puntos, ni introducir un pequeño 0,05.
lunp = KP *(len-len _ 1); // Corrección proporcional
Looney = lki * len // Corrección integral
Lund = KD * (len-2 * len _ 1+len _ 2); //Corrección diferencial
LUN = lunp+Luni+Lund+LUN _ 1; //Corrección total
* * * * * * * * * * * *Actualizaciones de datos nuevas y antiguas* * * * * * * * * * * * * * * * * * *
len _ 2 = len _ 1;
len _ 1 = len; //len: desviación de velocidad en el período de muestreo actual; Len_1: desviación de velocidad en el período de muestreo anterior.
LUN_1 = LUN; //lun: valor de corrección PWM obtenido en el período de muestreo actual; Lun_1: valor de corrección PWM obtenido en el período de muestreo anterior.
* * * * * * * * * * * *Actualizaciones de datos nuevas y antiguas* * * * * * * * * * * * * * * * * * * * *
if (LUN > 255)
{
lun = 255//Velocidad positiva
}
Si (lun & lt- 255)
{
LUN =-255 //Velocidad negativa
}
Si (lun & lt0)
{
vls = 1;
PCA 0 cph 0 =-LUN;
}
si (LUN & gt;=0)
{
vls = 0;
PCA0CPH0 = lun
}
/ * * * * * * * * * * * *Ajuste PID de rueda derecha* * * * * * * * * * * * * * * * *
if(drf==0)
{
ryn =(vr2 * 256+VR 1); //drf es la dirección de retroalimentación de la rueda derecha, 0 significa avance vl=TL0.
}
Otros
{
ryn =-(vr2 * 256+VR 1); //dlf=1 significa Después de eso, la velocidad debería ser negativa.
}
ren = or-ryn; //Error = velocidad dada - velocidad de retroalimentación (número de ondas cuadradas en el período de muestreo)
if(ABS (ren)<8)//30
{
lki = 1,4;//determinar//valor de ki 1,4
}
Otros
{
lki = 0.05//Coeficiente integral: si |el valor de retroalimentación dado es demasiado grande|.
}//No se pueden introducir puntos, ni introducir un pequeño 0,05.
runp = KP *(ren-ren _ 1); //Corrección proporcional
runi = lki * ren//Corrección integral
rund = KD * (ren-2 * ren _ 1+ren _ 2); //Corrección diferencial
run = runp+runi+rund+run _ 1; //Corrección total
* * * * * * * * * * * *Actualizaciones de datos nuevas y antiguas* * * * * * * * * * * * * * * * * * * *
ren _ 2 = ren _ 1 ;
p>ren _ 1 = ren; //len: desviación de velocidad en el período de muestreo actual Len_1: desviación de velocidad en el período de muestreo anterior.
run_1 = run; //lun: valor de corrección PWM obtenido en el período de muestreo actual; Lun_1: valor de corrección PWM obtenido en el período de muestreo anterior.
* * * * * * * * * * * *Actualizaciones de datos nuevas y antiguas* * * * * * * * * * * * * * * * * * * * *
if (ejecutar > 255)
{
ejecutar = 255//velocidad positiva
}
if (ejecutar & lt- 255)
{
run =-255 //Velocidad negativa
}
if(run<0) p >
{
VRS = 1;
PCA 0 cph 1 =-ejecutar;
}
if(ejecutar & gt;=0)
{
VRS = 0;
PCA 0 cph 1 = en ejecución;
}
//Debido a que cuanto mayor es el PCA0CPH0 aquí, menor es la velocidad del motor correspondiente, por lo que debe reducirse en 255.
}
void pio_init(void)
{
XBR0 = 0x00//0000 0001
xbr 1 = 0x 72; // Cuando 0111010, T0T1 se puede levantar débilmente para conectar el tobillo P06, P07 CEX0, CEX1 y conectar el tobillo P00, P01.
P0MDIN = 0xff//Simulación (0); número (1) 1111011.
P0MDOUT = 0xc3//Drenaje abierto (0); push-pull (1) 111 111
P0SKIP = 0x3c//0011 1100
p 1 mdin = 0x ff; //1111 1111
p 1m dout = 0x fc; //
p 1 saltar = 0x 00; //1111 1111
}
void sys _ init(void)//12 MHz
{
OSSCICL = 0x43
OSSCICN = 0xc2
CLKSEL = 0x00
}
void PWM 1 _ 1(void)//Inicialización de PWM
{
PCA0MD = 0x08 //Reloj PCA dividido por 12.
PCA0CPL0 = 200 //Rueda izquierda
PCA 0 CPM 0 = 0x 42; //Configura la rueda izquierda en salida PWM de 8 bits.
PCA0CPH0 = 200
PCA 0 CPL 1 = 200; // Corrección de equilibrio
PCA 0 CPM 1 = 0x 42; Salida PWM.
PCA 0 cph 1 = 200;
PCA0CN = 0x40 //Permitir que PCA funcione
}
void t01_init(void)
{
TCON = 0x 50; //Los contadores 1 y 2 están permitidos
TMOD = 0x 55 //Los temporizadores 1 y 2 usan 16 bits; función de conteo.
CKCON = 0x00
th 1 = 0x 00; //Se utiliza para recopilar la velocidad de la rueda izquierda.
TL 1 = 0x 00;
TH0 = 0x00 // Se utiliza para recoger la velocidad de la rueda derecha.
TL0 = 0x00
}
void TIME3_INT(void)
{
TMR3CN = 0x00// El temporizador 3 sobrecarga automáticamente 16 bits.
CKCON & amp= ~ 0x40
TMR3RLL = 0xff
TMR3RLH = 0xd7
TMR3L = 0xff
TMR3H = 0xd7
TMR3CN | = 0x04
}
Voidt3 _ ISR() interrupción 14 // Rutina de servicio de interrupción del temporizador 3.
{
//led = ~ led
EA = 0
TCON & amp; Counter 0, 1
VL 1 = TL0; //Obtener el valor de velocidad de la rueda izquierda
vl2 = TH0
VR 1 = TL 1; el valor correcto de velocidad de la rueda.
vr2 = th 1;
th 1 = 0x 00;
TL 1 = 0x 00
TH0 = 0x00 p>
p>
TL0 = 0x00
PID(); //Procesamiento PID
TMR3CN & amp= ~ 0x80//Borrar el indicador de interrupción.
TCON | = 0x 50; //Reiniciar contador 0, 1.
EA = 1;
}
void interrupt_initialization (void)
{ IE = 0x80
IP = 0x00
eie 1 | = 0x 80;
EIP 1 | = 0x 80;
}
Retraso nulo (int sin signo) m) //Programa de retardo
{
for(I = 0;i<2000;i++)
{
for(j = 0; j & ltm; j++){ _ no _(); _ no _();}
}
}