Gast
#446330
Hallo
Ich programmiere einen ADuC7026.
Ich kann einen Text mit dieser Funktion ausgeben:
int PutCharUart (char ch) { // Schreibe Char auf uart
while ((COMSTA0 & 0x40)==0) {} // Warte bis Sendepuffer leer ist
if (ch==LF) { // Wandle Zeilenende um
COMTX = CR; // Sende Zeichen
return 0;
}
COMTX = ch; // Sende Zeichen
return 0;
}
Leider wartet die Funktion so lange, bis der Sendepuffer leer ist.
Daher habe ich mir folgendes überlegt:
* Sende das Zeichen, wenn Sendepuffer leer ist
* Kopiere das Zeichen in Zwischenspeicher, wenn Sendepuffer voll ist
So bald der Sendepuffer wieder leer ist, wird ein Interrupt ausgelöst.
In der Interrruptfunktion wird ein Zeichen gesendet.
const short int sizeofuartbuffer = 50; // Größe des Array 50==100
Zeichen
// Speichere in einem "short int" 2 Zeichen.
// -> Positionspuffer beinhaltet 2 Informationen:
// posbuffer / 2 == Position im Array
// posbuffer % 2 == Position im "short int"
short int uarttxbuffer[50]; // Sendepuffer
short int readuarttxbuffer; // Lese ab hier Messwerte auf Puffer
short int writeuarttxbuffer; // Schreibe ab hier Messwerte in Puffer
int PutCharUart (char ch) {
if (ch==LF) ch=CR; // Wandele Zeilenende um.
// while ((COMSTA0 & 0x40)==0) {}
// COMTX = ch;
if ((COMSTA0 & 0x40)==1) { // Sendepuffer leer, Sende nächstes Zeichen
COMTX = ch;
}
else { // Kopiere Wert in Puffer
writeuarttxbuffer++;
writeuarttxbuffer = writeuarttxbuffer % (sizeofuartbuffer*2);
int ArrayPos = writeuarttxbuffer / 2;
int ShortIntPos = writeuarttxbuffer % 2;
int highbyte;
int lowbyte;
if (ShortIntPos==0) {
highbyte = ch << 8;
lowbyte = uarttxbuffer[ArrayPos] & 0x00FF;
}
else {
lowbyte = ch;
highbyte = uarttxbuffer[ArrayPos] & 0xFF00;
}
uarttxbuffer[ArrayPos] = highbyte + lowbyte;
}
return 0;
}
void IrqUart (void) {
if (writeuarttxbuffer!=readuarttxbuffer) { // Zeichen im Sendepuffer
if ((COMSTA0 & 0x40)==1) { // Sendepuffer leer, Sende nächstes
Zeichen
readuarttxbuffer++;
readuarttxbuffer = readuarttxbuffer % (sizeofuartbuffer*2);
int ArrayPos = readuarttxbuffer / 2;
int ShortIntPos = readuarttxbuffer % 2;
if (ShortIntPos==0) COMTX = uarttxbuffer[ArrayPos] & 0xFF00; //
high byte
else COMTX = uarttxbuffer[ArrayPos] & 0x00FF; // low byte
}
}
}
void My_IRQ_Function (void) {
IrqUart();
if ((IRQSTA & UART_BIT) != 0) { // Uart
IrqUart();
}
int main(void) {
GP1CON |= 0x0011; // Aktiviere uart
COMCON0 = 0x080; // Erlaube setzen der Baudrate
int cd = (POWCON & 0x07); // aktuelle Taktrate
// Formel zur Baudratenbestimmung aus uC Handbuch S. 62
int dl = (1305625 >> cd) / rate;
COMDIV0 = (dl & 0x00FF); // Setze Lowbyte
COMDIV1 = (dl & 0xFF00); // Setze Highbyte
COMCON0 = 0x003; // Verwende 8bit Wörter mit 1 Stopbit
// Setze Variablen auf 0, Startbedingung
readuarttxbuffer=0;
readuartrxbuffer=0;
writeuarttxbuffer=0;
writeuartrxbuffer=0;
COMIEN0 = 0x03; // Aktiviere Interrupt, wenn RX oder TX Puffer voll
for (int i=0; i<50; i++)
PutCharUart('X');
}
Leider erhalte ich gar keine Ausgabe mehr.
Woran könnte das liegen?
Vielen Dank,
Tilo