jiodatsinga
19.02.2013, 18:02
Moin,
ich versuche ein Echo-Test zwischen PC und Atmega644p mit hilfe der
Interruptsfunktion ISR(USART0_TX_vect) und ISR(USART0_UDRE_vect) aufzubauen. Der PC sendet über
RS232 nacheinander Daten zum Atmega644p. Der Atmega644p empfängt über
USART0 die Daten vom PC und sendet wieder über USART0 die Empfangene
Daten zum PC zurück. Als der PC ein Zeichen zum ATmega644p sendet, empfängt
der Atmega644p das Zeichen und dann sendet der Atmega644p das empfangene
Zeichen zum PC zurück. Danach sendet der PC das nächste Zeichen und das gleiche Prozess soll sich wiederholen.
Momentan ist der Atmega644p in der Lage Daten vom PC zu empfangen. Aber
der Atmega644p sendet nicht die Daten zum PC zurück. Also,meine
interruptsfunktion ISR(USART0_TX_vect) und ISR(USART0_UDRE_vect) funktioniert nicht.
Ich wäre sehr dankbar, wenn jemand mir hilft.
Danke im Voraus.
Mein Code.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <avr/pgmspace.h>
#define F_CPU 3686400UL
#define FOSC 7372000 // Clock Speed
#define BAUD 9600UL
// Berechnungen zur Baudrate:
#define UBRR_VAL ((FOSC+BAUD*8)/(BAUD*16)-1) // clever runden
#define usart0_rx_buffer_max_size 50
/************************************************** */
char usart0_rx_buffer[usart0_rx_buffer_max_size];
volatile uint8_t usart0_rx_buffer_size = 0;
/************************************************** **/
void USART_Init (unsigned int ubrr)
{
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char) ubrr;
// UBRR1H = (unsigned char)(ubrr>>8);
// UBRR1L = (unsigned char) ubrr;
UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0)|(0<<TXCIE0)|(0<<UCSZ02)|(0<<UDRIE0);
UCSR0C = (0<<USBS0) | (1<<UCSZ01)|(1<<UCSZ00);// 1 Stopbit, 8 Bits
DDRB = 0b11111111; // Setting PB7-PB0 as output
PORTB = (0<<PB7); // USART0 receive data from pc
}
ISR(USART0_RX_vect)
{
char data = UDR0;
if (usart0_rx_buffer_size < usart0_rx_buffer_max_size)
{
usart0_rx_buffer[usart0_rx_buffer_size] = data;
++usart0_rx_buffer_size;
/* Activation transmission of data, then we have data in the buffer */
UCSR0B |= (1<<UDRIE0);
}
}
ISR(USART0_TX_vect)
{
UCSR0B &= ~((1<<UDRIE0)|(1<<TXCIE0));
}
ISR(USART0_UDRE_vect)
{
int i;
if (usart0_rx_buffer_size == 0) // If we have no data to send
{
UCSR0B &= ~(1<<UDRIE0);// we stop transmission
}
else
{
UDR0 = usart0_rx_buffer[0];
--usart0_rx_buffer_size;
if (usart0_rx_buffer_size == 0)
{
UCSR0A = (0<<TXC0);
UCSR0B = (1<<TXCIE0; // TX-Interrupt aktivieren
}
else
// it can be a circular buffer
for (i = 0; i < usart0_rx_buffer_size; ++i)
usart0_rx_buffer[i] = usart0_rx_buffer[i + 1];
}
}
int main (void)
{
USART_Init(UBRR_VAL) ; // USART Initialisierung
sei();
while(1)
{
}
}
- - - Aktualisiert - - -
Ich habe das Problem gelöst.
ISR(USART0_RX_vect)
{
char data = UDR0;
if (usart0_rx_buffer_size < usart0_rx_buffer_max_size)
{
usart0_rx_buffer[usart0_rx_buffer_size] = data;
++usart0_rx_buffer_size;
/* Activation transmission of data, then we have data in the buffer */
UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(1<<UDRIE0);
}
}
ISR(USART0_TX_vect)
{
UCSR0B &= ~((0<<RXEN0)|(0<<TXEN0)|(1<<TXCIE0)|(1<<UDRIE0));
}
ISR(USART0_UDRE_vect)
{
int i;
if (usart0_rx_buffer_size == 0) // If we have no data to send
{
UCSR0B &= ~((0<<RXEN0)|(0<<TXEN0)|(1<<TXCIE0)|(1<<UDRIE0));// we stop transmission
}
else
{
UDR0 = usart0_rx_buffer[0];
--usart0_rx_buffer_size;
if (usart0_rx_buffer_size == 0)
{
UCSR0A = (0<<RXC0)|(0<<TXC0)|(1<<UDRE0);
UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(1<<UDRIE0)|(1<<TXCIE0);
}
else
// it can be a circular buffer
for (i = 0; i < usart0_rx_buffer_size; ++i)
usart0_rx_buffer[i] = usart0_rx_buffer[i + 1];
}
}
ich versuche ein Echo-Test zwischen PC und Atmega644p mit hilfe der
Interruptsfunktion ISR(USART0_TX_vect) und ISR(USART0_UDRE_vect) aufzubauen. Der PC sendet über
RS232 nacheinander Daten zum Atmega644p. Der Atmega644p empfängt über
USART0 die Daten vom PC und sendet wieder über USART0 die Empfangene
Daten zum PC zurück. Als der PC ein Zeichen zum ATmega644p sendet, empfängt
der Atmega644p das Zeichen und dann sendet der Atmega644p das empfangene
Zeichen zum PC zurück. Danach sendet der PC das nächste Zeichen und das gleiche Prozess soll sich wiederholen.
Momentan ist der Atmega644p in der Lage Daten vom PC zu empfangen. Aber
der Atmega644p sendet nicht die Daten zum PC zurück. Also,meine
interruptsfunktion ISR(USART0_TX_vect) und ISR(USART0_UDRE_vect) funktioniert nicht.
Ich wäre sehr dankbar, wenn jemand mir hilft.
Danke im Voraus.
Mein Code.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <avr/pgmspace.h>
#define F_CPU 3686400UL
#define FOSC 7372000 // Clock Speed
#define BAUD 9600UL
// Berechnungen zur Baudrate:
#define UBRR_VAL ((FOSC+BAUD*8)/(BAUD*16)-1) // clever runden
#define usart0_rx_buffer_max_size 50
/************************************************** */
char usart0_rx_buffer[usart0_rx_buffer_max_size];
volatile uint8_t usart0_rx_buffer_size = 0;
/************************************************** **/
void USART_Init (unsigned int ubrr)
{
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char) ubrr;
// UBRR1H = (unsigned char)(ubrr>>8);
// UBRR1L = (unsigned char) ubrr;
UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0)|(0<<TXCIE0)|(0<<UCSZ02)|(0<<UDRIE0);
UCSR0C = (0<<USBS0) | (1<<UCSZ01)|(1<<UCSZ00);// 1 Stopbit, 8 Bits
DDRB = 0b11111111; // Setting PB7-PB0 as output
PORTB = (0<<PB7); // USART0 receive data from pc
}
ISR(USART0_RX_vect)
{
char data = UDR0;
if (usart0_rx_buffer_size < usart0_rx_buffer_max_size)
{
usart0_rx_buffer[usart0_rx_buffer_size] = data;
++usart0_rx_buffer_size;
/* Activation transmission of data, then we have data in the buffer */
UCSR0B |= (1<<UDRIE0);
}
}
ISR(USART0_TX_vect)
{
UCSR0B &= ~((1<<UDRIE0)|(1<<TXCIE0));
}
ISR(USART0_UDRE_vect)
{
int i;
if (usart0_rx_buffer_size == 0) // If we have no data to send
{
UCSR0B &= ~(1<<UDRIE0);// we stop transmission
}
else
{
UDR0 = usart0_rx_buffer[0];
--usart0_rx_buffer_size;
if (usart0_rx_buffer_size == 0)
{
UCSR0A = (0<<TXC0);
UCSR0B = (1<<TXCIE0; // TX-Interrupt aktivieren
}
else
// it can be a circular buffer
for (i = 0; i < usart0_rx_buffer_size; ++i)
usart0_rx_buffer[i] = usart0_rx_buffer[i + 1];
}
}
int main (void)
{
USART_Init(UBRR_VAL) ; // USART Initialisierung
sei();
while(1)
{
}
}
- - - Aktualisiert - - -
Ich habe das Problem gelöst.
ISR(USART0_RX_vect)
{
char data = UDR0;
if (usart0_rx_buffer_size < usart0_rx_buffer_max_size)
{
usart0_rx_buffer[usart0_rx_buffer_size] = data;
++usart0_rx_buffer_size;
/* Activation transmission of data, then we have data in the buffer */
UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(1<<UDRIE0);
}
}
ISR(USART0_TX_vect)
{
UCSR0B &= ~((0<<RXEN0)|(0<<TXEN0)|(1<<TXCIE0)|(1<<UDRIE0));
}
ISR(USART0_UDRE_vect)
{
int i;
if (usart0_rx_buffer_size == 0) // If we have no data to send
{
UCSR0B &= ~((0<<RXEN0)|(0<<TXEN0)|(1<<TXCIE0)|(1<<UDRIE0));// we stop transmission
}
else
{
UDR0 = usart0_rx_buffer[0];
--usart0_rx_buffer_size;
if (usart0_rx_buffer_size == 0)
{
UCSR0A = (0<<RXC0)|(0<<TXC0)|(1<<UDRE0);
UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(1<<UDRIE0)|(1<<TXCIE0);
}
else
// it can be a circular buffer
for (i = 0; i < usart0_rx_buffer_size; ++i)
usart0_rx_buffer[i] = usart0_rx_buffer[i + 1];
}
}