es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Enviando el UART b’\x05′ y recibiendo b’\x85′

Mi Attiny2313 está configurado para eco del carácter recibido por UART, pero cuando envío un b’\x05′, recibo un b’\x85′ desde el Attiny.

Estoy enviando el byte a través de Python.

def initSerial(self, port):
    self._serialPort = port
    self._serial = serial.Serial(port, 9600, timeout=1)
    self._serial.write(b'\x05')
    receivedCmd = self._serial.readline()
    print(receivedCmd)

El código en el Attiny que hace eco es el siguiente:

int main(void) {
    uint16_t c = 0;
    init_uart();

    sei();

    while (1) {

        c = uart_getc();
        if (c == UART_NO_DATA);
        else {
            uart_putc(c);
        }
    }

    return 0;
}

El archivo uart.cpp es el siguiente:

“`c
/*
* uart.cpp
*
* Created: 11/28/2021 10:36:27 PM
* Author: jonashoft
*/

#define F_CPU 1000000UL

#include <inttypes.h>
#include <stdio.h>
#include
#include
#include
#include

#include “uart.h”

#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif

#define BAUD 9600
#define MYUBBR ((F_CPU / (BAUD * 16L)) – 1)
#define BUFFER_SIZE 16

volatile static uint8_t rx_buffer[BUFFER_SIZE] = “xxxxxxxxxxxxxxx”;
volatile static uint8_t tx_buffer[BUFFER_SIZE] = “xxxxxxxxxxxxxxx”;
volatile static uint8_t rx_head = 0;
volatile static uint8_t rx_tail = 0;
volatile static uint8_t tx_head = 0;
volatile static uint8_t tx_tail = 0;
volatile static uint8_t sent = TRUE;

/*
* init_uart
*/
void init_uart(void) {
// set baud rate
UBRRH = (uint8_t)(MYUBBR >> 8);
UBRRL = (uint8_t)(MYUBBR);
// enable receive and transmit
UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
// set frame format
UCSRC = (1 << USBS) | (3 << UCSZ0); // asynchron 8n1
}

/*
* send_uart
* Sends a single char to UART without ISR
/
void send_uart(uint8_t c) {
// wait for empty data register
while (!(UCSRA & (1<<udre))); set=”” data=”” into=”” data=”” register=”” udr=”c;” }=”” *=”” *=”” receive_uart=”” *=”” receives=”” a=”” single=”” char=”” without=”” isr=”” */=”” uint8_t=”” receive_uart()=”” {=”” while=”” (=”” !(ucsra=”” &=””></udre)));><rxc)) )=”” ;=”” return=”” udr;=”” }=”” *=”” *=”” uart_getc=”” *=”” gets=”” a=”” single=”” char=”” from=”” the=”” receive=”” buffer.=”” *=”” return=”” uint16_t=”” the=”” received=”” char=”” or=”” uart_no_data=”” */=”” uint16_t=”” uart_getc(void)=”” {=”” uint8_t=”” c=”0;” uint8_t=”” tmp_tail=”0;” if=”” (rx_head=”=” rx_tail)=”” {=”” return=”” uart_no_data;=”” }=”” tmp_tail=”(rx_tail” +=”” 1)=”” %=”” buffer_size;=”” c=”rx_buffer[rx_tail];” rx_tail=”tmp_tail;” return=”” c;=”” }=”” *=”” *=”” uart_getc_f=”” *=”” getc=”” in=”” stdio=”” style.=”” */=”” int=”” uart_getc_f(file=”” *stream)=”” {=”” uint16_t=”” c;=”” while=”” ((c=”uart_getc())” ==”UART_NO_DATA)” {}=”” return=”” c;=”” }=”” *=”” *=”” uart_getc_wait=”” *=”” blocking=”” call=”” to=”” getc.=”” will=”” not=”” return=”” until=”” a=”” char=”” is=”” received.=”” */=”” uint8_t=”” uart_getc_wait(void)=”” {=”” uint16_t=”” c;=”” while=”” ((c=”uart_getc())” ==”UART_NO_DATA)” {}=”” return=”” c;=”” }=”” *=”” *=”” uart_putc=”” *=”” puts=”” a=”” single=”” char.=”” will=”” block=”” until=”” there=”” is=”” enough=”” space=”” in=”” the=”” *=”” send=”” buffer.=”” */=”” void=”” uart_putc(uint8_t=”” c)=”” {=”” uint8_t=”” tmp_head=”(tx_head” +=”” 1)=”” %=”” buffer_size;=”” wait=”” for=”” space=”” in=”” buffer=”” while=”” (tmp_head=”=” tx_tail)=”” {=”” ;=”” }=”” tx_buffer[tx_head]=”c;” tx_head=”tmp_head;” enable=”” uart=”” data=”” interrupt=”” (send=”” data)=”” ucsrb=”” |=””></rxc))><udrie); }=”” *=”” *=”” uart_putc_f=”” *=”” puts=”” a=”” single=”” char.=”” used=”” by=”” printf=”” functions.=”” */=”” int=”” uart_putc_f(char=”” c,=”” file=”” *stream)=”” {=”” uart_putc(c);=”” return=”” 0;=”” }=”” *=”” *=”” uart_puts=”” *=”” sends=”” a=”” string.=”” */=”” void=”” uart_puts(const=”” char=”” *s)=”” {=”” while=”” (
s)=”” {=”” uart_putc(*s);=”” s++;=”” }=”” }=”” *=”” *=”” uart_puts_p=”” *=”” sends=”” a=”” progmem=”” string.=”” */=”” void=”” uart_puts_p(const=”” char=”” *s)=”” {=”” while=”” (pgm_read_byte(s)=”” !=”0x00)” {=”” uart_putc(pgm_read_byte(s++));=”” }=”” }=”” *=”” *=”” isr=”” user=”” data=”” regiser=”” empty=”” *=”” send=”” a=”” char=”” out=”” of=”” buffer=”” via=”” uart.=”” if=”” sending=”” is=”” complete,=”” the=”” *=”” interrupt=”” gets=”” disabled.=”” */=”” isr(usart_udre_vect)=”” {=”” uint8_t=”” tmp_tail=”0;” if=”” (tx_head=”” !=”tx_tail)” {=”” tmp_tail=”(tx_tail” +=”” 1)=”” %=”” buffer_size;=”” udr=”tx_buffer[tmp_tail];” tx_tail=”tmp_tail;” }=”” else=”” {=”” disable=”” this=”” interrupt=”” if=”” nothing=”” more=”” to=”” send=”” ucsrb=”” &=”~(1″ <<=”” udrie);=”” }=”” }=”” *=”” *=”” isr=”” rx=”” complete=”” *=”” receives=”” a=”” char=”” from=”” uart=”” and=”” stores=”” it=”” in=”” ring=”” buffer.=”” */=”” isr(usart_rx_vect)=”” {=”” uint8_t=”” tmp_head=”0;” tmp_head=”(rx_head” +=”” 1)=”” %=”” buffer_size;=”” if=”” (tmp_head=”=” rx_tail)=”” {=”” buffer=”” overflow=”” error!=”” }=”” else=”” {=”” rx_buffer[rx_head]=”UDR;” rx_head=”tmp_head;” }=”” }=”” ="" el="" archivo="" uart.h="" es="" el="" siguiente:=""c=”” *=”” *=”” uart.h=”” *=”” *=”” created:=”” 11/28/2021=”” 10:36:11=”” pm=”” *=”” author:=”” jonashoft=”” */=”” #ifndef=”” uart_h=”” #define=”” uart_h=”” #include=””></udrie);><stdio.h>

#define UART_NO_DATA 0x0100

// Initialize UART to 9600 baud with 8N1.
void init_uart(void);

// Send and receive functions, that run without ISRs
uint8_t receive_uart();
void send_uart(uint8_t c);

// Receive a single char or UART_NO_DATA, if nothing received
uint16_t uart_getc(void);
// Blocking call to receive a char
uint8_t uart_getc_wait(void);
int uart_getc_f(FILE *stream);

// Send a single char
void uart_putc(uint8_t c);
int uart_putc_f</stdio.h></stdio.h></inttypes.h>

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El problema parece estar relacionado con la forma en que se envían y reciben los bytes. El código de Python envía los bytes correctamente, pero el código C no los interpreta correctamente.

    Una posible solución es modificar el código C para comprobar el byte recibido usando su valor decimal en lugar de su valor hexadecimal. Por ejemplo, para comprobar si el byte recibido es igual a 5, en lugar de usar if (c == 0x05), puedes usar if (c == 53).

    Otro problema parece estar relacionado con la forma en que se envía el eco desde el Attiny. La función de eco simplemente envía el byte recibido de vuelta al código Python. Sin embargo, no considera la posibilidad de que el byte recibido pueda ser un carácter de control. Los caracteres de control son caracteres no imprimibles que tienen un significado especial, como el salto de línea o la tabulación. Cuando se recibe un carácter de control, el comportamiento de la función de eco puede ser diferente al esperado.

    Para resolver este problema, puedes modificar la función de eco para comprobar si el byte recibido es un carácter de control y, si es así, convertirlo a su carácter imprimible correspondiente antes de enviarlo de vuelta.

    Aquí tienes un ejemplo de cómo modificar la función de eco para manejar los caracteres de control:

    void echo(uint8_t c) {
      // Comprobar si el byte recibido es un carácter de control
      if(c < 32 || c == 127) {
        // Si es así, convertirlo a su carácter imprimible correspondiente
        switch(c) {
          case '\n':
            c = '\r'; // Convertir el salto de línea a retorno de carro
            break;
          case '\t':
            c = ' '; // Convertir la tabulación a espacio
            break;
          // Agregar más casos para otros caracteres de control según sea necesario
        }
      }
      uart_putc(c); // Enviar el byte de vuelta
    }
    

    Con esta modificación, la función eco convertirá los caracteres de salto de línea en caracteres de retorno de carro y los caracteres de tabulación en caracteres de espacio, antes de enviarlos de vuelta al código Python. Esto debería garantizar que el código Python reciba los bytes esperados.

Comments are closed.