Hallo zusammen,
ich beschäftige mich jetzt seit einigen Tagen mit PIC-Prozessoren,
wesentlich mehr Erfahrung habe ich mit den ATMega's von Atmel.
Es ist nicht möglich, mehrere Zeichen über die UART-Schnittstelle an ein
Terminalprogramm zu senden. Es kommt immer nur das erste und das letzte
Zeichen an (Wenn ich "MICROCHIP." senden will, kommt nur "M.").
Senden per String über die Funktion "UART_Zeile_senden" geht überhaupt
nicht, da kommt am PC gar nix an.
Ich tüftel nun schon einige Tage und studiere das Datenblatt und
Internetseiten rauf und runter, aber ich komm nicht drauf...
Ich verwende MPLAB x IDE v 1.60, einen PIC 18F258, einen MAX232, und
HTERM 0.8.1
Danke ;)
Christian
main.c:
void UART_Zeichen_senden(unsigned char zeichen)
{
// Zeichen in den Ausgabepuffer schreiben
TXREG = zeichen;
// Warten, bis das Zeichen gesendet wurde
while(PIR1bits.TXIF);
}
Danke für diese fixe Antwort. Manchmal kann's so einfach sein... Hab das
1<< übersehen...
Klappt aber leider nicht ganz.
so:
1
while((PIR1&(1<<TXIF)));
sendet er gar nix. Terminalfenster bleibt leer.
und so:
1
while(!(PIR1&(1<<TXIF)));
funktioniert's zwar teilweise, aber mit dem oben angegebenen Quellcode
kommt nur "MCOHP." im Terminalfenster an.
Irgendwie vergisst der da die Hälfte, aber ich weiß nicht warum
:-(
Christian
>ein syntax error vom compiler
Komplette Fehlermeldung posten.
Welcher Compiler?
Und wieso definiert du den ganzen Kram hier neu?
myuart.h:
// Bitdefinitionen
#define SPEN 7
#define TX9 6
#define TXEN 5
#define SYNC 4
#define BRGH 2
#define TRMT 1
#define TXIF 4
Das steht mit Sicherheit irgendwo in einer Headerdatei vom Compiler.
ok hier die Meldung:
Error: syntax error
in Zeile:
while(!TXSTAbits.TRMT); // Loop til TXREG empty
Die Definitionen deswegen, weil der Compiler die Bits nicht kennt, und
rot unterstreicht. Ich hab mir auch noch nicht die Mühe gemacht, die
entsprechende Headerdatei zu suchen und einzubinden.
Christian
>weil der Compiler die Bits nicht kennt
Welcher Compiler?
Was passiert wenn du diese Zeile
TXSTA &= ~(1<<BRGH); // High Speed Aus
so schreibst
TXSTAbits.BRGH = 0; // High Speed Aus
holger schrieb:> TXSTAbits.BRGH = 0;holger schrieb:>>weil der Compiler die Bits nicht kennt>> Welcher Compiler?>> Was passiert wenn du diese Zeile>> TXSTA &= ~(1<<BRGH); // High Speed Aus>> so schreibst>> TXSTAbits.BRGH = 0; // High Speed Aus
Compiler: C18 (v3.45) [C:\Program Files\Microchip\mplabc18\v3.45\bin]
Da passiert: myuart.h:19:Error: syntax error
Rufus Τ. Firefly schrieb:> void UART_Zeile_senden(char *zeile)> {> // Solange senden, bis Stringende erreicht> while(*zeile)> {> // Einzelnes Zeichen senden> UART_Zeichen_senden(*zeile);>> // Nächstes Zeichen> *zeile++; // <--- ?> }> }>> In der gekennzeichneten Zeile:>> Was genau wird da inkrementiert?> Und was soll inkrementiert werden?
oh, der Stern muss da weg ;-)
Christian
>Da passiert: myuart.h:19:Error: syntax error
Dann mach mal ein
#include <p18f258.h>
da rein.
Wie kommt man eigentlich auf die Idee Funktionen in
eine Header Datei zu legen?
holger schrieb:> Wie kommt man eigentlich auf die Idee Funktionen in> eine Header Datei zu legen?
Sowas lernt man wohl in drei Jahren der AVR "Programmiererei".
Jetzt nimmst du mal das:
void UART_Zeichen_senden(unsigned char zeichen)
{
while(!TXSTAbits.TRMT); // Loop til TXREG empty
TXREG = zeichen; //Send data
}
Und entfernst das
#define TRMT 1
>Erklärbär doch mal wieso das nicht gehen soll.
Weil
while(!TRMT);
mit seinem define mit Sicherheit nicht auf TXSTA zugreift.
Danke! Sieht gut aus.
Es kommt: "MICROCHIP."
Nur diese Zeile: UART_Zeile_senden("TECHNOLOGY.");
ist noch ohne Funktion... Da kommt leider nix.
Christian
holger schrieb:> Noch ein Versuch:
Leider nicht :-(
Mit dem unten angegebenen Code kommt im Terminalfenster "MICROCHIP." an.
Das "TECHNOLOGY." fehlt.
Hier mal im Anhang mein aktueller Quellcode, damit man mal einen
Überblick hat, was alles mittlerweile verändert wurde.
Aktueller Stand "main.c":
1
#pragma config OSC = HS // 14,7456 MHz
2
#pragma config PWRT = ON // Power-On-Timer
3
#pragma config WDT = OFF // Watchdog off
4
5
#include<delays.h>
6
#include<p18f258.h>
7
8
// Ausgänge initialisieren
9
voidAusgaenge_Init(void)
10
{
11
TRISCbits.RC3=0;// C3: LED rot
12
TRISCbits.RC4=0;// C4: LED grün
13
}
14
15
// Eingänge initialisieren
16
voidEingaenge_Init(void)
17
{
18
// A0: Fotowiderstand
19
}
20
21
// Funktion Pin C3 Ein- oder Ausschalten
22
voidSet_LED_rot(charstatus)
23
{
24
if(status)LATCbits.LATC3=1;
25
if(!status)LATCbits.LATC3=0;
26
}
27
28
// Funktion Pin C4 Ein- oder Ausschalten
29
voidSet_LED_gruen(charstatus)
30
{
31
if(status)LATCbits.LATC4=1;
32
if(!status)LATCbits.LATC4=0;
33
}
34
35
// UART initialisieren
36
voidUART_Init(void)
37
{
38
SPBRG=3;// Baud Rate Generator Register, 57600 bd
39
TXSTAbits.BRGH=0;// High Speed Aus
40
TXSTAbits.SYNC=0;// Asynchroner Modus
41
TXSTAbits.TX9=0;// 8-bit-Übertragung
42
TXSTAbits.TXEN=1;// Transmit Enable
43
RCSTAbits.SPEN=1;// RX und TX Pins aktivieren
44
}
45
46
voidUART_Zeichen_senden(unsignedcharzeichen)
47
{
48
while(!TXSTAbits.TRMT);// Warten, bis TXREG leer ist
holger schrieb:> Dann vieleicht so:>> void UART_Zeile_senden(const rom char *zeile)>> So ging das bei mir immer.
ok vielen Dank! :-)
Werd mich aber dann doch wohl wieder der AVR-"Programmiererei" zuwenden,
und mich mal durch gute C-Bücher lesen...
Christian
>und mich mal durch gute C-Bücher lesen
Das wird leider auch nichts helfen, wenn du das Grundprinzip der
seriellen Datenübertragung beim Senden nicht kapieren willst!
Man muss ERST abfragen, ob das VORHERIGE Zeichen rausgegangen ist und
der Sendebuffer somit frei (geworden) ist.
NUR DANN darf man in das Sende-Datenregister schreiben.
Du machst das genau falsch herum und so hast du den Effekt "jeden 2.
Zeichen fehlt" und ähnliches.
Anschliessend warten braucht man nicht bzw. sollte das auch nicht tun.
Warum? Das kannst dir jetzt selbst überlegen!
Gruss
Erich schrieb:> Man muss ERST abfragen, ob das VORHERIGE Zeichen rausgegangen ist und> der Sendebuffer somit frei (geworden) ist.
Macht er ja jetzt auch nicht mehr
1
voidUART_Zeichen_senden(unsignedcharzeichen)
2
{
3
while(!TXSTAbits.TRMT);// Warten, bis TXREG leer ist
4
TXREG=zeichen;// Zeichen senden
5
}
´
Das sieht für mich durchaus OK aus.
Aber wenn ich mich recht erinnere, und worauf auch Holger hinauswollte:
Auf einigen PIC gibt es da so einen Fallstrick, dass ein
Character-Literal, also ein konstanter String - eben nicht ein const
char* ist, sondern dass das ganze übers Flash abgewickelt wird (da wird
der String in den Programmcode eingebettet). D.h. man muss dauernd drauf
achten, ob man jetzt eine String-Konstante oder ein tatsächlich
variables char-Array hat und dann je nachdem die richtige Funktion
aufrufen.