UART: solo recibe el desorden en RasberryPi cuando está conectado a un PIC18

0

Tengo un PIC 18 LF 27 J 53 funciona correctamente y puedo hacer que parpadee un LED. FOSC está a 8MHz (lo que se confirma a través del LED).

Ahora, quiero que el PIC envíe algunos bytes a la RaspberryPi a través de UART (estoy usando minicom para inspeccionar /dev/ttyAMA0 y he desactivado tanto el bluetooth como la consola serial). Intenté tanto con TX1 como con TX2 remapeado pero solo recibo el mismo desorden ( fààþæ ). Intenté invertir la lógica, pero eso no ayudó y recibo ~øxøxxøxþ en su lugar.

Este es mi código para configurar la interfaz UART (con BRGH, BRG @ 9600 de 8 bits):

TXSTA2   = 0b10100110;
RCSTA2   = 0b00010000;
BAUDCON2 = 0b01000010;
// BR=FOSC/(16(n+1)) <=> n=FOSC/BR/16-1
n = (uint8_t)round(1.0 * CLOCKSPEED / BAUDRATE / 16.0) - 1;
SPBRG2 = n;
RCSTA2bits.SPEN = 1;

La fórmula genera 51 para CLOCKSPEED = 8MHz y BAUDRATE = 9600 , que es el mismo que está escrito en la hoja de datos (página 343).

Este es el código que uso para enviar una cadena:

void putc(char c)
{
    while(TXSTA2bits.TRMT == 0);
    TXREG2 = c;
}
void puts(const char *str)
{
    const char *p;
    for (p = str; *p; p++)
        putc(*p);
}

Finalmente, lo llamo así:

const char *str = "HELLO\r\n";
puts(str);

¿Qué puedo hacer para que RaspberryPi reciba los caracteres correctos?

EDIT : acabo de intentar imprimir el carácter U ( 01010101 ) continuamente a través de UART. Minicom recibe continuamente alternando los caracteres f ( 01100110 ) y æ ( 11100110 ). Así que supongo que hay un problema con la velocidad de transmisión. ¿Cómo puedo verificar esto y encontrar el error?

    
pregunta msrd0

1 respuesta

0

Conecté el pin TX del PIC a un pin de entrada GPIO de mi RaspberryPi y escribí un pequeño programa para monitorear lo que está pasando:

    #include <assert.h>
    #include <fcntl.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <sys/mman.h>
    #include <sys/stat.h>
    #include <sys/time.h>
    #include <time.h>
    #include <unistd.h>

    #define BLOCK_SIZE 256

    #define GPIO_IN(g)  *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
    #define GPIO_OUT(g) *(gpio+((g)/10)) |=  (1<<(((g)%10)*3))

    #define GPIO_SET(g)  *(gpio+7)  = 1<<(g)
    #define GPIO_CLR(g)  *(gpio+10) = 1<<(g)
    #define GPIO_LEV(g) (*(gpio+13) >> (g)) & 0x1

    #define PIN 18

    int                mem_fd;
    void              *gpio_map;
    volatile uint32_t *gpio;

    unsigned long ellapsed(struct timespec last, struct timespec now)
    {
      unsigned long diff = now.tv_sec - last.tv_sec;
      diff *= 1e9;
      diff += now.tv_nsec - last.tv_nsec;
      return diff;
    }

    int main()
    {
      mem_fd = open("/dev/gpiomem", O_RDWR|O_SYNC);
      assert(mem_fd != -1);

      gpio_map = mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0);
      assert(gpio_map != MAP_FAILED);
      gpio = (volatile uint32_t*)gpio_map;

      GPIO_IN(PIN);

      struct timespec last, now;
      clock_gettime(CLOCK_BOOTTIME, &last);
      char state = 1;
      while (1)
        {
          if ((state & 0x1) != (GPIO_LEV(PIN)))
            {
              clock_gettime(CLOCK_BOOTTIME, &now);
              printf("state changed from %d to %d after %f µsecs (= %f kHz)\n", state, GPIO_LEV(PIN), ellapsed(last, now)/1000.0, 1.0/(ellapsed(last,now)/1e9)/1e3);
              last = now;
              state = GPIO_LEV(PIN);
            }
        }
    }

La velocidad fue de aproximadamente 207 µseg por bit. Busqué la velocidad de uart y encontré que esto equivale a una velocidad en baudios de 4800, exactamente la mitad de lo que esperaba. Dividir n a través de 2 me da la velocidad de transmisión correcta, aunque no entiendo por qué es necesario, ya que ni la hoja de datos ni Internet informan sobre ese comportamiento.

    
respondido por el msrd0

Lea otras preguntas en las etiquetas