PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] PIC UASRT Programmierung klappt nur mit fehlerhafter ser. Ausgabe



oderlachs
26.03.2017, 18:42
Hallo , bestimmt stecke ich jetzt in der nächsten Anfänger Fussangel drinnen.
Ich habe mich mit Hilfe des Datenblattes(PIC16F877A) an die Ser. Kommunikation ran gewagt. Aber so richtig will es nicht klappen. Ich muss gestehen, ich habe ein paar Schwierigkeiten das Datenblatt , besonders die Register zu verstehen. Meines Erachtens ist das beim Atmega und Co. besser gehalten und verständlicher.
So recht und schlecht kommen die gesendeten Zeichen(Kleinbuchstaben) zum PC-Terminal (Putty) zurück...mal ok, mal als Großbuchstabe..auch mal als andere Zeichen wie eingegeben. Auch manchmal wird nach ein paar Zeichen die Ausgabe einfach inaktiv.
Ich habe mir also anhand des Datenblattes und etwas im Inet geborgtem Code folgendes Programm erstellt was eigentlich nur ein Eingabe-Echo zurücksendet:


/*
* File: Serial_F877.c
* Author: gerhard
*
* Created on 26. März 2017, 12:08
*/
// CONFIG
#pragma config FOSC = XT // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#define _XTAL_FREQ 4000000 //EasyPIC-40 FQ= 4.0MHz
#include <xc.h>
//#include <stdint.h>
char Empf;
/* ================================================== ======================== */
/* */
/* UART Einstellen */
/* */
/* */
/* ================================================== ======================== */
void UART_Init(void)
{
SPBRG = 6; // 9600 Bd XC0 4.000000HZ lt. Datenblatt
SYNC = 0; // Setze Asynchron Modus
TX9 = 0; // 8-Bitmodus TX
RX9 = 0; // 8-Bitmodus RX
SPEN = 1; // Serial Port ein
TRISC7 = 1; // RX Pin INPUT
TRISC6 = 0; // TX Pin OUTPUT
CREN = 1; // RX ein
TXEN = 1; // TX ein
}

/* ================================================== ======================== */
/* */
/* Sende ein Byte */
/* */
/* ================================================== ======================== */

void UART_Write(char data)
{
while(!TRMT); // Statusbit lesen ob frei zum Senden
TXREG = data;
}

/* ================================================== ======================== */
/* */
/* Empfange ein Byte */
/* */
/* ================================================== ======================== */
char UART_Read()
{
while(!RCIF); //Empfangsbereit ja/nein
return RCREG;
}
/* ================================================== ======================== */
/* */
/* Hauptroutine */
/* */
/* ================================================== ======================== */

void main(void)
{

UART_Init();

do // Endlosschleife
{
if(RCIF) // Empfangsbereit RCIF =1
{
Empf = UART_Read();
__delay_ms(50); // kleine Pause
UART_Write(Empf);
__delay_ms(50); // kleine Pause
}
}while(1);


}




Ich denke bestimmt das ich da als Anfänger was entscheidend falsch gemacht habe, aber ich selber finde es nicht herraus :(

Es kann sein das ich eine Registereinstellung übersehen habe, weil ich beim Datenblatt nicht so recht durchsehe, habe aber den Abschnitt 10. USART
hin und zurück "gelesen", was ich so verstehe davon...;)

Vielleicht hat ja wer eine helfende Idee...??

Gruss und danke

Gerhard

witkatz
26.03.2017, 19:29
Hallo Gerhard,

ich vermute, dass es an der ungenauen Baudrate liegt. Mit BRGH = 0 (default) und SPBRG = 6 wird die Baudrate 9600 bei FOSC=4MHz mit einem Fehler von 7% generiert. Laut Tabelle 10-3 (http://ww1.microchip.com/downloads/en/DeviceDoc/39582C.pdf#I9.1.1027103) wird mit diesen Einstellungen mit 8929 BAUD gesendet, wahrscheinlich ist die Abweichung zu groß für eine fehlerfreie Übertragung. Du könntest das Flag BRGH setzen und mit SPBRG = 25 senden, damit sollte laut Tabelle 10-4 (http://ww1.microchip.com/downloads/en/DeviceDoc/39582C.pdf#I9.1.1027561) die Baudrate 9615, bzw. der Fehler nur noch 0.16% betragen.

Gruß
witkatz

oderlachs
26.03.2017, 20:04
Hallo Witkatz !

Danke , das war eine Fehlerursache, wollte morgen sowieso einen Baudraten freundlicheren Qu aufstecken.
Aber ein Fehler bleibt das nach eine nicht feststehenden Anzahl von gesendeten Bytes , das Senden oder eventuell auch das Empfangen aufhört zu funktionieren.
Denke mal das da ein Zeichenspeicher voll ist und nicht gelöscht wird. Wie gesagt , es ist mein erster Versuch mit einem PIC eine ser. Kommunikation aufzubauen.
Beim AVR klappt es ja immer, also liegt der Grund bestimmt noch in meiner Register-Unkenntnis.

Jetzt ist aber erst mal Filmabend(DVD) für mich , sonst raucht mir wirklich noch der Kopf ab... ;)

Gruss und Danke

Gerhard

oderlachs
27.03.2017, 19:28
Nachtrag :
Ich habe mich da wohl in den Registerwerten etwas vertan, beim lesen des Datenblattes. Habe nun vom ähnlichem Boardhersteller einUSART Demo probiert und es geht.
Musste es nur ein wenig an den XC8 Compiler anpassen.... dann habe ich ein zwei Code-Passagen in meinen Code übernommen und alles OK. Hatte vorher noch mit einem Baudraten XT: 3.686400 getestet, aber der brachte es auch nicht.
Nun get es mit glatt 4MHz und auch mit dem 3.686400..

Also der Fehler war meine eigenen Anfängerblödheit... ;)

Danke nochmals für alle Mithilfe

Gerhard

RoboHolIC
27.03.2017, 19:51
:-#:-#:-#:-#:-#:-#:-#:-#:-#:-#:-#