Hallo leute,
Ich habe ein Programm geschrieben jedoch bekomme ich beim ausführen eine
fehlermelding
"undefined reference to USART_Transmit"
muss ich da eventuell irgendwelche Bibliotheken hinzufügen?
Ich habe die bibliotheken
#include <avr/io.h>
#include <inttypes.h>
#define FOSC 12000000UL //12MHz Taktfrequenz
#define BAUD 9600UL //9600 Baud
#define MYUBRR (FOSC/(16*BAUD))-1
bereits hinzugefügt, fehlen vielleicht welche?
Danke LG Thomas
>Ich habe die bibliotheken>>....>>bereits hinzugefügt, fehlen vielleicht welche?
Das sind Headerfiles.
Du hast die *.c Datei wo USART_Transmit drin ist
nicht mit compiliert.
Thomas schrieb:> ok danke,>> aber irgendwie funktioniert das itoa nicht dadurch sollten doch die ad> wandlerwerte in binär angezeigt werden,
wieso binär?
Du hast dezimale Rrepräsentierung angefordert.
char Werte[4]="";
Das ist zu knapp dimensioniert.
Du kriegst vom ADC Zahlenwerte bis 1023. Das sind alleine schon 4
Zeichen. Dazu noch das obligatorische \0 Zeichen, das jeden C-String
abshcliest macht 5 Zeichen.
USART_Transmit(Werte[0]);
USART_Transmit(Werte[1]);
USART_Transmit(Werte[2]);
USART_Transmit(Werte[3]);
Woher weißt du, das der String 4 Zeichen lang ist? Wenn der Messert 5
ist, dann ist der String auch nur 1 Zeichen lang!
ALs ersts schreibst du dir jetzt erst mal eine Hilfsfunktion, die einen
String ausgeben kann
1
voidUSART_Transmit_String(char*s)
2
{
3
while(*s!='\0'){
4
USART_Transmit(*s);
5
++s;
6
}
7
}
dann verwendest du die Funktion, um den String auszugeben, den dir itoa
erzeugt. Und damit du an der Ausgabe auch noch sehen kannst, wann die
nächste Zahl anfängt, gibst du nach der 'Zahl' auch noch ein Leerzeichen
aus. Sonst siehts du am Terminal im Zahlenwust nicht wo eine Zahl
aufhört und wo die nächste anfängt
1
...
2
3
charWerte[10];
4
5
while(1){
6
inti=ADC_Read(0);
7
8
itoa(i,Werte,10);
9
USART_Transmit_String(Werte);
10
USART_Transmit(' ');
11
}
12
}
und achte ein bischen besser auf eine saubere Formatierung und
Einrückung. Deine ADC Routinen sind ein Graus und schwer lesbar, weil
sie keine Form haben.
Hallo,
Ich habe den Programmcode jetzt umgeändert jedoch habe ich das Problem
dass ich immer noch nicht die AD Wandler Werte abgezeigt bekomme sonder
immer nur ein ý....
Das ist der geänderte Programmcode
Hast du denn schon mal getestet, ob die USART prinzipiell funktioniert?
(Baudrate und der ganze restliche Kram?)
Zum programm sag ich nix ausser: Kauf dir ein C-Buch
SChau doch mal was du ausgibst
void USART_Transmit( unsigned char data )
{
while (!(UCSRA &(1<<UDRE))); //Überprüfen ob Senden möglich
UDR = (ADC_Read(0)); //Senden eines Returns
}
Der Befehl gibt ja die AD Wandlerwerte aus
UDR = (ADC_Read(0)); //Senden eines Returns
Die Überprüfung ob das senden möglich ist müsste ich eventuell
rausnehmen, nehm ich an
Hüsameddin N. schrieb:> Der Befehl gibt ja die AD Wandlerwerte aus
Oh Mann.
NEIN!
AUfgabe der Funktion USART_Transmit ist es nicht, die
'Wandlerergebnisse' auszugeben, sondern das Zeichen, welches die
Funktion als Argument in Data bekommt auszugeben!
void USART_Transmit( unsigned char data )
{
while (!(UCSRA &(1<<UDRE)))
;
UDR = data;
}
das ist die Aufgabe dieser Funktion.
Der Funktion ist es nämlich schnurzpiepegal, wo das Byte herkommt, das
es auf der USART ausgeben soll.
Im konkreten Fall kommt das Zeichen von hier
void USART_Transmit_String( char* s )
{
while( *s != '\0' )
{
USART_Transmit( *s );
++s;
}
}
Der String wird ausgegeben, indem Zeichen für Zeichen an die Funktion
USART_Transmit übergeben wird, welche dann das Zeichen ausgibt.
Gibt man alle Zeichen hintereinander aus, dann hat man den kompletten
String ausgegeben.
So
Wo kommt jetzt wieder der String her?
Der kommt von hier
USART_Transmit_String( Werte );
Der String steht in Werte.
Wie kommt er dort rein?
itoa( i, Werte, 10 );
der kommt dort rein, weil ihn itoa dort rein schreibt. itoa nimmt sich
den Zahlenwert von i, erzeugt einen entsprechenden String dafür.
Wo kommt jetzt wiederrum das i her?
Von hier
int i = ADC_Read(0);
i ist also der Wert, den der ADC am Kanal 0 gelesen hat.
In Summe und in chronologischer Reihenfolge
der ADC wird ausgelesen
der Wert vom ADC wird in einen String gewandelt
dieser String wird an USART_Transmit_String übergeben
USART_Transmit_String wiederrum gibt den String Zeichen für
Zeichen aus, indem es dazu die Funktion USART_Transmit benutzt
Und deshalb darf USART_Transmit nicht den ADC auslesen, sondern einfach
nur seinen Job machen: Es bekommt ein Zeichen und dieses gibt es aus.
@Hüsameddin N. (hsameddin_n)
>Ich habe den USART_Transmit geändert, jedoch bekomme ich trotzdem von>termite irgendwelche zeichen (siehe anhang)
Falsche Baudrate oder Taktquelle.
Alle Jahre wieder . . .
http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART
Hallo,
Punkt 1: verwende in deinem Code in zukunft tabstopps! Das erhöht
merklich die übersicht
Punkt 2: Schreibe Methoden nicht in dein Hauptprogramm main, sondern
danach
Punkt 3: um deutlich zahlen auf dem Termialprogramm ablesen zu können,
empfehle ich die Escapesequenzen: \n -> new line, \r -> carriage return
Diese befehle der folgenden methode übergeben:
"dieser String wird an USART_Transmit_String übergeben"
Punkt 4: Schau dir noch mal genau! das AVR GCC tutorial an, dort wird
gut erklärt, was du wie machen musst bezgl. ADC und USART (C-kenntnisse
vorrausgesetzt)
Punkt 5: Anstatt die Baudrate zu berechnen würde ich empfehlen die im
datenblatt vermerkten Zahlen direkt zu übergeben. Eine fehlerquelle
weniger.
Punkt 6: Leider hast du nicht deinen versuchsaufbau beschrieben, aber
ein weiterer fehler könnte eine fehlende GND verbindung zwischen uC und
PC sein. Bei müssen das gleiche bezugspotenzial haben.
Punkt 7: mach die Variable werte Lokal in eine Methode (-> googlen),
weil du damit einem Zeigerproblem aus dem Weg gehst.
Punkt 8:
1
TIMSK|=(1<<TOIE0);//Timer Interrupt 0 verwenden
2
TCCR0|=((1<<CS02)|(1<<CS00));//Oszilatorenfrequenz durch 1024 teilen
Diese Zeilen sind überflüssig, da du erstens Interrupst global nicht
aktivierst und zweitens keine ISR hast, die den interrupt
abfängt->Streichen
Punkt 9: bei allen zuweisungen in register, fass das gesammte argument
rechts von der Zuweisung in Klammern.
Punkt 10: Leider kenn ich deinen Chiptyp nicht, aber in AVR
Datenblättern wird eigentlich immer angegeben (in c-code), wie du den
internen ADC ausliest, dort mal nachschauen, ob ADCW unterstützt wird!
Punkt 11: ADCValue = ADC_Read(0); wieso? Der Wert wird nicht wieder
verwendet, du kannst dir diese Zeile und die Definition der Variable
sparen.
so das wars erstmal.. ich hoffe ich habe nichts doppelt erwähnt oder
mich verlesen.
PS: lies dir mal das GCC tutorial durch, und zwar ganz! Enorm
hilfreich..
Gruß Quadrocopter