Sida 1 av 1
Automatisk Baudrate-koll eller inte...
Postat: 29 september 2005, 06:01:42
av JimmyAndersson
Kör med: MikroBasic, PIC18LF1320. MAX232 och dator med COM-port...
Har precis fått kommunikationen mellan min PIC18LF1320 och dator att fungera. Testprogrammet skickar ett "A" samtidigt som en lysdiod lyser i 500ms, sedan skickar det ett mellanslag och lysdioden är släckt i 500ms.
Det är tänkt att det ska fungera så iallafall. Programmet skickar lite annorlunda tecken (ett x och ett norskt ö, istället för "A"...) Eftersom närmsta baudrate jag räknat fram är 9615 och datorn är inställd på 9600, så tänkte jag köra med "Auto Baudrate detection".
Men, det vill inte fungera riktigt. Lysdioden lyser hela tiden och det skickas inget. (Det gjorde det innan jag körde med "Auto Baudrate" Vad har jag missat?
Gissar att det har med interrupt att göra, men har inte riktigt fått kläm på det.
Här är koden:
Kod: Markera allt
program RS232_3
TRISA = $0 ' Utgångar
SetBit(TRISB,4) ' RB4 - IN
SetBit(TRISB,1) ' RB1 - IN
ClearBit(TRISB,2) 'RB2 - UT
PORTA = $0 ' Inget här
PORTB = $0 ' Inte här heller
SetBit(ADCON1,5) ' PCFG5 Digital
SetBit(ADCON1,6) ' PCFG6 Digital
TXSTA = %00100010 '8bit transmitt, asyncron, low speed, ingen parietetsbit
RCSTA = %10011000 'continious receive, ingen framing error, ingen overrun error, ingen parietetsbit
BAUDCTL = %01000011 '8bit baudrate register,
' dvs 8bit Asynchronous. BaudRateFormula = Fosc/(64*(n+1))
SPBRG = $40 ' 64 decimalt, innebär 9615 baud
'automatisk bauddetection: operate in PRI_RUN eller PRI_IDLE
'enable RXIF interrupts. Set RCIE, PEIE, GIE.
' När nästa RCIF interrupt händer så har baudrate blivit mätt.
' Läs RCREG för att rensa RCIF och discard. Kolla SPBRG och SPBRGH för valid value.
' EUSART är redo for normal communications. Return from the interrupt.
' Allow the primary clock to run (PRI_RUN or PRI_IDLE).
' Process subsequent RCIF interrupt normally as in asyncron repetition.
' Remain in PRI_RUN or PRI_IDLE until communications are complete.
' Så:
SetBit (PIE1,RCIE) ' Enable EUSART recieve interrupt
SetBit (INTCON,PEIE)
SetBit (INTCON,GIE)
do
TXREG = $41 ' A
SetBit(PORTB,2)
delay_ms(500)
TXREG = $20 ' Mellanslag
ClearBit(PORTB,2) delay_ms(500)
loop until 0 = 1
end.
edit: Justerade rubriken.

Postat: 29 september 2005, 08:14:04
av Icecap
Automatisk baudrate fungerar så att den förväntar att din PC ska sända en mellanslag och det väntar den på.........
Det är i alla fall standartsättet och just hur det fungerar på ditt system vet jag inte.
9615 fungerar ganska utmärkt mot 9600, har själv ett antal system som har det så och det har alldrig varit kommunikationsfel av den anledning.
Du har kanske inställt lite fel, jag ids inte ladda ner datablad men du har helt klart fel baudrate inställt. På PIC16-serien finns det ju en BRGH-bit som väljer vilken formel som baudraten räknas ut efter, du bör nog lusläsa lite om detta.
Postat: 29 september 2005, 12:28:13
av sodjan
Jag tror inte att autobaud löser problemen.
Kör med BRGH=1 och BRG16=1, så kan du ställa buadraten exaktare.
Är du säker på att processorn går i 40 Mhz ?
Om den går i 10 Mhz så skulle det kunna förklara det du ser på PC'n.
En snabb test kan vara att sätta SPBRG=15 (ca 9600 baud vid 10 Mhz), och se om det blir någon skillnad. Kolla sedan din CONFIG så att HSPLL är valt (vet inte hur man gör det i det språk du kör). Obs att man måste "power-cykla" vid ändringar i CONFIG för att det skall "ta".
Postat: 29 september 2005, 18:05:37
av JimmyAndersson
CONFIG var satt på HS. Har ändrat till HSPLL nu.
Hur "power-cyklar" man? Power av/på ? (Märker visserligen det när jag testar sedan, men det kan vara bra att veta.)
edit:
Har plockat bort Autobaud eftersom det alltså ska fungera ändå. Men nu lyser lysdioden hela tiden och jag får det inte att fungera som förrut. TXREG sätts rätt iallafall när jag kollar i debuggern.
Har vid ett tidigare försök disableat interrupten, men det fungerar ändå inte...
Här är den koden som den ser ut nu:
Kod: Markera allt
program RS232_3
TRISA = $0 ' Utgångar
SetBit(TRISB,4) ' RB4 - IN
SetBit(TRISB,1) ' RB1 - IN
ClearBit(TRISB,2) 'RB2 - UT
PORTA = $0 ' Inget här
PORTB = $0 ' Inte här heller
SetBit(ADCON1,5) ' PCFG5 Digital
SetBit(ADCON1,6) ' PCFG6 Digital
TXSTA = %00100110 '8bit transmitt, asyncron, high speed, ingen parietetsbit
RCSTA = %10010000 'continious receive, ingen framing error, ingen overrun error, ingen parietetsbit
BAUDCTL = %01001010 '16bit baudrate register,
SPBRG = %00010000
SPBRGH = %00000100
' Totalt 1040 som blir 9606baud.
do
TXREG = $41 ' A
SetBit(PORTB,2)
delay_ms(500)
TXREG = $20 ' Mellanslag
ClearBit(PORTB,2)
delay_ms(500)
loop until 0 = 1
end.
Postat: 29 september 2005, 19:49:49
av Andax
Apropå känsligheten på baudrate har jag för mig att fel på 3-4% inte ska vara några större problem. UART kretsarna synkar ju ihop klockorna vid varje startbit. Och driften under den tid det tar att skicka 10 bitar är ju försumbar då.
Postat: 29 september 2005, 20:36:00
av sodjan
3-4 % gäller acceptabelt fel sett mellan då två ändarna.
Det är bara att räkna på hur mycket en halv bit är på 10 bitar (inkl start och stop bit).
Men om den ena skall kunna ligga fel åt ena "hållet", och den andra åt det andra, så får varje ände inte ligga mer fel än hälften av det. Om båda ändar ligger inom 2% från nominell baudrate, så spelar det ingen roll om den ena ligger "+" och den andra "-". Bäst är om man kan hålla sin inom +/- 1.5%.
> Hur "power-cyklar" man? Power av/på ?
Yes !!
> Men nu lyser lysdioden hela tiden
Tja, det är väll bara att debugga...
Plocka bort allt utom (i loopen alltså) :
SetBit(PORTB,2)
delay_ms(500)
ClearBit(PORTB,2)
delay_ms(500)
och se om du "får igång" led'en...
När det fungerar, lägg till USART prylarna igen...
Postat: 29 september 2005, 21:18:09
av JimmyAndersson
Sådär nu fungerar det igen. Debuggern är bra...
Men: Bara när jag kör HS i config. Men inte i HSPLL...
Det som landar i terminalfönstret när jag kör med HS är:
Kod: Markera allt
ASCII:
Received: xø
Received:
Received: xø
Received:
Received: xø
Received:
Received: xø
HEXADECIMALT:
Received: 0x00 0x80
Received: 0x78 0xF8
Received: 0x00 0x80
Received: 0x78 0xF8
Received: 0x00 0x80
DECIMALT:
Received: 120 248
Received: 0 128
Received: 120 248
Received: 0 128
Precis som förra gången det fungerade. När jag kör HSPLL så är lysdioden tänd hela tiden och terminalen tar bara emot "brus-data".
Sladdarna till kristallen mm är korta. Tog en bild:

Den gula sladden till höger om kristallen är inte samma som går från den vänstra kondensatorn, det ser bara ut så.

Motståndet är för MCLR.
Postat: 29 september 2005, 21:46:08
av sodjan
OK, det skall i och för sig få detta att fungera även vid 10 Mhz, men då måste du välja SPBRG(H) värden för 10 Mhz också. Har du gjort det ? Jag har för mig att värderna som du körde med från början var för 40 Mhz, eller minns jag fel ?
Postat: 29 september 2005, 22:43:20
av JimmyAndersson
Minns knappt själv efter alla tester.
Jag gör om för säkerhetskull:
Med HSPLL och SPBRG(H) räknat på 40MHz: Lysdioden lyser hela tiden.
Med HS och SPBRG(H) räknat på 10MHz: Då fungerar allt som det ska. Lysdioden blinkar och terminalen tar emot varannan "A" och varannan mellanslag.
Kan tillägga att jag även testade utan USART-kommandona i loopen i testet räknat på 40MHz och HSPLL.
Hm, hur kommer det sig att det är "stopp" när jag försöker köra med 40MHz...
Postat: 29 september 2005, 23:42:24
av sodjan
OK, då var problemet från början att baud raten var beräknad utifrån 40 Mhz, men processorn gick i 10, stämmer bra med vad du såg...
Sen, *vissa* PIC18 har haft problem vid 40 Mhz. Jag tror att den serien där den du har var med bland dessa. Detta problem skall vara åtgärdat i senare kisel-revisioner, men jag vet inte om just den du har ligger före eller efter denna tidpunkt. Jag vet inte heller riktigt hur man ser det på märkningen på processorn...
En annan sak, på bilden (där man i och för sig inte såg så mycket) fanns det inte några glättnings/avstörrnings kondingar. 100nF så nöra PICen som möjlig brukar rekomenderas..
Man skulle behöva göra något enkelt program som enbart testar om den "snurrar" alls vid 40 Mhz...
Postat: 30 september 2005, 00:35:30
av JimmyAndersson
Jag gjorde några enkla program. Resultaten av dessa är att denna kod fungerar:
(Fungerar även om jag kör PORTB=$FF istället.)
Däremot, börjar jag blanda in pauser, som t.ex:
Kod: Markera allt
TRISB = $00
PORTB = $00
delay_ms(500)
PORTB = $FF
delay_ms(500)
PORTB = $00
Så stannar den med lysdioden släckt.
Byter jag plats på $00 och $FF så stannar den i stället med lysdioden tänd.
Så den "snurrar" men inte helt ok.
Jag har ingen så liten avstörnings-konding inkopplad. (Däremot 2200µF, 47µF och en på 10µF.)
edit: Kopplade in en 100nF, men tyvärr blev det ingen skillnad. Provade även med en okänd konding, som visade sig vara en 47nF, (körde den samtidigt som 100nF och de andra.)
Tyvärr gick det inte att koppla in dem direkt på PIC-kretsen, så jag satt dem så nära 5volts-matningen som det gick. Har även bytt sladdar, även dessa är korta, så det borde inte vara de som spökar...
Testade för säkerhetskull med den andra (likadana) PIC som jag köpte, men det var ingen skillnad.