Serial Servo Control usando PIC

0

Estoy tratando de hacer un servocontrolador en serie usando el microcontrolador pic18f4550.

siguiendo si el código completo que he intentado ..

tenga en cuenta que actualmente estoy enviando un hex de 8 bits para controlar solo un servo. Estoy enviando estos datos de una foto a otra ...

#define FREQ 20000000
#define baud 9600
#define spbrg_value (((FREQ/64)/baud)-1)


unsigned char rx_data(void);
void tx_data(unsigned char);


void main()
{
int i;
double state;
int ip1=0;
SPBRG=spbrg_value;      // Fill the SPBRG register to set the Baud Rate
RCSTA.SPEN=1;           // To activate Serial port (TX and RX pins)
TXSTA.TXEN=1;           // To enable transmission
RCSTA.CREN=1;           // To enable continuous reception

TRISB.RB0=0;

while(1)
{
    ip1=rx_data();    // Receive data from PC

    //this part doesn't gets executed!!
    state=max((ip1/4)+1,12);
    LATB.LATB0=1;

    for (i=0;i<state;i++)
       delay_us(10);

    LATB.LATB0=0;

    for (i=0;i<200-state;i++)
       delay_us(1);
}
}


void tx_data(unsigned char data1)
{
TXREG=data1;                                     // Store data in Transmit register
while(PIR1.TXIF==0);                             // Wait until TXIF gets low
}


unsigned char rx_data(void)
{
while(PIR1.RCIF==0);                           // Wait until RCIF gets low
return RCREG;                                 // Retrieve data from reception register
}

Me he asegurado de que la imagen maestra envíe los datos correctos al conectarlos al puerto serie de la PC y observar el resultado.

como se indica en el código, la parte posterior a ip1=rx_data(); no se ejecuta.

También confirmé comentando la parte ip1=rx_data(); y luego reemplazando la variable ip1 con un valor int ... luego el servo se mueve a la posición adecuada de acuerdo con el valor en lugar de ip1 (que va de 0 a 255) ).

¿Alguna ayuda?

ACTUALIZACIÓN:

con las sugerencias dadas en las respuestas que he cruzado, verifiqué lo siguiente.

1.Both PICs running on 20mhz so frequency is correct.

2.serial data format is correct. i am receiving the proper data to the PC.

3.Wiring checked.

4.decoupling( plz explain how to do proper decoupling).

5.power supply. ( both running of a 5v 1 amp wall chargers).

por lo que el problema más probable (aparte del software) puede ser el desacoplamiento incorrecto. ¿Alguien me puede explicar esto?

    
pregunta Suraj Bhawal

2 respuestas

1

En primer lugar, tu código está bloqueando. Esa no es la manera de esperar por los datos en serie. Deberá monitorear el indicador de interrupción de RX desde el bucle principal y, si está configurado, haga el ip1=rx_data(); para obtener los datos. En su caso, si su cableado de los pines UART es incorrecto o no hay datos de la MCU maestra, la línea while(PIR1.RCIF==0); es un bucle infinito. Eso explica por qué el resto de tu código no funciona.

Lo segundo que noté es que le está dando al servo solo un pulso por señal de control. La mayoría de los servomotores RC de hobby esperan que al menos 3 pulsos de este tipo posicionen la bocina de manera confiable.

    
respondido por el Siddharth
0

Su código parece estar funcionando bien, así que si se atasca en rx_data() entonces el PIC se está ejecutando en una frecuencia incorrecta, el formato de datos en serie es incorrecto, o tiene un problema de hardware (error de cableado, desacoplamiento inadecuado, mala fuente de alimentación etc.).

Para obtener la precisión de reloj suficiente, debe utilizar un resonador de cristal o cerámica, y los bits de configuración deben establecerse en el oscilador HS. También verifique que el PIC maestro esté enviando datos en serie con el mismo formato y velocidad de transmisión (con una precisión superior al 2%). ¡El hecho de que su PC pueda leerlo no prueba que sea correcto!

Otro problema posible es que su código solo produce un pulso de servo por cada byte serie recibido. Si pretende enviar un byte cada 20 ms aproximadamente, está bien, pero tenga en cuenta que es posible que el servo no funcione correctamente si la tasa de repetición de pulsos es demasiado baja o demasiado alta.

    
respondido por el Bruce Abbott

Lea otras preguntas en las etiquetas