Forum: Mikrocontroller und Digitale Elektronik PIC18f46j50 USART will nicht wie Ich


von Andreas B. (hokage)


Lesenswert?

Hallo zusammen nach langem suchen lesen und noch mehr versuchen muss ich 
doch um hilfe bitten da ich einfach nicht vorwärts komme. Habe im Rahmen 
meiner Ausbildung ein Projekt bei dem ich über RS232 Daten an meinen PIC 
18f46j50 schicke die dann an i2c oder spi Bautsteine gesendet werden.
Bin Blutiger Anfänger hab  nur schon ne Menge gelesen und versuche mich 
zu beginn einfach mal damit dauerhaft etwas über die Usart Schnittstelle 
zu senden. Leider kommt nur mist an.

Meine Hardware ist oben genannten PIC und das sind meine Testboards:

"PICDEM HPC Explorerboard" mit dem "PIC18F46J50 FS USB Demo Board" 
Aufsteckboard.

Quarztakt sind 12MHz Terminal am PC auf 1200Baud eingestellt

hier mal mein Quellcode:

#include <p18f46j50.h>
#include <usart.h>
#include <delays.h>

#pragma code

void main()
{

Open1USART (USART_TX_INT_OFF &
            USART_RX_INT_OFF &
            USART_BRGH_LOW  &
      USART_CONT_RX &
            USART_EIGHT_BIT  &
            USART_ASYNCH_MODE, 156);

baud1USART( BAUD_IDLE_RX_PIN_STATE_HIGH & BAUD_8_BIT_RATE & 
BAUD_WAKEUP_OFF & BAUD_AUTO_OFF);


while(1)
{

while(Busy1USART());
{

putrs1USART ((const far rom char*)"a");
Delay100TCYx(100);
}
}



}

sollte doch eigentlich recht simpel sein es kommen aber nur Hieroglyphen 
an.

von Michael H. (morph1)


Lesenswert?

auch nicht den fallstrick verschlafen, dass beim PIC18 der CYCLE-Takt 
nur 1/4 vom Quarztakt ist?

beliebte falle :)

ich bin jetzt zu faul das nachzurechnen, aber ich vermute es mal

von Andreas B. (hokage)


Lesenswert?

doch bin ich:-) dann wäre der Dezimalwert den ich übergebe nach meiner 
Rechnung 39, das ändert zwar die Hieroglyphen ist bringt aber trotzdem 
nicht das gewünschte Ergebnis. Danke schon mal für die schnelle Antwort

von Michael H. (morph1)


Lesenswert?

dann glaube ich mich noch zu erinnern, dass beim c18 die putrs sowieso 
nur auf strings im rom angewendet werden kann.

somit fällt alles vorm "a" weg.

probier das mal :)

von Andreas B. (hokage)


Lesenswert?

bringt leider auch nichts, so wie du meinst hatte ich es bis vorher 
auch, doch dann von nem Bekannten den Tipp bekommen das es so sein 
müsste, von daher hab ich es dann mit rein genommen. Leider 
funktionieren beide Varianten nicht.

Irgendwie werd ich das Gefühl nicht los das was mit der Baudrate nicht 
stimmt....aber naja was sagt schon das Gefühl von einem Anfänger:-)

von Michael H. (morph1)


Lesenswert?

also mich wundert mehr dein krummer takt, die 39 dezimal hab ich gerade 
nochmal nachgerechnet, die passen für 3MHz Cycle

aber wieso verbaut jemand einen 12Mhz Quarz?

von Andreas B. (hokage)


Lesenswert?

gute Frage, das Board wird so halt fertig angeboten, das PICDEM Board 
gab es nicht mit genau diesem PIC also gibt es diese Huckepack Lösung. 
Sollte doch aber trotzdem funktionieren wenn man den richtigen Wert 
übergibt. Sonst scheint der Code zu stimmen?? ode noch irgendwelche 
Ideen was ich noch versuchen könnte??? Danke schon mal

von morph1 (Gast)


Lesenswert?

Also auf Grund vieler Probleme mit den Microchip - libs mach ich das 
eigentlich immer zu Fuss.

Dummerweise sind meine Libs alle Interrupt-driven, aber ich versuch das 
mal auf Blocking umzuschreiben:
1
void UART1Init(void)
2
{
3
  BAUDCON1 = 0b00001000;    // BRG16 = 1, TX idle low, RX active high
4
  
5
  SPBRGH1 = 0x00;
6
  SPBRG1 = 0xCE;
7
    
8
//        76543210
9
  TXSTA1 = 0b00000100;
10
  RCSTA1 = 0b00010000;
11
  RCSTA1bits.SPEN = 1;
12
  Nop();
13
  Nop();        // pic18 errata workaround
14
15
  PIE1bits.RC1IE = 1;    // Enable receive interrupt
16
  PIE1bits.TX1IE = 1;    // Enable transmit interrupt
17
18
//  IPR1bits.RC1IP = 1;    // high priority int
19
//  IPR1bits.TX1IP = 1;    // high priority int
20
}

senden müsste so ausehen:
1
void UART1send(unsigned char data)
2
{
3
   PIR1bits.TX1IF = 0;
4
   TXREG1 = data;
5
   TXSTA1bits.TXEN = 1;
6
   while(!PIR1bits.TX1IF);
7
}
ist aber ungetestet und jetzt schnell aus dem kopf geschrieben :)

aja und sieh in den configuration-bits nach ob PLL (HS with PLL Module) 
an ist! ich weiß wozu der 12Mhz quarz ist, den braucht dieser PIC um 
seine 48Mhz für USB zu basteln.
Also entweder ausschalten oder mit 48Mhz rechnen.

von morph1 (Gast)


Lesenswert?

ach bitte noch die "enable Interrupt" zeilen auskommentieren :)

von Andreas B. (hokage)


Lesenswert?

ich tue mich mit dem code von dir ein bisschen schwer, du meinst wenn 
ich die Interrupt Enable zeilen auskommentier dann sollte ich das so 
übernhemen können oder wie?? was meinst du mit ausschalten oder mit 
48Mhz rechnen, dachte über den Teiler muss eh nur mit einem viertel, 
sprich 3Mhz rechnen.

hab auf jeenfall vor deine Vorschläge zu versuchen und will heute Baned 
wenn es mir reicht mit dem Oszi mal die Sendeleitung zu messen ob die 
errechnete baudrate sicher auch übernommen wurde.

von morph1 (Gast)


Lesenswert?

folgende Erklärung zu dem Ganzen:

Um mit einem PIC USB sprechen zu können, brauchen die intern einen Takt 
von 48Mhz.

Damit man nun keine blöden Quarze mit 48Mhz dranknallen muss, gibt es 
eine PLL (vereinfacht: Frequenzvervielfacher) dieser macht dir AUF 
WUNSCH 48Mhz Taktsignal.

Das muss man allerdings in der Konfiguration einstellen. D.h. wenn du da 
nicht reingefasst hast, dann rennt dein PIC eventuell sogar noch am 
internen RC-Oszillator, dann hat der nur 8Mhz alias 2Mhz Cycle Takt!

Oder wenn du ein fertiges Beispiel von Microchip verwendet hast, dann 
rennt der vielleicht mit eingeschalteter PLL auf 48MHz.

Es wäre also wichtig, dass du den realen Takt deines Prozessors 
rausfindest.

von Andreas B. (hokage)


Lesenswert?

Hi so hab eben nochmal versucht und der PIC lief mit dem internen 
Osziallator, hab das jetzt in den Configuration Bits umgestellt. Jetzt 
messe ich am Quarz auch die 12Mhz, dass heißt durch den Teiler 4 hab ich 
jetzt ein Fosc von 3MHz. Dadurch ergibt sich 
((3000000MHz/1200baud)/16-1) ein übergabewert von 155 für die Baudrate 
1200.

Um das zu überprüfen hab ich mit dem Oszi das zu übertragende Zeichen 
mal angeschaut und ein Bit nachgemessen und siehe da entspricht genau 
der Baudrate 1200. Wenn ich jetzt aber mit dem Terminal schaue kommt 
eben immer noch nur mist an. Sehe ich es richtig das ich bei meiner 
Config 1Start und ein Stopbit habe???? denn scheinbar ist es ja nicht 
ganz falsch was ich sende......

danke morph 1 für deine hilfe bisher

von Michael H. (morph1)


Lesenswert?

nimm mal baud1USART( BAUD_IDLE_RX_PIN_STATE_HIGH & BAUD_8_BIT_RATE &
BAUD_WAKEUP_OFF & BAUD_AUTO_OFF);

raus, eventuell invertierst du damit den low-pegel, dann kommt am pc nur 
müll an :)

von Andreas B. (hokage)


Lesenswert?

also ich bin wesentlich weiter gekommen, zum einen war in den 
configuration bits immer noch der interne takt kativ was jetzt stimmt 
und dieses zeile hat gefehlt:

BAUD_IDLE_TX_PIN_STATE_LOW damit ist jetzt auf der rs232 sendeleitung 
der ruhezustand low und nicht mehr high. jetzt wird auch mein zeichen 
übertragen aber leider immer noch ein zweites direkt hinterher wo ich 
nicht weiß wo es herkommt.....

es wird also das zeichen a gesendet und hinterher kommt immer ein 
schwarzes kästchen wo ich noch nicht nachvollziehen kann woher es kommt

hast du da auch veilleicht noch ne idee????? weiterhin danke für die 
hilfe

von Andreas B. (hokage)


Lesenswert?

so senden geht mittlerweile ja, habe das  programm um eine abfrage 
erweitert, wenn der taster der an rb2 angeschlossen ist gedrückt wird 
soll der string gesendet werden, leider reagiert das programm nicht auf 
den taster:

#include <p18f46j50.h>
#include <usart.h>
#include <delays.h>
#include <PORTB.h>

#pragma code
int i=100;
void main()
{
TRISBbits.TRISB2 = 1; // RB2 als Eingang
INTCON2bits.RBPU = 1; // Interne PULL UP Disable

Open1USART (USART_TX_INT_OFF &
       USART_RX_INT_OFF &
           USART_BRGH_LOW  &
       USART_CONT_RX &
           USART_EIGHT_BIT  &
       USART_ASYNCH_MODE, 155);

baud1USART( BAUD_IDLE_RX_PIN_STATE_LOW &
      BAUD_IDLE_TX_PIN_STATE_HIGH &
        BAUD_8_BIT_RATE &
      BAUD_WAKEUP_OFF &
      BAUD_AUTO_OFF);



while(1)
{

if(PORTBbits.RB2 == 1) // abrage ob 1
{
while(Busy1USART());
{
for(;i>0;i--)
{
putrs1USART ((const far rom char*)"rs232-test");
Delay100TCYx(90000000);
}
}
}
}

}

weiß jemand warum??? thx

von PicNiker (Gast)


Lesenswert?

> Jetzt messe ich am Quarz auch die 12Mhz, dass heißt durch den Teiler 4 hab >ich 
jetzt ein Fosc von 3MHz.
Der Eingangstakt für die PLL muss genau 4MHz sein, also eher:

#pragma config PLLDIV   = 3         // (12 MHz crystal)
#pragma config CPUDIV   = OSC4_PLL6 // core clock is 16 Mhz
#pragma config USBDIV   = 2         // Clock source from 96MHz PLL/2
#pragma config FOSC     = HSPLL_HS

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.