Mit den Atmega8535 möchte ich Daten via RS232 empfangen und senden. In meiner Applikation verwende ich als Takt einen ext. 8 Mhz Quarz. Mein uC kann von der RS232 kein Zeichen empfangen. Ich habe mir das Datenblatt angeschaut. Da komme ich nicht klar mit. Wie kommt man darauf, das diese beiden Register: UCSRB=0xD8; //Baudrate 9600 UBRRL=0x33; so eingestellt werden müssen? Sind die beiden Register so richtig ingestellt? ATMEGA8535 C-Codeausschnitt: //***************************************************** interrupt [USART_RXC] void uart_rx_isr(void) { Zeichen = UDR; } interrupt [USART_TXC] void uart_tx_isr(void) { } //Hauptprogramm void main(void) { DDRB = 0xFF; PORTB = 0; DDRD = 0x00; PORTD = 0; PORTC_output(); t6963cinit(); LCD_Clear_Graphics(); LCD_Clear_Text(); UCSRB=0xD8; UBRRL=0x33; ACSR=0x80; #asm("sei") while (1) { delay_ms(100); lcd_printfz(0, 3,"Zeichen:%2x",Zeichen); if (PIND.1 == 1) { putchar('X'); } }; }
also erst uscrc schreiben (ursel bit setzen!) dann ubbrh und ubbrl schreiben (ursel in ubbrh nicht setzen) und dann uscrb schreiben grund für ursel bit ist, dass sich ubbrh und uscrc den selben speicher teilen grund für die reihenfolge ist, dass erst die einstellungen abzuschließen sind, bevor man etwas einschaltet (um fehler zu vermeiden)
wie man darauf kommt: einfach im datenblatt (was schon recht gut strukturiert ist - habe schon bescheidenere von anderen herstellern gesehen) die "USART Register summary" heraussuchen dort dann ein register nach dem anderen durchgehen. für die baudrate gibt es formeln oder auch tabellen mit beispielen (auch im datenblatt) die restlichen werte entstehen einfach durch das kombinieren der einzelnen bits. Es ist aber besser die bytes per schiebe-befehl zusammen zu bauen. bei codevisionavr (den scheinst du zu verwenden) sind die werte in dem header enthalten. z.B. USCRB = (1<<TXEN)|(1<<RXEN) ... (1<<3) |(1<<4) ... Tip für die Zukunft: Den Compiler-Namen mit dazu schreiben. C im Embedded Bereich ist NICHT genormt, weil einige verwendete dinge nicht im standard ansi-c stehen.
Puhh...ich bin jetzt irgendwie verwirrt. Könnte Ihr mir ein Beispiel dazu geben? Mit den Register komme ich durcheinander? In meinem C Programm verwende ich hierfür nur, UCSRB und UBRRL. Das register kenn ich nicht: USCRB und ubbrh und uscrc.
Im Prinzip sind nur diese Register -> UDR, UCSRB und UBRRL relevant, oder?
Im Prinzip sind nur diese Register -> UDR, UCSRB und UBRRL relevant, oder?
So, ich hab mal jetzt ein kleines Programm für den ATMEGA8535 mit CodeVision AVR geschrieben. Die RS232 verhält sich komisch beim ATMEGA8535. Es scheint so zu sein, dass das senden funktioniert. Nur der empfang funktioniert nicht. Ich kann am Controller nix empfangen. ********************************* #include <mega8535.h> #include <glcd_t6963.h> #include <delay.h> #include <math.h> #include <string.h> #include <delay.h> #include <stdlib.h> #include <stdio.h> unsigned char SetBaudrate = 0x33; // Baudrate 9600 Baud (ext.Quarz 8Mhz) // Stopbit = 1, Parity = none, Data Bits = 8 void USART_Transmit (unsigned char data) { while(!(UCSRA & (0x20))) ; UDR = data; } unsigned char USART_Receive (void) { while(!(UCSRA & (0x80))) ; return UDR; } //***************************************************** //***************************************************** //Hauptprogramm void main(void) { DDRB = 0xFF; PORTB = 0; DDRD = 0x00; PORTD = 0; t6963cinit(); LCD_Clear_Graphics(); LCD_Clear_Text(); UBRRL = SetBaudrate; UCSRB=0x18; UCSRC=0x86; ACSR=0x80; #asm("sei") while (1) { delay_ms(150); LCD_printfz(0,1,"Zeichen:%2x",USART_Receive()); }; }
Kann niemand zu dem C-Code was sagen? ********************************* #include <mega8535.h> #include <glcd_t6963.h> #include <delay.h> #include <math.h> #include <string.h> #include <delay.h> #include <stdlib.h> #include <stdio.h> unsigned char SetBaudrate = 0x33; // Baudrate 9600 Baud (ext.Quarz 8Mhz) // Stopbit = 1, Parity = none, Data Bits = 8 void USART_Transmit (unsigned char data) { while(!(UCSRA & (0x20))) ; UDR = data; } unsigned char USART_Receive (void) { while(!(UCSRA & (0x80))) ; return UDR; } //***************************************************** //***************************************************** //Hauptprogramm void main(void) { DDRB = 0xFF; PORTB = 0; DDRD = 0x00; PORTD = 0; t6963cinit(); LCD_Clear_Graphics(); LCD_Clear_Text(); UBRRL = SetBaudrate; UCSRB=0x18; UCSRC=0x86; ACSR=0x80; #asm("sei") while (1) { delay_ms(150); LCD_printfz(0,1,"Zeichen:%2x",USART_Receive()); }; }
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.