Gast
#75609
Ich versuche mit Printf_P Strings über den Uart auszugeben, hatte damit aber bislang nur wenig Erfolg. Das Ganze soll interruptgesteuert und gepuffert ablaufen. Hoffentlich kann mir hier jemand noch einen Rat geben wo der Fehler steckt... Ich benutze WinAVR-20030913 und AVR Studio 4.07 und folgenden Code: #include <avr/io.h> #include <avr/signal.h> #include <avr/interrupt.h> #include <stdio.h> #include <avr/pgmspace.h> #define UART_BUF_SIZE 40 char character = 'H'; char string[] = "ello World!"; /* uart globals */ volatile unsigned char uart_txd_buf_cnt; volatile unsigned char *uart_txd_in_ptr, *uart_txd_out_ptr; volatile unsigned char uart_txd_buffer[UART_BUF_SIZE]; SIGNAL(SIG_UART0_DATA) /* signal handler for uart data buffer empty interrupt */ { if (uart_txd_buf_cnt > 0) { outp(*uart_txd_out_ptr, UDR0); /* write byte to data buffer */ if (++uart_txd_out_ptr >= uart_txd_buffer + UART_BUF_SIZE) /* Pointer wrapping */ uart_txd_out_ptr = uart_txd_buffer; if(--uart_txd_buf_cnt == 0) /* if buffer is empty: */ cbi(UCSR0B, UDRIE0); /* disable UDRIE int */ } } int uart_putchar(char c) { if (uart_txd_buf_cnt<UART_BUF_SIZE) { cli(); uart_txd_buf_cnt++; *uart_txd_in_ptr = c; /* put character into buffer */ if (++uart_txd_in_ptr >= uart_txd_buffer + UART_BUF_SIZE) /* pointer wrapping */ uart_txd_in_ptr = uart_txd_buffer; sbi(UCSR0B, UDRIE0); /* enable UDRIE int */ sei(); return 0; } else return 1; /* buffer is full */ } unsigned char uart_putstr(char s[]) { char *c = s; while (PRG_RDB(c)) if (0 == uart_putchar(PRG_RDB(c))) c++; return 0; } int main(void) { /* initialize uart */ // USART initialization // Communication Parameters: 8 Data, 1 Stop, No Parity // USART Receiver: On // USART Transmitter: On // USART Baud rate: 38400 UCSR0A=0x00; UCSR0B=((1<<RXCIE) | (1<<RXEN) | (1<<TXEN)); // USART Mode: Asynchronous UCSR0C=0x86; UBRR0L=0x19; UBRR0H=0x00; uart_txd_in_ptr = uart_txd_out_ptr = uart_txd_buffer; uart_txd_buf_cnt = 0; fdevopen(uart_putchar,NULL,0); sei(); printf_P(character); printf_P(string); while (1) { }; return 0; }