PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Hilfestellung zu UART



chisi
10.02.2006, 20:59
abend
bin noch ein ziemlicher newbie also bitte seit nett zu mir...*gg*

zuerst einmal, was ist der unterschied zwischen rs232 und uart??kann ich ein uart-signal einfach mit meinem usbtoserial-converter empfangen?brauch ich dafür nur 2 leitungen??

ausgangssituation: ich habe ein evaluationboard mit aduc7024 (programmiere mit keil uvision 3) und generiere damit ein 3phasen pwm signal um einen linearmotor anzusteuern. funzt alles.
nun muss ich dem uC über rs232 (oder uart?!?) einen sollwert vorgeben, zu dem er fahren soll.

beim uC waren einige code examples dabei, check aba net ganz warum man da nicht einfach printf oda so nimmt?!?!?

wie funkt das mit dem empfangen auf dem uc?muss ich da jedesmal einen interrupt auslösen??

hier die 2 code examples


#include <ADuC7024.h>


void senddata(short);
void delay(int);
char hex2ascii(char);

int main (void) {

unsigned short SOMEDATA[1024];
int i;

GP0CON = 0x10000000; // enable ECLK output on P0.5

// configures GPIO to flash LED P4.2
GP4DAT = 0x04000000; // P4.2 configured as an output. LED is turned on

// Setup tx & rx pins on SPM 0 and SPM 1
GP1CON = 0x011;

// Start setting up UART at 9600bps
COMCON0 = 0x080; // Setting DLAB
COMDIV0 = 0x093; // Setting DIV0 and DIV1 to DL calculated
COMDIV1 = 0x000;
COMCON0 = 0x007; // Clearing DLAB

for (i=0; i <1024; i++)
{
SOMEDATA[i]=i;
}

while(1)
{
for (i=0; i <1024; i++)
{
senddata (SOMEDATA[i]);
}
GP4DAT ^= 0x00040000; // Complement P4.2
delay(2000);
}
}


void delay (int length)
{
while (length >=0)
length--;
}

void senddata(short to_send)
{
while(!(0x020==(COMSTA0 & 0x020))){}
COMTX = 0x0A; // output LF
while(!(0x020==(COMSTA0 & 0x020))){}
COMTX = 0x0D; // output CR
while(!(0x020==(COMSTA0 & 0x020))){}
COMTX = hex2ascii ((to_send >> 8) & 0x0F);
while(!(0x020==(COMSTA0 & 0x020))){}
COMTX = hex2ascii ((to_send >> 4) & 0x0F);
while(!(0x020==(COMSTA0 & 0x020))){}
COMTX = hex2ascii (to_send & 0x0F);
}


char hex2ascii(char toconv)
{
if (toconv<0x0A)
{
toconv += 0x30;
}
else
{
toconv += 0x37;
}

return (toconv);
}





#include <ADuC7024.h>

#define CR 0x0D

int write (int file, char * ptr, int len); // Functions used to
int getchar (void); // to output data
int putchar(int); // Write character to Serial Port


int main (void) {
unsigned char jchar = 0x30;

char output1[13] = "Hello World\n";

// Setup tx & rx pins on P1.0 and P1.1
GP1CON = 0x011;

// Start setting up UART at 9600bps
COMCON0 = 0x080; // Setting DLAB
COMDIV0 = 0x093; // Setting DIV0 and DIV1 to DL calculated
COMDIV1 = 0x000;
COMCON0 = 0x007; // Clearing DLAB

GP4DAT = 0x04000000; // P4.2 configured as an output. LED is turned on

while(1)
{

GP4DAT ^= 0x00040000; // Complement P4.2
write(0,output1,13); // Output Data
jchar = getchar(); // RX Data, Single Byte
write(0,&jchar,1); // Output Rxed Data
}
}

int putchar(int ch) { /* Write character to Serial Port */

if (ch == '\n') {
while(!(0x020==(COMSTA0 & 0x020)))
{}
COMTX = CR; /* output CR */
}
while(!(0x020==(COMSTA0 & 0x020)))
{}

return (COMTX = ch);
}


int getchar (void) { /* Read character from Serial Port */

while(!(0x01==(COMSTA0 & 0x01)))
{}
return (COMRX);
}

int write (int file, char * ptr, int len) {
int i;

for (i = 0; i < len; i++) putchar (*ptr++);
return len;
}

hoff ihr seit schlauer als ich

danke im voraus

ruediw
11.02.2006, 12:19
Salü Chisi,

RS-232 definiert die physikalischen und elektrischen Eigenschaften der seriellen Schnittstelle:
1. Stecker
2. Spannungspegel
Siehe dazu auch:
https://www.roboternetz.de/wissen/index.php/RS232
http://de.wikipedia.org/wiki/RS232

Das Uart ist das Modul oder der Chip der die Wandlung der
parallel vorliegenden Daten in den seriellen Datenstrom vornimmt.
Siehe dazu auch:

https://www.roboternetz.de/wissen/index.php/UART
http://de.wikipedia.org/wiki/UART

Damit Du nun die Daten mit dem uC austauschen kannst, muss das Uart
konfiguriert werden:
1. Baudrate (Geschwindigkeit)
2. Anzahl Startbits
3. Anzahl Datenbits
4. Anzahl Stoppbits
5. Parität

Diese Parameter müssen zwingend auf beiden Seiten
(PC und uC) übereinstimmen.

RS-232 selber definiert kein Protokoll. PrintF selber kannst Du verwenden
wenn Du einfach nur Daten zum PC senden und dort anzeigen willst.

Wenn Du aber Befehle zum uC senden willst, musst Du ein Protokoll
für die RS-232 implementieren. Dieses ist im Beispiel gemacht.

Normalerweise programmiert man den uC so, dass sobald der uC ein Zeichen empfängt, ein Interrupt ausgelöst wird.

Denke Du kannst das Beispielprogramm als Ausgangspunkt verwenden,
musst es aber an deine Bedürfnisse (Hardware, Protokoll) anpassen.

chisi
12.02.2006, 10:31
danke mal.

also das uart ist schon richtig konfiguriert im programmbeispiel. also kann ich mit einem terminalprogramm daten zum uc schicken, zum beispiel einen neuen sollwert. hab im datenblatt gelesen, dass ein interrupt ausgelöst wird, wenn COMRX voll ist: "Set automatically when COMRX is full. Cleared by reading COMRX."
das funktioniert aber nur zeichenweise oder? also jedes zeichen einzeln?wenn ich das dann in einem array speichern will, woher weiß ich die länge des arrays, das ich definieren muss?

daten zum pc z.b. aktueller istwert, kann ich einfach über printf, wenn die schnittstelle konfiguriert ist oder?

wie meinst du das mit wenn ich befehle zu uc senden will?was sind befehle? sind ja auch nur daten oder?

ruediw
12.02.2006, 11:48
Wie Du richtig bemerkt hast, wird beim Empfang eines Zeichens
ein Interrupt ausgelöst. Dieses Zeichen solltest Du in deiner ISR
abholen und in einen Buffer ablegen. Dies ist ein Array. Die Grösse
des Arrays ist natürlich abhängig davon wie lang den Befehl ist.

Bsp. Dein Befehl ist: (ohne Hochkomma)
Chr(STX) + "DR2000" + Chr(13) = Drehe Rechts 2000 Schritte
Dies sind 8 Zeichen. Deshalb muss dein Buffer mindestens 8
Zeichen aufnehmen können.

In diesem Beispiel setzt Du wenn Du das Zeichen <STX> empfängst ein
Flag dass Du einen neuen Befehl empfängst. Du Kopierst das Zeichen in deinen Buffer.
Wenn Du das Zeichen Chr(13) empfängst weisst Du dass Du den ganzen Befehl empfangen hast und kannst diesen nun auswerten.
Du setzt also in deiner ISR das Flag zurück. Dieses Wertest du nun aus.
Das ganze ist das, was ich unter dem Protokonll angedeutet habe.
Oftmals werden in den Befehl auch Informationen zur Fehlerkorrektur
eingebettet.

http://de.wikipedia.org/wiki/Netzwerkprotokoll

chisi
19.02.2006, 11:16
danke erstmal.

ich habe es diese woche geschafft (nach großen ärgernissen und dann programmupdate) dass ich beim empfang eines zeichens einen interrupt auslöse. das funktioniert soweit.

jetzt brauchte ich z.b. wenn ich 4 zeichen (zahlen) abhole und in ein array[4] speichere, dass ich dass dann in eine normale zahl "umwandle", also wenn array[4] = {1,2,3,4} dann soll wert = 1234 herauskommen.
ist das möglich?