ChristophB
12.03.2010, 16:02
Hallo ich versuche gerade meinen uC (atmega32) mit einem PC über UART zu verbinden.
Leider klappt das ganze nicht so richtig. Aus irgendeinem Grund liegen konstante 5V an meinem TX Pin. Der Max232 der das Signal wandeln soll funktioniert anscheinend, da hier passenderweiße -10 V anliegen.
Ich poste hier mal den Quellcode den ich verwende, villeicht kann mir ja jemand dabei helfen:
#include <avr/io.h>
#ifndef F_CPU
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert
(z.B. durch Übergabe als Parameter zum Compiler innerhalb
des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die
"nachträgliche" Definition hinweist */
#warning "F_CPU war noch nicht definiert, wird nun mit 1000000 definiert"
#define F_CPU 16000000UL /* Quarz mit 1,000000 Mhz */
#endif
#define BAUD 9600UL // Baudrate
// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
#endif
#include <util/delay.h> /* in älteren avr-libc Versionen <avr/delay.h> */
void long_delay(uint16_t ms) {
for(; ms>0; ms--) _delay_ms(1);
}
/* USART-Init beim ATmega16 */
void uart_init(void)
{
UCSRB |= (1<<TXEN); // UART TX einschalten
UCSRC |= (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // Asynchron 8N1
UBRRH = UBRR_VAL >> 8;
UBRRL = UBRR_VAL & 0xFF;
}
int main( void )
{
PORTD = 0x012;
DDRD = 0x012;//->PortD (LED-Segment) als Ausgabe definiert
uart_init();
// bei neueren AVRs steht der Status in UCSRA/UCSR0A/UCSR1A, hier z.B. fuer ATmega16:
while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */
{
}
while(1)
{
UDR = 'a'; /* schreibt das Zeichen a auf die Schnittstelle */
if(PORTD == 0x00){ //blink LED
PORTD = 0x04;
}
else{
PORTD = 0x00;
}
long_delay(100); //warte 100ms
UDR = 'b'; /* schreibt das Zeichen b auf die Schnittstelle */
if(PORTD == 0x00){ //blink LED
PORTD = 0x04;
}
else{
PORTD = 0x00;
}
long_delay(100); //warte 100ms
UDR = 'c'; /* schreibt das Zeichen c auf die Schnittstelle */
if(PORTD == 0x00){ //blink LED
PORTD = 0x04;
}
else{
PORTD = 0x00;
}
long_delay(1000); //warte 1000ms
}
return 0;
}
Leider klappt das ganze nicht so richtig. Aus irgendeinem Grund liegen konstante 5V an meinem TX Pin. Der Max232 der das Signal wandeln soll funktioniert anscheinend, da hier passenderweiße -10 V anliegen.
Ich poste hier mal den Quellcode den ich verwende, villeicht kann mir ja jemand dabei helfen:
#include <avr/io.h>
#ifndef F_CPU
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert
(z.B. durch Übergabe als Parameter zum Compiler innerhalb
des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die
"nachträgliche" Definition hinweist */
#warning "F_CPU war noch nicht definiert, wird nun mit 1000000 definiert"
#define F_CPU 16000000UL /* Quarz mit 1,000000 Mhz */
#endif
#define BAUD 9600UL // Baudrate
// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
#endif
#include <util/delay.h> /* in älteren avr-libc Versionen <avr/delay.h> */
void long_delay(uint16_t ms) {
for(; ms>0; ms--) _delay_ms(1);
}
/* USART-Init beim ATmega16 */
void uart_init(void)
{
UCSRB |= (1<<TXEN); // UART TX einschalten
UCSRC |= (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // Asynchron 8N1
UBRRH = UBRR_VAL >> 8;
UBRRL = UBRR_VAL & 0xFF;
}
int main( void )
{
PORTD = 0x012;
DDRD = 0x012;//->PortD (LED-Segment) als Ausgabe definiert
uart_init();
// bei neueren AVRs steht der Status in UCSRA/UCSR0A/UCSR1A, hier z.B. fuer ATmega16:
while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */
{
}
while(1)
{
UDR = 'a'; /* schreibt das Zeichen a auf die Schnittstelle */
if(PORTD == 0x00){ //blink LED
PORTD = 0x04;
}
else{
PORTD = 0x00;
}
long_delay(100); //warte 100ms
UDR = 'b'; /* schreibt das Zeichen b auf die Schnittstelle */
if(PORTD == 0x00){ //blink LED
PORTD = 0x04;
}
else{
PORTD = 0x00;
}
long_delay(100); //warte 100ms
UDR = 'c'; /* schreibt das Zeichen c auf die Schnittstelle */
if(PORTD == 0x00){ //blink LED
PORTD = 0x04;
}
else{
PORTD = 0x00;
}
long_delay(1000); //warte 1000ms
}
return 0;
}