PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RN-Minicontrol RS232 GCC



tr7
24.11.2006, 19:21
Hallo,
ich habe eine RN Minicontrol und möchte ein paar Debugdaten an den Rechner schicken. Es gibt auf dem Board ja anscheinend auch schon die 3 RS232 Pins, aber bisher klappt das Senden von Signalen noch nicht.
geht das irgendwie mit dem printf-Befehl? (ich programmiere in c)

Denn die UART Beispiele, die ich so gefunden habe klappen nicht (hat die RN Mini überhaupt UART funktionalität?)
Das Problem hier ist, dass der GCC Compiler einige Variablen gar nciht kennt:
main.c:4: error: `UCSRB' undeclared (first use in this function)

falls jemand ein kleines Beispiel hat zum senden eines Zeichens oder einer Zeichenkette über RS232, sodass man es mit nem Terminalprogramm auslesen kann, wäre ich äußerst dankbar :)

Gruß, Thomas

tr7
24.11.2006, 20:03
hab die Punkte hier in einem anderen Thread gefunden:

1. du hast RS232 Stecker (3 polig) falschruf aufgesteckt?
ist richtig rum

2. du hast am Terminalprogramm falschen RS232 Port gewählt?
auch richtig eingestellt

3. du hast am Terminalprogramm falsche Baudrate gewählt?
kann möglich sein, wie kann ich denn die Baudrate im C Programm angeben?
hab einfach 9600 im Terminal Programm angegeben und 8n1

4. du hast bei Fusebits den Quarz nicht korrekt aktiviert?
Müsste alles richtig eingestellt sein, da ich das Fertigmodul der RN Minicontrol gekauft habe

5. du hast bei Fusebits den Taktteiler nicht ausgeschaltet (DISABLE) (gibts nicht bei allen AVR´s, aber beim Mega168)?
da ich den 168 habe stellt sich mir nun die frage, ob ich das noch machen muss, oder ob das im Fertigmodul schon gemacht wurde

6. du hast einfach einen Aufbaufehler/Lötfehler gemacht?
das sicher nicht

linux_80
24.11.2006, 21:46
Hallo,
Du kannst uns auch deinen Test-Code zukommen lassen, evtl. lässt sich dann leichter erkennen woran es liegt.

Wegen dem nicht bekanntem Register vermute ich mal, der Controllername ist nicht richtig eingestellt, kann man im Makefile bei MCU angeben.
Dann werden mit #include <avr/io.h> auch die richtigen Namen eingebunden.

Beim Mega168 heisst Die UART UART0, deswegen muss man das auch im Namen angeben. In diesem Fall dann UCSR0B !

Die Baudrate muss man sich selber errechnen, anhand der CPU-Frequenz, das steht u.a. im DB, oder evtl. auch bei uns irgendwo im Wiki.
Der errechnete Wert kommt dann ins UBRR0 (BaudRateRegister UART0)
Auch die anzahl Stopbits, Parity usw. wird in den Registern angegeben.

Wenn Du nicht weisst wie es um die Fusebits steht, musst du sie einfach mal auslesen, erleichtert die weitere Arbeit ungemein ;-)
IMHO ist da an dem Mega168 noch nix umgestellt, also läuft der mit internen 1MHz.

Interessant wäre auch noch zu wissen mit welcher Hard- und Software Du hier zu werke gehst.

tr7
25.11.2006, 00:02
also der Code:

#include <stdlib.h>
#include <avr/io.h>
#include <stdio.h>
#include <stdint.h>

#define UART_BAUD_RATE 9600 // 9600 Baud

int main(void)
{
unsigned long x,y;

UCSR0B |= (1<<TXEN0); // UART TX einschalten
UCSR0C |= (1<<UMSEL00)|(3<<UCSZ00); // Asynchron 8N1

UBRR0 = F_CPU / (UART_BAUD_RATE * 16L) - 1;


while (1) {
while (!(UCSR0A & (1<<UDRE0))); /* warten bis Senden moeglich */
UDR0 = 'x'; /* schreibt das Zeichen x auf die Schnittstelle */
for(x=0;x<100000;x++)y++;
printf("test"); /*nur zum test*/
for(x=0;x<100000;x++)y++;
}

return 0; // never reached
}




Wegen dem nicht bekanntem Register vermute ich mal, der Controllername ist nicht richtig eingestellt, kann man im Makefile bei MCU angeben.
Dann werden mit #include <avr/io.h> auch die richtigen Namen eingebunden.

Beim Mega168 heisst Die UART UART0, deswegen muss man das auch im Namen angeben. In diesem Fall dann UCSR0B !

hab sie nur falsch benannt, danke für den Tipp

der AVR Programmer ist ein:
Found programmer: Id = "AVR ISP"; type = S
Software Version = 3.9; Hardware Version = 1.2

Ich programmiere im Programmers Notepad und programmiere auf dem AVR mit avrDude.

Bei dem Code oben kennt er nun alle Variablen...Programm läuft auch, aber ich empfange keine Daten im Hyperterminal...habe 8N1 eingestellt.
die Frequenz des Boards liegt übrigens ohne ändern der Fusebits bei 8MHz standardmäßig, jedenfalls bei mir.

Ist die Baudrate so richtig errechnet?

tr7
25.11.2006, 00:15
ich habe eine Zeile im Code mal versuchsweise geändert:
von
UCSR0C |= (1<<UMSEL00)|(3<<UCSZ00); // Asynchron 8N1
auf
UCSR0C |= (1<<UMSEL01)|(1<<UMSEL00)|(3<<UCSZ00)|(3<<UCSZ01); // Asynchron 8N1

und nun kommt schonmal was an im hyperterminal.
aber es sind irgendwie nur leerzeichen, die ausgegeben werden. Welche Option könnten denn dafür schon wieder verantwortlich sein? 8-[

linux_80
25.11.2006, 01:21
Printf ist normalerweise nicht gedacht um beim Controller über UART etwas auszugeben, es gibt da günstigere Möglichkeiten, dazu bitte im Wiki suchen.

Wenns unbedingt printf sein soll, gibts hier etwas:
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=214155#214155

tr7
25.11.2006, 15:46
hm, also ich empfange irgendwie mist und habe bisher keine Ahnung woran das liegt. Das RN-Wiki und das AVR Tutorial (http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Ganzzahlige_.28Integer.29_Datentypen) ahben mir auch nciht so richtig weiter helfen können.

wenn ich mit UART folgende Zeichenkette abschicke:
ABBCCCCDDDDDDDDEEEEEEEEEEEEEEEE

dann kommt folgendes im Terminalprogramm (http://www.der-hammer.info/terminal/index.htm) an:
00 18 18 1E 1E 1E 1E 60 60 60 60 60 60 60 60 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 00

vom Prinzip siehts ja gar nciht so schlecht aus, da die Anzahl der gleichen Zeichen stimmt...aber alle Zeichen sind irgendwie "verschoben"

woran kann das liegen?
Die Baudrate ist ja anscheinend schonmal richtig eingestellt[/url]


der Code dazu:

#include <stdlib.h>
#include <avr/io.h>
#include <stdio.h>
#include <stdint.h>

#define BAUDRATE 9600

void uart_init(){
uint16_t ubrr0 = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);

UBRR0H = (uint8_t) (ubrr0>>8);
UBRR0L = (uint8_t) (ubrr0);

// UART Receiver und Transmitter anschalten
// Data mode 8N1, asynchron
UCSR0B = (1 << RXEN0) | (1 << TXEN0);
UCSR0C = (1 << UMSEL00) |(1 << UMSEL01) | (1 << UCSZ01) | (1 << UCSZ00);

// Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte)
do{
uint8_t dummy;
(void) (dummy = UDR0);
}
while (UCSR0A & (1 << RXC0));
}

uart_putc (const uint8_t c){
// Warten, bis UDR bereit ist für einen neuen Wert
while (!(UCSR0A & (1 << UDRE0)));

// UDR schreiben startet die Übertragung
UDR0 = c;

return 1;
}

void uart_puts (const char *s){
do{
uart_putc (*s);
}
while (*s++);
}

int main(void){
unsigned long x,y;
int z=0;
uart_init();
while (1) {
uart_puts ("ABBCCCCDDDDDDDDEEEEEEEEEEEEEEEE");
for(x=0;x<1000000;x++)y++;
}
return 0; // never reached
}

ich vermute, dass ich die Bits für den 8N1 Modus nciht richtig eingestellt habe. Die Zeile sieht so aus:
UCSR0C = (1 << UMSEL00) |(1 << UMSEL01) | (1 << UCSZ01) | (1 << UCSZ00);

eigentlich stand im Tutorial statt UMSEL00 und UMSEL01 ein URSEL...gabs aber bei mir nicht, daher hatte ichs mal umbenannt in eine Variable, die sich so ähnlich angehört hat. Fehler hier?

m.a.r.v.i.n
25.11.2006, 16:53
Hi,

Das URSEL Bit muß beim mega168 nicht gesetzt werden.
Eigentlich müßte es so gehen:


UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);

Gruß m.a.r.v.i.n

tr7
25.11.2006, 20:20
Habs mal probiert und es kommt leider genau so ein Zeichenmüll an.

In einem anderem Thread steht, dass der Atmega noch intern mit 8MHz läuft und so ist es auch bei mir,wie es scheint.

ich habe dann mit avrdude die fusebits folgendermaßen verändert:
avrdude -p atmega168 -P com1 -c avr910 -U lfuse:w:0xFF:m -U hfuse:w:0xDF:m -U efuse:w:0xF9:m

beim übertragen vom efuse gibts zwar nen Fehler (kann nur 0x01 gesetzt werden), aber hat ja nicht sonderlich viel mit der Frequenz zutun. Die anderen werden laut Programm richtig gesetzt.

allerdings läuft der atmega168 immer noch mit 8MHz :-(
Die Fusebits stimmen doch aber so, oder nicht?
(hier (http://palmavr.sourceforge.net/cgi-bin/fc.cgi?P_PREV=ATmega168&P=ATmega168&V_LOW=7F&V_HIGH=DF&V_EXTENDED=F9&M_LOW_0x3F=0x3F&M_LOW_0x40=&M_LOW_0x80=&M_HIGH_0x07=0x07&M_HIGH_0x08=&M_HIGH_0x10=&M_HIGH_0x20=0x00&M_HIGH_0x40=&M_HIGH_0x80=&M_EXTENDED_0x01=&M_EXTENDED_0x06=0x00&B_CKDIV8=P&B_SPIEN=P&B_BOOTSZ1=P&B_BOOTSZ0=P) hab ich mir die zusammengeklickt)