Pic18lf452, Problem med att adressera med i2c

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Johel572
Inlägg: 53
Blev medlem: 5 juli 2006, 10:36:01
Ort: Linköping

Pic18lf452, Problem med att adressera med i2c

Inlägg av Johel572 »

Hej!
Jag försöker läsa en byte data från en extern givare via i2c till min pic18. Pic18lf452 har ju hårdvarustöd för i2c så det borde ju inte vara så svårt men jag har lite problem. Jag stegar igenom koden med en icd2 men det fasnar i en loop som kontrollerar om adressen är sänd. Koden är i princip microchips exempel kod för användning av i2c.

Bekymmret är att SSPIF i PIR1 registret inte blir hög (ska ju bli hög när adressen är sänd om jag har förstått det rätt) när jag försöker adressera givaren. Någon som har något tips på vad man ska kontrollera först?

Det är alltså btfss PIR1, SSPIF raden som spökar.

Del av koden jag använder:

Kod: Markera allt

rWakeSlave
	bcf	PIR1,SSPIF	; clear interrupt flag
	nop
	movf	slaveAddr,W
	movwf	SSPBUF		; move slave address to SSPBUF
	btfss	PIR1,SSPIF	; has SSP completed sending SLAVE Address?
	goto	$-2		; no, loop back to test

	btfss	SSPCON2,ACKSTAT	; was ACK received from slave?
	return			; yes, return to calling routine
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 7487
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Inlägg av Marta »

Det förefaller som att sändning inte sker, med följd att den väntar oändligt.

Har Du kollat initieringen så att det t.ex. finns rätt klocksignal tillgänglig för I2C-modulen? Det finns en lista i databladet i kapitlet om I2C som visar på de register som har inverkan.

Har Du läst alla grå rutor i databladet som har med I2C att göra och är säker på att det som står där uppfylls?
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 47013
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Inlägg av TomasL »

Kolla även erratorna, det finns en del konstigheter med MSSP modulen i en del av kretsarna i 18F serien.
blueint
Inlägg: 23238
Blev medlem: 4 juli 2006, 19:26:11
Kontakt:

Inlägg av blueint »

Är det vanligt med felfabricerade chips från Microchip jämfört med Atmel-AVR?, denna kommentar + infon om ENC 28J60 i december får mig att fundera.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 47013
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Inlägg av TomasL »

Nja, tror jag inte iofs, men som alla andra uC så är väl buggar nåt som förekommer, mer eller mindre.
Oavsett vilket, så förutom datablad och referensboken så är erratorna minst like viktiga.
Användarvisningsbild
squiz3r
Inlägg: 5424
Blev medlem: 5 september 2006, 20:06:22
Ort: Lund
Kontakt:

Inlägg av squiz3r »

Antingen är jag bara lite korkad idag, eller så har alla ni missat en detalj som jag upptäckte första gången jag skummade igenom koden.. :)

movwf SSPBUF
btfss PIR1,SSPIF
goto $-2

Det den gör här, om jag inte tänker fel, det är att den lägger in det som ska sändas i SSP bufferten, sen kollar den om det är skickat, efter det ska den testa det igen och igen, men eftersom det står $-2 så hoppar den två steg bakåt vilket gör att den laddar in värdet i SSPBUF igen. Och om jag minns rätt (har alldrig använt MSSP..) så börjar den om att skicka då, dvs. avbryter det den håller på med nu? Och då kommer den ju alldrig att skicka klart den byten!

Eller?? :)
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Inlägg av vfr »

Om jag inte minns helt fel så räknar PIC18 sina programadresser i bytes, och då stämmer det utmärkt. Däremot är det sättet att skriva helt förkastligt eftersom man måste justera adresserna hela tiden om man lägger in eller tar bort en rad emellan. Dessutom väldigt otydligt vart den egentligen hoppar. Tips till trådskrivaren: Använd lablar istället!!
Användarvisningsbild
Johel572
Inlägg: 53
Blev medlem: 5 juli 2006, 10:36:01
Ort: Linköping

Inlägg av Johel572 »

Det förefaller som att sändning inte sker, med följd att den väntar oändligt.

Har Du kollat initieringen så att det t.ex. finns rätt klocksignal tillgänglig för I2C-modulen?
Hm, det här kan nog vara något. I exemplet som koden kommer i från användes en 4Mhz oscillator medan jag har en 12Mhz kristall på min (tog ett gammalt labbkort jag hade liggandes). Jag är inte helt säker på att jag räknat rätt (eller rättare sagt jag är ganska säker på att jag räknar fel) när jag ställer in i2c klocksignalen (SSPADD).

Nu har jag dock gjort om beräkningen och är tämligen säker på att jag gjort rätt. Beräknar värdet genom formeln:

SSPADD=(Fosc/(4*Baud))-1

Och det verkar betydligt vettigare än det värde jag hade tidigare (vette sjutton hur jag räknade då). Ska se i morgon om det fungerar bättre.

Tack för snabbt och informativt svar.
Användarvisningsbild
Johel572
Inlägg: 53
Blev medlem: 5 juli 2006, 10:36:01
Ort: Linköping

Re: Pic18lf452, Problem med att adressera med i2c

Inlägg av Johel572 »

Jag skrev om koden lite för att testa men det tycks som om jag fastnar på samma ställe som förut. Dvs det ser inte ut som att jag skickar iväg någon adress. SSPSTAT, R_W ska bli hög när jag lägger slave-adressen i SSPBUF för att sedan bli låg när adressen är skickad (på samma sätt som PIR1,SSPIF i förra exemplet). Den blir aldrig låg och jag förstår inte riktigt varför.

SSPSTAT,R_W / PIR1,SSPIF är väl inte beroende av någon yttre källa så som ACK från slave. De ska väl bli låg när jag börjat sända adressen? Efter en titt i databladet så ser jag att jag missat pull-up resistorer på SDA, SCL, det skall fixas omgående. Det kan ju sen vara andra fel på inkopplingen av sensorn men hur påverkar det min PIC egentligen?

Ny kod:

Kod: Markera allt

	movf	slaveAddr,W
	movwf	SSPBUF		;Flytta slave adressen till SSPBUF för read, detta startar sänding av adressen
	btfsc	SSPSTAT,R_W	;Kontrollerar om vi skickat adressen
	goto	$-2
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 7487
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Pic18lf452, Problem med att adressera med i2c

Inlägg av Marta »

Läste inte koden tillräckligt noga. Antar att det är samma procedur för 18LF452 som för 18F452. I så fall gör Du fel.

Alla klarsignaler ges genom att interruptflaggan sätts. Det är denna Du skall vänta på och inget annat.

Innan Du sänder adressen så måste Du starta en överföring genom att initiera en "start condition". Har Du gjort detta samt väntat på att den blir klar?

Det finns en lista i databladet som steg för steg beskriver vad som skall göras för att t.ex. sända en byte. Använd denna som mall för Din kod till att börja med, sedan skall vi nog kunna hjälpa Dig att få det hela att fungera.

Titta även igenom alla timingdiagrammen, även om Du redan vet hur I2C fungerar, eftersom där finns en hel del PIC-specifik information om hur det hela hänger samman med vad som händer i de olika registren och det programmet måste göra.

Tag också bort hoppet med relativ addressering och använd labels. Även om det kan vara lite jobbigt i en assembler utan lokala labels så är det bättre så.

Posta också hela initieringen så det går att se om grundförutsättningarna är uppfyllda.
Senast redigerad av Marta 8 januari 2009, 12:41:37, redigerad totalt 2 gånger.
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Re: Pic18lf452, Problem med att adressera med i2c

Inlägg av vfr »

Pull-up resistorerna är viktiga! Utan dom så kan bussignalerna svänga hursomhelst och har inget definerat läge alls i öppet tillstånd. Det kan nog ge nästan vilka fenomen som helst. Återkom när du åtgärdat och testat vidare!
Användarvisningsbild
Johel572
Inlägg: 53
Blev medlem: 5 juli 2006, 10:36:01
Ort: Linköping

Re: Pic18lf452, Problem med att adressera med i2c

Inlägg av Johel572 »

Hej!
Tack för tipsen, jag har nu skrivit lite ny kod, satt dit pull-up resistorer och satt rätt adress(!). Det jag försöker göra är att ta emot en byte data från en sensor via i2c. Nu hänger den sig på raden för ACK från slave jag antar betyder att den inte hittar på sensorn.


Så här tänker jag mig att programmet skall fungera.
Initiera MSSP för i2c master
Skicka start bit, SSPCON2,SEN
Adressera slave
Ta emot ACK från slave
Konfigurera MSSP för recive mode, SSPCON2,RCEN
Ta emot data från slave
Spara data till en variabel, SSPBUF-->variabel
Skicka ACK till slave
Sätt stop bit, SSPCON2,PEN
Klart!

Här kommer delar av min kod.

Initiering av MSSP:

Kod: Markera allt

;Configure SSP for hardware master mode i2c
	bsf	SSPSTAT,SMP		;I2C slew rate control disabled
	bsf	SSPCON1,SSPM3	;I2C master mode in hardware
	bsf	SSPCON1,SSPEN	;enable SSP module

	movlw	0x1D		;set I2C clock rate to 100kHz,29d=>1Dh för 12MHz
	movwf	SSPADD		;SSPADD is baudrate reload value in mastermode

	bsf	TRISC,3			;I2C SCL pin is input
	bsf	PORTC,3			;(will be controlled by SSP)
	bsf	TRISC,4			;I2C SDA pin is input
	bsf	PORTC,4			;(will be controlled by SSP)
Mottagning av en byte data:

Kod: Markera allt

;Startar mottagning över i2c
	bcf		PIR1,SSPIF
	bsf		SSPCON2,SEN	;Sätter start bit för MSSP
startSend
	btfss 	PIR1,SSPIF	;Kontrollerar om i2c modulen är igång
	goto	startSend

	bcf		PIR1,SSPIF
	movf	slaveAddr,W
	movwf	SSPBUF		;Flytta slave adressen till SSPBUF för read, detta startar sänding av adressen	
addressSSPBUF	
	btfss	PIR1,SSPIF	;btfsc	SSPSTAT,2	;Kontrollerar om vi skickat adressen, R/W bit
	goto	addressSSPBUF	

ackSlave
	btfss	SSPCON2,ACKSTAT	;Fick vi ACK fån slave för adressen? ACKSTAT bara aktiv i Master transmit mode
	Goto	ackSlave

	bcf		PIR1,SSPIF
	bsf		SSPCON2,RCEN	;Gör klart för mottagning av en byte
reciveByte
	btfss	PIR1,SSPIF		;Kontrollerar om vi tagit emot en byte
	goto 	reciveByte

	movff	SSPBUF,data1	;Lägg mottagen data in en variabel

	bsf		SSPCON2,ACKDT	;Skickar ACK till slave
	bsf		SSPCON2,ACKEN
ackSend	
	btfsc	SSPCON2,ACKEN	;Kontrollerar om ACK är skickad
	goto	ackSend

	bsf		SSPCON2,PEN		;Skickar stop bit
stopSend	
	btfsc	SSPCON2,PEN		;Kontrollerar om stop bit sänd
	goto 	stopSend
Ska jobba vidare med det under kvällen så får vi se
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 7487
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Pic18lf452, Problem med att adressera med i2c

Inlägg av Marta »

Vad hittar Du på här?

Kod: Markera allt

ackSlave
   btfss   SSPCON2,ACKSTAT   ;Fick vi ACK fån slave för adressen? ACKSTAT bara aktiv i Master transmit mode
   Goto   ackSlave
Om ACKSTAT är satt så fortsätter programmet och om den är nollad så väntar det :? Om ACKSTAT är satt så skall Du hoppa till ERROR, om den är nollad så har adressen accepterats och Du skall fortsätta. Du har vänt på det hela. Dessutom skall Du inte vänta vid error utan hantera felet istället.
Användarvisningsbild
Johel572
Inlägg: 53
Blev medlem: 5 juli 2006, 10:36:01
Ort: Linköping

Re: Pic18lf452, Problem med att adressera med i2c

Inlägg av Johel572 »

Ni har så rätt, tack. ACKSTAT ska sätts ju låg när vi fått ACK från slave. Vettesjutton hur det kunde bli så.

Jag ser även att jag klantat mig längre ner i koden när jag skall skicka ACK till slave efter mottagning av en byte. Bör väl vara bcf SSPCON2,ACKDT om man tittar i SSPCON2 registret.

Jag mig en extra titt på sensorn i går kväll och den indikerade att fältstyrkan är för låg (magnetgivare). Dock borde man väl kunda läsa ett värde från den ändå. Lusläser man databladet för den så ska den skicka fyra byte med data då den andra byte innehåller status bitar som skall indikera om fältstyrkan är för låg vilket får mig att tro att jag kan komunicera med den ändå. Lär väl skriva om koden lite för att ta emot fyra byte men det borde inte vara några problem bara jag kan får den att fungera för en byte.

Jag bytte även ut PIC18LF452 till en PIC18F452, bör väl vara lika iofs.

Sitter på jobbet nu, återkommer med resultat i kväll eller i morgon.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 7487
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Pic18lf452, Problem med att adressera med i2c

Inlägg av Marta »

"Jag ser även att jag klantat mig längre ner i koden när jag skall skicka ACK till slave efter mottagning av en byte. Bör väl vara bcf SSPCON2,ACKDT om man tittar i SSPCON2 registret."

Nej, det har Du inte alls gjort.

Om Du skickar ACK till slave vid mottagning så betyder det att slave skall fortsätta sända. Skall flera bytes tas emot så skicka ACK till alla utom den sista som skall ha NAK eller vad det nu kallas som en signal att slave skall sluta sända.
Skriv svar