16F628A - RB0 påverkar USART?
16F628A - RB0 påverkar USART?
Jag är hyfsat grön på PIC:ar och just nu så håller jag på med ett litet bygge med en PIC16F628A där jag jag bit-bangar synkron seriell data in på RA7 och sänder den via USART som asynkron seriell data 9600 8n1 till en PC.
Först körde jag med klockan för den synkrona datan på RA1, och det var inga problem. Sen tänkte jag att jag skulle göra det lite smidigare och köra klockan på RB0 istället för att på så vis kunna läsa av INTCON, INTF när klockan når negativ flank. Jag funderade också på att använda interrupt "fullt ut" men började med att läsa INTF flaggan för att ta ett steg i taget.
Nu helt plötsligt fick jag bara skräp ut på porten. Det visade sig att när RB0 är satt som ingång så stör den USART:en på nåt sätt, för om jag tar bort kollen av INTF, sätter RB0 som utgång så får jag ut vad jag förväntar mig på Tx.
OBS! Inga interrupts var aktiverade alls.
Har någon nån idé på vad det kan vara för fel?
Först körde jag med klockan för den synkrona datan på RA1, och det var inga problem. Sen tänkte jag att jag skulle göra det lite smidigare och köra klockan på RB0 istället för att på så vis kunna läsa av INTCON, INTF när klockan når negativ flank. Jag funderade också på att använda interrupt "fullt ut" men började med att läsa INTF flaggan för att ta ett steg i taget.
Nu helt plötsligt fick jag bara skräp ut på porten. Det visade sig att när RB0 är satt som ingång så stör den USART:en på nåt sätt, för om jag tar bort kollen av INTF, sätter RB0 som utgång så får jag ut vad jag förväntar mig på Tx.
OBS! Inga interrupts var aktiverade alls.
Har någon nån idé på vad det kan vara för fel?
Re: 16F628A - RB0 påverkar USART?
Jag gissar att felet mest troligt beror på en tankevurpa i din programkod.
Nollställer du interruptflaggan efter varje avläsning?
Kan du posta koden (eller väl valda delar av den)?
Nollställer du interruptflaggan efter varje avläsning?
Kan du posta koden (eller väl valda delar av den)?
Re: 16F628A - RB0 påverkar USART?
Alltså. Det spelar ingen roll om jag använder den flaggan eller inte. Jag gjorde ett experiment.
I början av koden, innan klocksignalen finns på RB0 (Den kommer bara när det finns synkrondata) så skickar jag ett hårdkodat "HEJ" på serieporten. Inga problem.
När Carrier Detect från kretsen som skickar synkrondatan går hög så kommer klockan på RB0. Då försökte jag skicka ett hårdkodat "HEJ" igen, utan att ta hänsyn till klockan och interruptflaggan. Då kommer det bara skräp ut på serieporten. Det blir 0xFF 0xFE 0xFC och runt i den trakten. Det verkar på nåt sätt som att en signal på RB0 fyller upp TXREG?
Samma fenomen kan jag se om jag sätter på Pic:ens interna pull-up på PortB.
Jag kommer gå tillbaka till att manuellt läsa klockan på portA istället tror jag. Men det verkar ju skumt att resten av portB inte ska kunna ställas som ingångar när USART:en används.
I början av koden, innan klocksignalen finns på RB0 (Den kommer bara när det finns synkrondata) så skickar jag ett hårdkodat "HEJ" på serieporten. Inga problem.
När Carrier Detect från kretsen som skickar synkrondatan går hög så kommer klockan på RB0. Då försökte jag skicka ett hårdkodat "HEJ" igen, utan att ta hänsyn till klockan och interruptflaggan. Då kommer det bara skräp ut på serieporten. Det blir 0xFF 0xFE 0xFC och runt i den trakten. Det verkar på nåt sätt som att en signal på RB0 fyller upp TXREG?
Samma fenomen kan jag se om jag sätter på Pic:ens interna pull-up på PortB.
Jag kommer gå tillbaka till att manuellt läsa klockan på portA istället tror jag. Men det verkar ju skumt att resten av portB inte ska kunna ställas som ingångar när USART:en används.
Re: 16F628A - RB0 påverkar USART?
Klart att man kan använda serieporten on RBo samtidig, posta den nödvändiga kod och låt oss se var problemet uppstår.
Re: 16F628A - RB0 påverkar USART?
Så, då har jag gjort lite mer experiment bara för att se om jag kunde utesluta saker själv innan jag postade här. Vad jag har kommit fram till är att det inte är RB0 i sig som är boven, utan att jag av någon anledning måste ha någon mer pinne konfigurerad som "Input" än RB1 och RB2 som är RX och TX, annars så går inte PIC:en igång.
Jag strippade ner koden rejält bara för att prova och började här:
Obs! Vissa av kommentarerna i intitieringen speglar inte koden, de hänger kvar sen gammalt.
På detta sätt kommer det inget alls på serieporten i datorn.
Om jag däremot sätter en pinne till som ingång (jag provade med RA0 och RB0, båda funkar) och drar den direkt till jord så snurrar allt igång. Tar jag bort kopplingen till jord under drift, så stannar pic:en och när jag kopplar tillbaka till jord så gör den en reset och går igång igen. Att den resettar ser jag genom att den börjar skriva 0x00 på serieporten innan "HEJ" kommer.
Pinnarna på PIC:en som är anslutna är som följer:
4. (/MCLR) till VDD via motstånd på 10k
5. VSS
7. (RX) till 12 (R1out) på MAX232
8. (TX) till 11 (T1in) på MAX232
14. VDD , avkopplad med en 100nF polyesterkondning.
Alla andra (förutom den jag måste sätta som ingång för att det ska funka) är oanslutna.
Jag strippade ner koden rejält bara för att prova och började här:
Kod: Markera allt
include <p16f628a.inc>
__CONFIG _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _MCLRE_ON & _BOREN_OFF & _LVP_OFF & _DATA_CP_OFF & _CP_OFF
;-------------------------------------------
; Generella register
;-------------------------------------------
cblock 0x20
CounterA ; För Delay-loopen
CounterB
CounterC
Buffer ; Teckenbuffert
endc
;-------------------------------------------
; Programstart
;-------------------------------------------
org 0x00 ; Resetvektor
goto start
;-------------------------------------------
; Interrupthantering
;-------------------------------------------
org 0x04 ; Interruptvektor
retfie
;-------------------------------------------
; Initiering vid reset
;-------------------------------------------
start
banksel PIR1 ; Välj bank 0
giecheck
bcf INTCON, GIE ; Stäng av globala interrupts
btfsc INTCON, GIE
goto giecheck
clrf PIR1 ; Nolla peripherial flags
clrf PORTA ; Nolla Port A
movlw 0x07
movwf CMCON ; Stäng av komparatorna
clrf PORTB ; Nolla Port B
banksel PIE1
clrf PIE1 ; Stäng av alla peripherial interrupt
movlw b'00100000'
movwf TRISA ; Sätt RA0 och RA7 till ingångar Port A
;**********************************************************************************************************
;Detta fungerar inte! Någon mer pinne på antingen PORTA eller PORTB måste vara ingång och kopplad till VSS!
;**********************************************************************************************************
movlw b'00000110' ; Sätt RB1 och RB2 till ingångar (för UART på Port B)
movwf TRISB ; samt RB0 som ingång för interruptflaggan
bsf OPTION_REG, NOT_RBPU ; Slå av interna pullups på ingångarna på PortB
clrf INTCON
;-------------------------------------------
; Sätt upp UART
; 9600bps 8n1
;-------------------------------------------
movlw b'00100100'
movwf TXSTA ; Slå på asynkron sändning och sätt BRGH hög
movlw 0x19 ; 0x19 = 9600bps
movwf SPBRG
banksel RCSTA ; Välj Bank 0
movlw b'10010000'
movwf RCSTA ; Slå på serieporten
call delay_1_sec ; Vänta 1s så att allt är OK
movf RCREG, W ; Rensa rx-bufferten
movf RCREG, W ; Inklusive fifo
movf RCREG, W ; som är 3 djup
movlw 0x00 ; Skicka ett dummytecken.
movwf TXREG ; För att få transmitflaggan OK
;-------------------------------------------
; Huvudfunktion
;-------------------------------------------
loop
call test ; Skriv 'HEJ' till serieporten för att testa
goto loop ; Vänta på nästa meddelandep
test
movlw 'H'
movwf Buffer
call send
movlw 'E'
movwf Buffer
call send
movlw 'J'
movwf Buffer
call send
return
;-------------------------------------------
; Skicka tecknet via RS232
;-------------------------------------------
send
movf Buffer, W
sendw
btfss PIR1, TXIF
goto sendw ; Vänta på transmitt interrupt flaggan
movwf TXREG ; Skicka data i Buffer
banksel TXSTA ; Välj Bank 1
txNotReady
btfss TXSTA, TRMT ; Om biten är satt är sändningen klar
goto txNotReady
banksel PORTA ; Välj Bank 0 och återgå
return
; Delay code generated by PikLoops (lör 2009-jan-03 18:56:45)
; Time Delay = 0.99999300s with Osc = 4.00000000MHz
delay_1_sec
movlw D'6'
movwf CounterC
delay_1_sec_loop
call sub_delay_1_sec
decfsz CounterC,1
goto delay_1_sec_loop
return
sub_delay_1_sec
movlw D'217'
movwf CounterB
movlw D'111'
movwf CounterA
sub_delay_1_sec_loop
decfsz CounterA,1
goto sub_delay_1_sec_loop
decfsz CounterB,1
goto sub_delay_1_sec_loop
return
end
På detta sätt kommer det inget alls på serieporten i datorn.
Om jag däremot sätter en pinne till som ingång (jag provade med RA0 och RB0, båda funkar) och drar den direkt till jord så snurrar allt igång. Tar jag bort kopplingen till jord under drift, så stannar pic:en och när jag kopplar tillbaka till jord så gör den en reset och går igång igen. Att den resettar ser jag genom att den börjar skriva 0x00 på serieporten innan "HEJ" kommer.
Kod: Markera allt
movlw 0x00 ; Skicka ett dummytecken.
movwf TXREG ; För att få transmitflaggan OK
4. (/MCLR) till VDD via motstånd på 10k
5. VSS
7. (RX) till 12 (R1out) på MAX232
8. (TX) till 11 (T1in) på MAX232
14. VDD , avkopplad med en 100nF polyesterkondning.
Alla andra (förutom den jag måste sätta som ingång för att det ska funka) är oanslutna.
Re: 16F628A - RB0 påverkar USART?
Du har skapat en evighetswait för första tecknet. Hur skall interruptflaggan kunna sättas innan något har sänts så att ett tecken kan bli färdigt och generera en interrupt.
Ta bort detta och vänta på att txregistret skall bli tomt *innan* ett tecken skivs till detta istället.
Skall Du ändra sändrutinen till att använda interrupt, vilket är onödigt om hastigheten på sändningen är så hög att den alltid hinner sända färdigt innan nästa tecken kommer, så måste förstateckenproblemet hanteras.
Ta bort detta och vänta på att txregistret skall bli tomt *innan* ett tecken skivs till detta istället.
Skall Du ändra sändrutinen till att använda interrupt, vilket är onödigt om hastigheten på sändningen är så hög att den alltid hinner sända färdigt innan nästa tecken kommer, så måste förstateckenproblemet hanteras.
Re: 16F628A - RB0 påverkar USART?
Jag vet inte vad problemet är, men har ett par kommentarer...
> Obs! Vissa av kommentarerna i intitieringen speglar inte koden,
Om du nu redan *vet* det, fixa det först innan du postar koden.
> Alla andra (förutom den jag måste sätta som ingång för att det ska funka) är oanslutna.
Och ingen av dom är ingångar (d.v.s de oanslutna) ?
> banksel TXSTA ; Välj Bank 1
Lite korkad och onödig kommentar. Hela finessen med BANKSEL är att inte behöva
veta vilken bank ett register befinner sig, för att skriva den där kommenteren
måste du ju i alla fall slå upp det i databladet...
Jag ser också att du i många fall har "optimerat bort" en del BANKSEL därför att
du sannolikt har upptäckt att vissa register ligger i samma bank. Men i detta fall
där du ju har något problem så är det lite dumt att ha det potentiella felet att
du har missat något fall där en BANKSEL skulle behövas. Alltså bättre vid felsökning
att ha BANKSEL överallt där du accessar ett register (som inte ligger i alla banker,
om man är helt säker på det, STATUS, INTCON o.s.v).
> Obs! Vissa av kommentarerna i intitieringen speglar inte koden,
Om du nu redan *vet* det, fixa det först innan du postar koden.
> Alla andra (förutom den jag måste sätta som ingång för att det ska funka) är oanslutna.
Och ingen av dom är ingångar (d.v.s de oanslutna) ?
> banksel TXSTA ; Välj Bank 1
Lite korkad och onödig kommentar. Hela finessen med BANKSEL är att inte behöva
veta vilken bank ett register befinner sig, för att skriva den där kommenteren
måste du ju i alla fall slå upp det i databladet...
Jag ser också att du i många fall har "optimerat bort" en del BANKSEL därför att
du sannolikt har upptäckt att vissa register ligger i samma bank. Men i detta fall
där du ju har något problem så är det lite dumt att ha det potentiella felet att
du har missat något fall där en BANKSEL skulle behövas. Alltså bättre vid felsökning
att ha BANKSEL överallt där du accessar ett register (som inte ligger i alla banker,
om man är helt säker på det, STATUS, INTCON o.s.v).
Re: 16F628A - RB0 påverkar USART?
Njae....
Detta har jag ju i initieringen:
På så sätt är ju interruptflaggan rätt med en gång. Den här koden för subrutinen "send" hittade jag här (rekommenderat från Piclist.)
Jag har faktist provat att köra utan koll på TXIF, men det blir samma sak.
Problemet är ju inte TXIF, utan att jag måste ha en pinne som ingång kopplad direkt till VSS, annars så resettas kretsen, eller på nåt sätt hoppar tillbaka till 0x00. Det duger inte med ett 10k motstånd emellan, utan den måste vara direkt på VSS.
Detta har jag ju i initieringen:
Kod: Markera allt
movlw 0x00 ; Skicka ett dummytecken.
movwf TXREG ; För att få transmitflaggan OK
Jag har faktist provat att köra utan koll på TXIF, men det blir samma sak.
Problemet är ju inte TXIF, utan att jag måste ha en pinne som ingång kopplad direkt till VSS, annars så resettas kretsen, eller på nåt sätt hoppar tillbaka till 0x00. Det duger inte med ett 10k motstånd emellan, utan den måste vara direkt på VSS.
Re: 16F628A - RB0 påverkar USART?
> utan att jag måste ha en pinne som ingång kopplad direkt till VSS, annars så resettas kretsen, eller på
> nåt sätt hoppar tillbaka till 0x00. Det duger inte med ett 10k motstånd emellan, utan den måste vara
> direkt på VSS.
Ja, *öppen* ska den i alla fall inte vara, däremot så ska ett nmotstånd vara helt OK. Det krävs
väldigt kraftiga störningar för att "överrösta" ett 10 K motstånd...
> nåt sätt hoppar tillbaka till 0x00. Det duger inte med ett 10k motstånd emellan, utan den måste vara
> direkt på VSS.
Ja, *öppen* ska den i alla fall inte vara, däremot så ska ett nmotstånd vara helt OK. Det krävs
väldigt kraftiga störningar för att "överrösta" ett 10 K motstånd...
Re: 16F628A - RB0 påverkar USART?
Förlåt. Jag upptäckte att jag hade glömt fixa kommentarerna efter jag hade postat inlägget, och skrev till ovanstående som ett tillägg.sodjan skrev:> Obs! Vissa av kommentarerna i intitieringen speglar inte koden,
Om du nu redan *vet* det, fixa det först innan du postar koden.
Nej, alla är satta som utgångar.sodjan skrev: > Alla andra (förutom den jag måste sätta som ingång för att det ska funka) är oanslutna.
Och ingen av dom är ingångar (d.v.s de oanslutna) ?
Korkat och korkat... Jag anser att det är bättre att överkommentera så här i början när jag lär mig.sodjan skrev: > banksel TXSTA ; Välj Bank 1
Lite korkad och onödig kommentar. Hela finessen med BANKSEL är att inte behöva
veta vilken bank ett register befinner sig, för att skriva den där kommenteren
måste du ju i alla fall slå upp det i databladet...
OK, så långt har jag inte tänkt. All kod jag har stött på hittils använder ju bara "bsf STATUS, RP0" osv. för att byta banker, men eftersom jag har sett här att banksel är att föredra så har jag använt det istället, fast på samma sätt. Men det var en bra synpunkt, den tar jag till mig direkt.sodjan skrev: Jag ser också att du i många fall har "optimerat bort" en del BANKSEL därför att
du sannolikt har upptäckt att vissa register ligger i samma bank. Men i detta fall
där du ju har något problem så är det lite dumt att ha det potentiella felet att
du har missat något fall där en BANKSEL skulle behövas. Alltså bättre vid felsökning
att ha BANKSEL överallt där du accessar ett register (som inte ligger i alla banker,
om man är helt säker på det, STATUS, INTCON o.s.v).
Re: 16F628A - RB0 påverkar USART?
Ovanstående kod funkar inte om jag inte har minst en ingång till utöver TX och RX. Och det funkar inte om jag kopplar den till VSS genom ett 10k motstånd, utan jag måste koppla den direkt till VSS. Jag har iofs inte provat med lägre värden.sodjan skrev:Ja, *öppen* ska den i alla fall inte vara, däremot så ska ett nmotstånd vara helt OK. Det krävs
väldigt kraftiga störningar för att "överrösta" ett 10 K motstånd...
Re: 16F628A - RB0 påverkar USART?
Vad mäter ingången för spänning när den är kopplad till Vss genom ett motstånd? Mät med ett scope om Du har tillgång till ett sådant.
Hur har Du det med avkopplingskondingar o.dyl saker?
Angående sändrutinen tycker jag det är ett mycket konstigt sätt att göra på. Har Du en länk till denna kod, där det kanske finns en förklaring till vad programmeraren har tänkt sig?
Hur har Du det med avkopplingskondingar o.dyl saker?
Angående sändrutinen tycker jag det är ett mycket konstigt sätt att göra på. Har Du en länk till denna kod, där det kanske finns en förklaring till vad programmeraren har tänkt sig?
Re: 16F628A - RB0 påverkar USART?
Jag har en avkoppling på 100nF precis vid picen.
7805 är avkopplad med 0.33uF samt 0.1uF enl. databladet
MAX232 har 5st 1uF enl. datablad
Länken postade jag ovan, men den är nog svår att se då den är inbäddad i ett "här".
http://redrival.com/mcgahee/picuart.zip
Den är för en 16C74 från början, men innehåller otroligt mycket bra kommentarer som förklarar varför allt är som det är.
7805 är avkopplad med 0.33uF samt 0.1uF enl. databladet
MAX232 har 5st 1uF enl. datablad
Länken postade jag ovan, men den är nog svår att se då den är inbäddad i ett "här".
http://redrival.com/mcgahee/picuart.zip
Den är för en 16C74 från början, men innehåller otroligt mycket bra kommentarer som förklarar varför allt är som det är.
Re: 16F628A - RB0 påverkar USART?
Ingången mäter 2,807V när den är kopplad över en 10K resistor.
Re: 16F628A - RB0 påverkar USART?
Är det en stabil DC, eller är det pulser. Det är mycket viktig information. Har Du inget scope kanske Du har en logikprobe. Har Du inte det så sätt ihop en enkel topplikriktare och mät vad Du får då.
Är intern pull-up avstängd? Om inte förklarar det nivåerna och Du behöver nog knappast mäta mera.
Är intern pull-up avstängd? Om inte förklarar det nivåerna och Du behöver nog knappast mäta mera.