PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PIC18F452: USART Kommunikation in C



mi.ja
09.02.2005, 10:35
Hallo zusammen,
Ich bin neu hier, habe schon von Anfang an einen superguten Eindruck!

Zudem habe ich ein Problem.
Ich will Daten von einem Funkempfänger (einer Wetterstation) auslesen, der eine RS-232-Schnittstelle hat. Das programm ist in C geschrieben (MPLAB 6.6, C18 Compiler). Für die nötigen Pegel sorgt ein MAX232ACPE.


Nun, um den Code ein bisschen zu erklären:
Um die "Verbindung" herzustellen, muss DTR High sein und RTS Low. Das Programm wartet, solange keine Daten ankommen. Steht die Verbindung, sollte der Wert $03 (ETX) ankommen und wird in "store" gespeichert.
Dann schicke ich 5 Byte Daten, das sind Einstellungen, deren Bedeutung sollte euch nicht stören. Ist die Einstellung erfolgt, sendet der Funkempfänger laut Theorie den Wert $06 (ACK), der dann in "store2" gespeichert werden sollte.

Hier der Code:



#pragma code // definiert, dass der Code ausführbare Befehle enthält
void main(void){
InitPeripherals(); // benutzte Ports initialisieren

OpenUSART(USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_LOW, 64);

store = 0;
store2 = 0;
PORTC_DTR = 0;



/*Initialisiertung der Wetterstation(Empfänger)*/

PORTC_RTS = 0; //clear RTS (RC5)
PORTC_DTR = 1; //set DTR (RC4)


while (!DataRdyUSART()); // warten, solange keine Daten ankommen

store = ReadUSART(); // Get the character received from the USART */
while (BusyUSART());



while (TRUE){

// Display a prompt to the USART

putcUSART ((const far rom char *) 0x01 ); // SOH
while (BusyUSART());

putcUSART ((const far rom char *) 0x36 ); // d 6
while (BusyUSART());

putcUSART ((const far rom char *) 0xC9 ); // d 201
while (BusyUSART());

putcUSART ((const far rom char *) 0x10 ); // zeit in min.: 10
while (BusyUSART());

putcUSART ((const far rom char *) 0x04 ); // EOT
while (BusyUSART());



while (!DataRdyUSART()); // warten solange keine Daten ankommen

store2 = ReadUSART(); // Get the character received from the USART
while (BusyUSART());
}


CloseUSART();
}




Problem:
Ich bekomme entweder gar keine Werte oder dann falsche.

Kann mir jemand helfen?
Das wäre einfach genial, denn ich studiere und probiere schon lange habe nicht mehr ewig Zeit. Aber mal eins nach dem andern O:)


Mit freundlichen Grüssen, mi.ja

09.02.2005, 11:15
Was mir auffällt: mit "&" wird UND gemacht

OpenUSART(USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_LOW, 64);

Um die Summe aller Bits zu kriegen, mußt du "|" schreiben (ODER)
?? mfg robert

PicNick
09.02.2005, 11:16
Verflixt, der Gast bin ich mfg

mi.ja
09.02.2005, 12:06
kein problem O:) , danke für deine Antwort

Also das stimmt schon so, das sind ja Konfigurationen. Wenn ich in den Compiler Libraries des C18 nachsehe, sind diese Definitionen immer mit UND verknüpft, siehe Seite 65:
http://www.acfr.usyd.edu.au/teaching/3rd-year/mech3701-Mx3/reference/tools/C18/MPLAB%20C18%20C%20Compiler%20Libraries%20(51297b). pdf

Und wenn das falsch würde der Code gar nicht fertig kompiliert, oder?

Bitte um weitere Hilfe!!

mfg michi

PicNick
09.02.2005, 12:15
Hi, na, flagfrei kompilieren tut er das so oder so, der C weiß ja nicht, was es werden soll.
Ich hab dort reingesehen, du hast recht.
Das ist sehr seltsam, äußerst seltsam.
Kontrollier das mal folgendermaßen.
Irgendwo in der usart.h file müssen diese Werte drin stehen.
Kannst du die mal mit cut & paste da reinstellen, daß wir sie uns anschauen können ?
mfg (gruezi, bonjour salu) robert

mi.ja
09.02.2005, 13:23
du meinst schon "usart.h" oder? hier ist es:



#ifndef __USART_H
#define __USART_H

/* PIC18 USART peripheral libraries. */

/* There are three library modules, corresponding to register names:
* USART1 (TXSTA1, RCSTA1, etc.)
* USART2 (TXSTA2, RCSTA2, etc.)
* USART (TXSTA, RCSTA, etc.)
* Each module is defined only for those devices for which the register
* names are defined.
*/

/* Corresponding to each module, there are several routines:
*
* The 'open' routine takes two parameters:
* - 'config' is the bitwise 'and' of the appropriate configuration
* bit masks (defined below);
* - 'spbrg' is the baud rate.
* The registers associated with the USART module are set according to these
* parameters; then, the transmitter and receiver are enabled.
*
* The 'datardy' routine returns 1 if data has been received, 0 otherwise.
*
* The 'read' routine returns the received byte. It also sets the framing
* and overrun error status bits (FRAME_ERROR & OVERRUN_ERROR) if necessary;
* also, the status receive bit 8 (RX_NINE) is significant if 9-bit mode
* is enabled.
* (See status bit structure definition below).
*
* The 'write' routine accepts the byte to transmit. If 9-bit mode is
* enabled, the status trasmit bit 8 (TX_NINE) is also trasmitted.
*
* The 'gets' routine accepts a buffer and the buffer length in bytes as
* parameters. It fills the buffer with bytes as they are received; it will
* wait for data if necessary in order to fill the entire buffer.
*
* The 'puts' routine accepts a null-terminated byte string. All bytes
* are transmitted, including the null character. It will wait until the
* USART is not busy in order to transmit all the bytes.
*
* The 'putrs' routine is identical to 'puts', except the byte string
* resides in ROM.
*
* The 'close' routine disables the receiver, the transmitter, and the
* interrupts for both.
*
* The 'busy' routine returns 1 if the transmit shift register is not empty;
* otherwise, it returns 0.
*
* For devices with enhanced USART capability, an additional 'baud'
* routine is provided. This routine takes a 'config' parameter, which
* is a bitwise 'and' of the baud configuration bit masks (see below).
* The BAUDCON (a.k.a. BAUDCTL) register is configured appropriately.
*/

/* Change this to near if building small memory model versions of
* the libraries. */
#define MEM_MODEL far

/* storage class of library routine parameters; pre-built with auto;
* do not change unless you rebuild the libraries with the new storage class */
#define PARAM_SCLASS auto

/* Configuration bit masks to be 'anded' together and passed as the 'config'
* parameter to the 'open' routine. */
#define USART_TX_INT_ON 0b11111111 // Transmit interrupt on
#define USART_TX_INT_OFF 0b01111111 // Transmit interrupt off
#define USART_RX_INT_ON 0b11111111 // Receive interrupt on
#define USART_RX_INT_OFF 0b10111111 // Receive interrupt off
#define USART_BRGH_HIGH 0b11111111 // High baud rate
#define USART_BRGH_LOW 0b11101111 // Low baud rate
#define USART_CONT_RX 0b11111111 // Continuous reception
#define USART_SINGLE_RX 0b11110111 // Single reception
#define USART_SYNC_MASTER 0b11111111 // Synchrounous master mode
#define USART_SYNC_SLAVE 0b11111011 // Synchrounous slave mode
#define USART_NINE_BIT 0b11111111 // 9-bit data
#define USART_EIGHT_BIT 0b11111101 // 8-bit data
#define USART_SYNCH_MODE 0b11111111 // Synchronous mode
#define USART_ASYNCH_MODE 0b11111110 // Asynchronous mode

/* These devices have enhanced USARTs. */
#if defined(__18F6585) || defined(__18F6680) || \
defined(__18F8585) || defined(__18F8680) || \
defined(__18F2480) || defined(__18F2580) || \
defined(__18F4480) || defined(__18F4580) || \
defined(__18F2585) || defined(__18F2680) || \
defined(__18F4585) || defined(__18F4680) || \
defined(__18F64J15) || defined(__18F65J10) || defined(__18F65J15) || \
defined(__18F66J10) || defined(__18F66J15) || defined(__18F67J10) || \
defined(__18F84J15) || defined(__18F85J10) || defined(__18F85J15) || \
defined(__18F86J10) || defined(__18F86J15) || defined(__18F87J10) || \
defined(__18F1220) || defined(__18F1320) || \
defined(__18F6525) || defined(__18F6621) || \
defined(__18F8525) || defined(__18F8621) || \
defined(__18F2515) || defined(__18F2525) || \
defined(__18F2610) || defined(__18F2620) || \
defined(__18F4515) || defined(__18F4525) || \
defined(__18F4610) || defined(__18F4620) || \
defined(__18F6310) || defined(__18F6390) || \
defined(__18F6410) || defined(__18F6490) || \
defined(__18F8310) || defined(__18F8390) || \
defined(__18F8410) || defined(__18F8490) || \
defined(__18F2455) || defined(__18F2550) || \
defined(__18F4455) || defined(__18F4550) || \
defined(__18F2510) || defined(__18F2520) || \
defined(__18F4410) || defined(__18F4420) || \
defined(__18F4510) || defined(__18F4520)
/* The baud configuration bit masks to be 'anded' together and passed to
* the 'baud' routine. */
#define BAUD_IDLE_CLK_HIGH 0b11111111 // idle state for clock is a high level
#define BAUD_IDLE_CLK_LOW 0b11101111 // idle state for clock is a low level
#define BAUD_16_BIT_RATE 0b11111111 // 16-bit baud generation rate
#define BAUD_8_BIT_RATE 0b11110111 // 8-bit baud generation rate
#define BAUD_WAKEUP_ON 0b11111111 // RX pin monitored
#define BAUD_WAKEUP_OFF 0b11111101 // RX pin not monitored
#define BAUD_AUTO_ON 0b11111111 // auto baud rate measurement enabled
#define BAUD_AUTO_OFF 0b11111110 // auto baud rate measurement disabled
#endif


/* Only these devices have two USART modules: USART1 & USART2. */
#if defined(__18F6520) || defined(__18F6620) || defined(__18F6720) || \
defined(__18F8520) || defined(__18F8620) || defined(__18F8720) || \
defined(__18F64J15) || defined(__18F65J10) || defined(__18F65J15) || \
defined(__18F66J10) || defined(__18F66J15) || defined(__18F67J10) || \
defined(__18F84J15) || defined(__18F85J10) || defined(__18F85J15) || \
defined(__18F86J10) || defined(__18F86J15) || defined(__18F87J10) || \
defined(__18F6627) || defined(__18F6722) || \
defined(__18F8627) || defined(__18F8722) || \
defined(__18F6525) || defined(__18F6621) || \
defined(__18F8525) || defined(__18F8621) || \
defined(__18F6310) || defined(__18F6390) || \
defined(__18F6410) || defined(__18F6490) || \
defined(__18F8310) || defined(__18F8390) || \
defined(__18F8410) || defined(__18F8490)


/* ***** USART1 ***** */

/* status bits */
union USART1
{
unsigned char val;
struct
{
unsigned RX_NINE:1; // Receive Bit 8 if 9-bit mode is enabled
unsigned TX_NINE:1; // Transmit Bit 8 if 9-bit mode is enabled
unsigned FRAME_ERROR:1; // Framing Error for USART
unsigned OVERRUN_ERROR:1; // Overrun Error for USART
unsigned fill:4;
};
};


void Open1USART (PARAM_SCLASS unsigned char config, PARAM_SCLASS char spbrg);
#if defined(__18F6525) || defined(__18F6621) || \
defined(__18F8525) || defined(__18F8621) || \
defined(__18F64J15) || defined(__18F65J10) || defined(__18F65J15) || \
defined(__18F66J10) || defined(__18F66J15) || defined(__18F67J10) || \
defined(__18F84J15) || defined(__18F85J10) || defined(__18F85J15) || \
defined(__18F86J10) || defined(__18F86J15) || defined(__18F87J10) || \
defined(__18F6627) || defined(__18F6722) || \
defined(__18F8627) || defined(__18F8722)

#define DataRdy1USART( ) (PIR1bits.RCIF)
#else
#define DataRdy1USART( ) (PIR1bits.RC1IF)
#endif
char Read1USART (void);
void Write1USART (PARAM_SCLASS char data);
void gets1USART (PARAM_SCLASS char *buffer, PARAM_SCLASS unsigned char len);
void puts1USART (PARAM_SCLASS char *data);
void putrs1USART (PARAM_SCLASS const MEM_MODEL rom char *data);
#define getc1USART Read1USART
#define putc1USART Write1USART
#define Close1USART( ) RCSTA1&=0b01001111,TXSTA1bits.TXEN=0,PIE1&=0b11001111
#define Busy1USART( ) (!TXSTA1bits.TRMT)
#if defined(__18F6525) || defined(__18F6621) || \
defined(__18F8525) || defined(__18F8621) || \
defined(__18F6310) || defined(__18F6390) || \
defined(__18F6410) || defined(__18F6490) || \
defined(__18F8310) || defined(__18F8390) || \
defined(__18F8410) || defined(__18F8490) || \
defined(__18F64J15) || defined(__18F65J10) || defined(__18F65J15) || \
defined(__18F66J10) || defined(__18F66J15) || defined(__18F67J10) || \
defined(__18F84J15) || defined(__18F85J10) || defined(__18F85J15) || \
defined(__18F86J10) || defined(__18F86J15) || defined(__18F87J10) || \
defined(__18F6627) || defined(__18F6722) || \
defined(__18F8627) || defined(__18F8722)

void baud1USART (PARAM_SCLASS unsigned char baudconfig);
#endif


/* ***** USART2 ***** */

/* status bits */
union USART2
{
unsigned char val;
struct
{
unsigned RX_NINE:1; // Receive Bit 8 if 9-bit mode is enabled
unsigned TX_NINE:1; // Transmit Bit 8 if 9-bit mode is enabled
unsigned FRAME_ERROR:1; // Framing Error for USART
unsigned OVERRUN_ERROR:1; // Overrun Error for USART
unsigned fill:4;
};
};

void Open2USART (PARAM_SCLASS unsigned char config, PARAM_SCLASS char spbrg);
#define DataRdy2USART( ) (PIR3bits.RC2IF)
char Read2USART (void);
void Write2USART (PARAM_SCLASS char data);
void gets2USART (PARAM_SCLASS char *buffer, PARAM_SCLASS unsigned char len);
void puts2USART (PARAM_SCLASS char *data);
void putrs2USART (PARAM_SCLASS const MEM_MODEL rom char *data);
#define getc2USART Read2USART
#define putc2USART Write2USART
#define Close2USART( ) RCSTA2&=0b01001111,TXSTA2bits.TXEN=0,PIE3&=0b11001111
#define Busy2USART( ) (!TXSTA2bits.TRMT)
#if defined(__18F6525) || defined(__18F6621) || \
defined(__18F8525) || defined(__18F8621) || \
defined(__18F64J15) || defined(__18F65J10) || defined(__18F65J15) || \
defined(__18F66J10) || defined(__18F66J15) || defined(__18F67J10) || \
defined(__18F84J15) || defined(__18F85J10) || defined(__18F85J15) || \
defined(__18F86J10) || defined(__18F86J15) || defined(__18F87J10) || \
defined(__18F6627) || defined(__18F6722) || \
defined(__18F8627) || defined(__18F8722)
void baud2USART (PARAM_SCLASS unsigned char baudconfig);
#endif

#else


/* ***** USART (TXSTA, RCSTA, etc.) ***** */

/* status bits */
union USART
{
unsigned char val;
struct
{
unsigned RX_NINE:1; // Receive Bit 8 if 9-bit mode is enabled
unsigned TX_NINE:1; // Transmit Bit 8 if 9-bit mode is enabled
unsigned FRAME_ERROR:1; // Framing Error for USART
unsigned OVERRUN_ERROR:1; // Overrun Error for USART
unsigned fill:4;
};
};

void OpenUSART (PARAM_SCLASS unsigned char config, PARAM_SCLASS unsigned spbrg);
#define DataRdyUSART( ) (PIR1bits.RCIF)
char ReadUSART (void);
void WriteUSART (PARAM_SCLASS char data);
void getsUSART (PARAM_SCLASS char *buffer, PARAM_SCLASS unsigned char len);
void putsUSART (PARAM_SCLASS char *data);
void putrsUSART (PARAM_SCLASS const MEM_MODEL rom char *data);
#define getcUSART ReadUSART
#define putcUSART WriteUSART
#define CloseUSART( ) RCSTA&=0b01001111,TXSTAbits.TXEN=0,PIE1&=0b11001111
#define BusyUSART( ) (!TXSTAbits.TRMT)
#if defined(__18F6585) || defined(__18F6680) || \
defined(__18F8585) || defined(__18F8680) || \
defined(__18F2480) || defined(__18F2580) || \
defined(__18F4480) || defined(__18F4580) || \
defined(__18F2585) || defined(__18F2680) || \
defined(__18F4585) || defined(__18F4680) || \
defined(__18F1220) || defined(__18F1320) || \
defined(__18F2515) || defined(__18F2525) || \
defined(__18F2610) || defined(__18F2620) || \
defined(__18F4515) || defined(__18F4525) || \
defined(__18F4610) || defined(__18F4620) || \
defined(__18F2455) || defined(__18F2550) || \
defined(__18F4455) || defined(__18F4550) || \
defined(__18F2510) || defined(__18F2520) || \
defined(__18F4510) || defined(__18F4520)
void baudUSART (PARAM_SCLASS unsigned char baudconfig);
#endif

#endif

#endif





is a bissle lang 8-[

PicNick
09.02.2005, 13:36
Aha, danke, wieder was gelernt. Die Burschen machen das genau verkehrt.
Gut. Das "&" ist richtig, daran liegt's nicht. Ich seh auch keinen Programmtechnischen Fehler.

Du hast gesagt "falsche Daten". Welche (hilft manchmal)

Vielleicht versteht dich der Kollege einfach nicht ?

Ohne Detailkenntnis, schickst du doch eine recht seltsame Mischung von Ascii u. Binär

0x36 ); // d 6 ASCII 6
0xC9 ); // d 201 Binär ??
0x10 ); // zeit in min.: 10 (0x10 ist eigenlich 16 ??)

Bist du da sicher ? Die meisten Messgeräte vermeiden Binäres, wenn sie gleichzeitig Kontrollzeichen ( < 0x20) verwenden.
mfg robert

mi.ja
09.02.2005, 14:01
Hi
Ich bin eben selber nicht sicher, wie es GENAU sein sollte. Ich habe nur eine Ungenaue Doku dieses Empfängers und einige zusammengesammelte Infos aus dem Internet.

Also dieser Receiver hat ja einen integierten speicher, auf dem diese Daten sind. In meinem Code-Beispiel oben mache ich eine Einstellung, ich setze die die Intervallzeit, d.h. alle x min fragt der Empfänger die Daten der Sensoren ab (Temparatur, Feuchtigkeit u.s.w.)

Ich habe folgende Infos
----------------------------

Mit diesen Daten stellt man die Intervalltzeit ein:

<SOH> ¦ '6' ¦ (Zeit in Minuten) ¦ (-Summe) ¦ <EOT>

¦ ist nur zur Darstellung und unterteilt die Bytes, im gesamten sind es 5

Beschreibung:

- Die '6' ist quasi der Befehl, die Intervallzeit einzustellen.

- Zeit in Minuten, von 1-60

- (-Summe) wird wie folgt berechnet:
'-Summe' = 255 - 'command Byte'
Dabei ist 'command Byte' der Befehl, in unserem Beispiel 6.
Nun nimmt man den ASCII-Code von '6' (=54d):
'-Summe' = 255 - 54 = 201


--> Der Empfänger sollte dann als Antwort ein ACK senden.


Die "falschen Daten", die ich bekomme, sind jedes mal anders.
Manchmal EOh, 80h, F0h, FFh...immer anders! (komisch..!)




Vielleicht versteht dich der Kollege einfach nicht ?


Tja ich glaub auch langsam... Meine Infos, d.h. die Dokumentation dees Empfängers sind einfach sehr ugenau, ich habe schon stunden, ja Tage, im internet gesuch bis ich so viel Infos hatte wie ich jetzt habe, aber scheinbar doch noch nicht genug.




Ohne Detailkenntnis, schickst du doch eine recht seltsame Mischung von Ascii u. Binär

0x36 ); // d 6 ASCII 6
0xC9 ); // d 201 Binär ??
0x10 ); // zeit in min.: 10 (0x10 ist eigenlich 16 ??)


Oben habe ich die infos, die ich habe über das Protokoll der zu sendenden Daten, mehr weiss ich nicht, sicher bin ich auch nicht!

Merci & Gruss Michi

PicNick
09.02.2005, 14:29
Tscha,
1 du hast die falsche Reihenfolge, du schickst ja "Cmd|Summe|Min"
2 Steht in der Info daß es 5 Byte sein sollen, oder nimmst du das an ?
3 Du mußt, glaub ich, hacken
Wenn ein "|" als Trennzeichen angeführt ist, wieso dann noch Klammer, Hochkomma und "-" ? --> verdächtig
Wenn nicht definitiv drin steht, daß es 5 Byte sein sollen (WENN)
also ich würde mich blöd stellen und alles in ASCII schicken, so wie's da steht, also
<SOH>'6'(10)(-201)<EOT>
Sorry, hab' keinen Schimmer

mi.ja
09.02.2005, 14:40
Tscha,
1 du hast die falsche Reihenfolge, du schickst ja "Cmd|Summe|Min"
2 Steht in der Info daß es 5 Byte sein sollen, oder nimmst du das an ?
3 Du musst, glaub ich, hacken
Wenn ein "|" als Trennzeichen angeführt ist, wieso dann noch Klammer, Hochkomma und "-" ? --> verdächtig
Wenn nicht definitiv drin steht, daß es 5 Byte sein sollen (WENN)
also ich würde mich blöd stellen und alles in ASCII schicken, so wie's da steht, also
<SOH>'6'(10)(-201)<EOT>
Sorry, hab' keinen Schimmer

hallo
Ja das habe ich verkehrt, stimmt!! hab ich übersehen und voller Hoffnung schnell geändert und probiert - ohne erfolg: es funtzt nicht...

ich glaub da kam nicht alles so rüber wie ich es wollte: die ¦ sind nur zur Darstellung, das man sieht, dass dort ein neues Byte kommt. Das schickt man nicht! Und das mit den 5Bytes hanbe ich nicht erfunden, das ist so.

tja, wie kann ich ASCII eingeben? ich habs probiert aber es gibt immer fehler.

und: ich bin kein Hacker ;-), was meinst du genau mit hacken?

thx und gruss michi

PicNick
09.02.2005, 14:53
Hacken heißt, einfach rumprobieren, ob irgendeine Reaktion erfolgt.
Wenn dort fix steht, 5 Bytes, dann soll es gelten.

Die Return werte 0xE0, 0x80 etc. könnten hinweisen, daß das Comm-Format nicht stimmt, oder die Baudrate
Du schickst 1 start / 8 Bits / No parity / 1 Stop NO Flowcontrol
Da kann was klemmen

UND noch eine ev. Gemeinheit: Vielleicht will der Kerl Flowcontrol mit RTS/DTR haben ? ( z.B Modems lieben das)

EDIT
Ein Versuch: mach zwischen dem senden zweier Zeichen eine kleine Pause, manchmal hilft das. (ein paar mS)

mi.ja
09.02.2005, 15:07
ok, ich hacke demfall schon die ganze zeit...

Was ist das Comm-Format?

Die Baudrate sollte stimmen, die Parameter des Empfängers sind:
9600 Baud, 8 Datenbits, gerade Parität (even), 2 Stoppbits!!
Da stimmt was nicht mit meinem Code überein...Aber wie ändere ich z.B., dass die parity even ist?
(Weiss nicht wie, habe keine Erfahrung mit C auf Pic, nur auf PC-ebene. Oder dann Assembler, aber ich sollte es in C schreiben)

Noch eine Info: Um die Verbindung herzustellen, muss ich folgendes tun, bevor ich Daten abfrage oder Einstllungen mache:

RTS = Low setzen
DTR = High setzen

Nach ca. 30ms, wenn der Oszillator des Empfängers stabil ist, wird ein ETX geschickt. Mein Code macht das so.

Die Verbindung steht, bis DTR = Low oder 0.5 sec. nichts geschickt wird.

Thx. for your help, gruss Michi

PicNick
09.02.2005, 15:41
Oh je, Oh je, mir schwant Unheil.
die Parity kannst du mit dem 9-Bit modus noch reinquetschen, mußt aber selber rechnen, fürcht ich. (das is aber ein Klacks)
ABER
2 Stop-Bits wird der Pic, fürcht ich, gar nicht draufhaben, da müßtest du ev. im Datasheet nachschauen.
Was du wahrscheinlich machen mußt, ist "software UART". --> d.i. selbst gestrickt, zumindest beim Senden.
Ohnmächtg geworden ?
Du mußt im Bitraster von 9600 Baud deine Bits einzeln raus-schicken
(Rechnerei)
Ein Einser = Startbit
deine 8 -Datenbits das paritybit bei jedem einser toggeln
das Parity schicken
und noch zwei 1-er = Stoppbits.

*seufz oh graus*
am besten Testen mit einem Terminal (Hyperterm oder so)

Bevor du aber zu schreiben beginnst, tät ich mit dem genannten Test-Terminal erst mal den Empfänger direkt ansprechen. die Binären codes halt zuerst zusammensuchen (ALt / Ziffernblock den asciicode/ alt wieder auslassen)
sorry

BlackBox
10.02.2005, 09:31
Zwei Stopbits stellen beim Empfang im PIC kein Problem dar. Beim Senden kann man schon die UART des PIC verwenden, muss aber vor dem Neuladen des TXREG eine Bitperiode abwarten --> ergibt 2 Stoppbits.

Also warten, bis TRMT=1, dann Pause, dann erst nächstes Byte senden. Nicht TXREG neu laden, wenn TXIF=1 (Sende-Interupt).

mi.ja
10.02.2005, 09:51
Hllo und merci für den post

Nun, ich hoffe ich habe es richtig verstanden, aber ein Codebeispiel wäre hilfreicht.

Und: Um die Verbindung herzustellen, muss ich folgendes tun, bevor ich Daten abfrage oder Einstllungen mache:

RTS = Low setzen
DTR = High setzen

Nach ca. 30ms, wenn der Oszillator des Empfängers stabil ist, wird ein ETX geschickt. Aber ein ETX empange ich gar nicht.

mfg michi

BlackBox
10.02.2005, 10:15
Was empfängst Du dann?

Hier ist auch ein fehler im Quellcode:
while (!DataRdyUSART()); // warten, solange keine Daten ankommen

store = ReadUSART(); // Get the character received from the USART */
while (BusyUSART());



Du liest das empfangen Byte aus und wartest dann darauf, dass der Sendepuffer lehr ist. Gut, nicht unbedingt ein Fehler, wenn die Funktion nur das Flag überprüft aber unnötig.

Die Pause zur verlängerung des Stoppbits müsstest Du wie PicNick schon geschrieben hat immer nach der funktion while(BussyUSART()); ausführen. Ich habe nur keine Ahnung, ob die Funktion TXIF oder TRMT abfragt. Das müsste aber aus der Doku ersichtlich sein. Ich verwende einen anderen Compiler.

mi.ja
10.02.2005, 10:29
Ich empfange nichts oder irgendetwas, z.B. 0xE0, 0x80, 0xF0, 0xFF...
(siehe oben).

Das mit der Pause zur verlängerung des Stoppbits muss ich erst noch im Datenbuch nachsehen...

Ich lerne Elektroniker und kenne mich mit C auf uP-Basis nicht aus, ich habe nur Grundlagen von C auf PC-Ebene und ich kann Assembler. Aber ich sollte es mit C machen.

Gruss Michi

BlackBox
10.02.2005, 12:44
Da ja nur ein Byte gesendet wird (nehme ich jetzt mal an) passt da irgendwas nicht. Entweder die Baudrate stimmt nicht oder es liegt irgendwo ein Hardwarefehler vor. Letzeres ist wahrscheinlicher, da bei falschen Einstellungen immer das gleiche falsche zeichen empfangen werden würde.

Ich lerne Elektroniker und kenne mich mit C auf uP-Basis nicht aus, ich habe nur Grundlagen von C auf PC-Ebene und ich kann Assembler. Aber ich sollte es mit C machen.

Macht doch nichts. Jeder fängt mal an.

MfG

mi.ja
10.02.2005, 12:46
Ich lerne Elektroniker und kenne mich mit C auf uP-Basis nicht aus, ich habe nur Grundlagen von C auf PC-Ebene und ich kann Assembler. Aber ich sollte es mit C machen.

Macht doch nichts. Jeder fängt mal an.

MfG

Ja, jeder fängt mal an, wollte nur sagen, dass von mit nicht allzu viel zu erwarten ist :wink:

mfg

PicNick
10.02.2005, 13:06
Hi, vor lauter Stopp-Bits vergessen wir ganz auf das Parity-Bit, der Kollege legt eventuell Wert darauf.

BlackBox
10.02.2005, 13:24
Ich dachte das war soweit geklärt.
Ist aber so oder so das 9. Bit also müsste trotzdem immer das falsche Bitmuster empfangen werden oder hab ich da irgendwo nen Denkfehler?

PicNick
10.02.2005, 13:39
Beim Empfang isses eh mehr oder weniger wurst.
Aber beim Senden muß er sich drum kümmern und jeweils rechnen und setzen.
Tut der Kollege das schon ?
Wie auch immer, nochmal: Ich tät das ganze erst mit einem richtigen Terminal probieren, meinethalben Hyperterm, einmal als Sender, einmal als Empfänger, dann kann man einiges abhaken.
mfg

BlackBox
10.02.2005, 13:52
Jo, so würde ich es auch machen.

mi.ja
10.02.2005, 13:53
Ich habe hier im Geschäft lediglich das HyperTerminal von Windows, das schon dabei ist (Windows 2000 Prof.)

Du meinst ein anderes oder?

BlackBox
10.02.2005, 14:03
HyperTerm ist ein echt besch..nes Programm für so etwas. Google mal nach MTTTY. Ist Shareware und für so etwas recht brauchbar. Es gibt aber auch noch jede Menge anderer Terminalprogramme, die auch Hex-Anzeige etc. beherschen. Da kann ich dir aber nichts empfehlen.

PicNick
10.02.2005, 14:12
Halt, Stop, Retour.
Ich bin vom Hyperterminal auch nicht begeistert, aber es sollte alles tun, was du konkret brauchst.
Aber wenn die der Google was besseres bietet, soll es sein.
mfg robert

mi.ja
11.02.2005, 08:46
Hallo zusammen

So, die Situation hat sich ein bisschen geändert. Ich habe auf microchip.com ein .pdf und Besispielprogramme gefunden. So wie es aussieht, ist es tatsächlich gar nicht möglich, diese Kommunikation jemals herzustellen.

Die Daten vom Empfänger kommen so:
1Startbit, 8 Datenbits, 1 Paritätsbit (even), 2 Stoppbits.

Beim PIC kann man standartmässig dieses Muster Empfangen:
1Startbit, 8Datenbits, 1Stopbit

Nun gibt es ein 9. Bit, das für folgendes verwendet werden kann:
> 2. Stopbit
> Parity-Bit
> 9. Datenbit

Aber um die Daten von der Wetterstation korrekt einzulesen, brauche ich quasi ein 9. UND ein 10. Bit, welches ich aber nicht habe! Denn das 9. Bit ist ja ENTWEDER das 2. Stopbit ODER das Parity-Bit.

Nachzulesen auf S.9/10:
http://ww1.microchip.com/downloads/en/AppNotes/00774a.pdf

Falls nötig, hier sind die Beispielcodes:
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en012073


Und alles "von Hand" machen mit einer geschwindigkeit von 9600 Baud ist schwierig (und ich habe nicht mehr viel Zeit).

Was sagt ihr dazu bzw. gibt es einen Ausweg?

Gruss Michi

BlackBox
11.02.2005, 08:59
Hast Du dir meinen obigen Beitrag durchgelesen?

Beim Empfang ist es wie von mir und mehrfach von Robert erwähnt egal ob 1,2,3,4,5,6 oder 100000000 Stoppbits kommen, so lange deine Software den Empfng nicht durch einen Timeout abbricht.
Beim Senden: PAUSE nach einem Byte=zusätzliche(s) Stoppbit(s).

Schau dir mal an, wie das Signal genau aussieht, dann sollte das klar werden.

PicNick
11.02.2005, 09:02
Hi, na so schlimm isses nicht.
9 Bit (8 + Parity) kann der Pic senden und empfangen.
das Problem ist das zweite Stoppbit.
Gute Info gibt's da
http://www.sprut.de/electronic/pic/grund/rs232.htm
--> RS232 Software simulation.
damit müßtest du zurecht kommen

mi.ja
11.02.2005, 09:21
Hast Du dir meinen obigen Beitrag durchgelesen?

Beim Empfang ist es wie von mir und mehrfach von Robert erwähnt egal ob 1,2,3,4,5,6 oder 100000000 Stoppbits kommen, so lange deine Software den Empfng nicht durch einen Timeout abbricht.
Beim Senden: PAUSE nach einem Byte=zusätzliche(s) Stoppbit(s).

Schau dir mal an, wie das Signal genau aussieht, dann sollte das klar werden.

Klar habe ich alles gelesen, ich frage ja nach hilfe. ich habe auch einen KO angeschlossen, aber ich Empfange ja gar nichts, und die -/+10V an RTS/DTR stimmen

mi.ja
11.02.2005, 09:22
Hi, na so schlimm isses nicht.
9 Bit (8 + Parity) kann der Pic senden und empfangen.
das Problem ist das zweite Stoppbit.
Gute Info gibt's da
http://www.sprut.de/electronic/pic/grund/rs232.htm
--> RS232 Software simulation.
damit müßtest du zurecht kommen

huch, doch noch hoffnung. wo bekomm ich diese Software? seh die nicht auf spruts'page...

BlackBox
11.02.2005, 09:25
Was isn ein KO? Kabel Oszi?

Wenn Du nichts empfängst, dann ist entweder doch irgendwo was an der Verbindung faul oder der Empfänger funktioniert nicht.

Was misst Du denn für einen Pegel beim PIC an RXD vor und nach dem Max?

mi.ja
11.02.2005, 09:40
Was isn ein KO? Kabel Oszi?

Wenn Du nichts empfängst, dann ist entweder doch irgendwo was an der Verbindung faul oder der Empfänger funktioniert nicht.

Was misst Du denn für einen Pegel beim PIC an RXD vor und nach dem Max?

KO = Kathodenstrahloszillograph/-skop = Oszi

Was faul ist weiss ich leider nicht genau. Aber der Empfänger funzt mit der dazugehürigen Software am PC, die es zu eretzen gilt, dass nicht immer ein PC laufen muss. Und die Hardware mit MAX232 ist schon verbessert, hatte am Anfang auch Fehler, aber nun ist sie von hinten bis vorne mehrmals durchgecheckt und verbessert.

Wie gesagt, ich Empfange nichts. Wenn mein code läuft, dann ist RxD = 0V und TxD = 5V.

BlackBox
11.02.2005, 10:33
Wenn mein code läuft, dann ist RxD = 0V und TxD = 5V.

Da hammer doch schon das Problem.

RXD=0 --> Startbit oder Daten --> Puffer läuft über

RXD am PIC muss im Ruhezustand auf +5V (=Stoppbit) liegen! Vor dem Max (also TXD von dem Empfänger) muss auf -10V liegen.

Wenn der Empfänger seinen RS232-Tranciver erst einschaltet, wenn die Statussignale anliegen (Kontrolle mit Oszi), dann darfst Du den Empfang im PIC auch erst aktivieren, wenn die Signale gesetzt sind. Sollte dem nicht der Fall sein, dann ist wie gesagt irgendwo ein Schaltungsfehler.