Problém s I2C u 16F877A

Sehnal jsem si teplotní čidlo MCP9800A0 a mám problém se čtením teploty s 16F877A. Komunikace funguje, data se s čidla vyčtou, ale po nějaké době se komunikace zhroutí a v PIE2 mi to hlásí kolizi na sběrnici, ale při tom to třeba 20 minut měřilo normálně.
V čidle chyba není, připojil jsem ho k PC přes LPT a meřilo to celou noc a bez problému.

Může mi někdo poradit, co se má správně udělat při kolizi na sběrnici nebo co mám špatně v programu?

[code]ReadTemp_4
banksel PIR2
bcf PIR2,BCLIF ; vymazat priznak kolize
;StartI2C
banksel PIR1
bcf PIR1,SSPIF ; vznulovat priznak dokonceni
banksel SSPCON2
bsf SSPCON2,SEN ; send i2c START [S] bit
banksel PIR2
btfsc PIR2,BCLIF ; doslo ke kolizi
goto $-12 ; Ano - znova START I2C
banksel PIR1 ;
btfss PIR1,SSPIF ; donkoncen START?
goto $-7 ; NE, tak pockat a testovat kolizi

;AdresaI2C write
banksel PIR1 ; START odeslan, jinak bych sem nedosel
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPBUF ;
movlw b’10010000’ ; adresa + WRITE do
movwf SSPBUF ; registru odesilani
banksel PIR1 ; dokonceno ?
btfss PIR1,SSPIF ; vcetne ACK od cidla?
goto $-1 ; NE, tak pockat a testovat a cekat
;Config
banksel PIR1 ; Data odeslana, jinak bych sem nedosel
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPBUF
movlw b’00000000’ ; zapsat 0x00, cteni teploty
movwf SSPBUF ; zapsat do registru odesilani
banksel PIR1 ; dokonceno ?
btfss PIR1,SSPIF ; vcetne ACK od cidla?
goto $-1 ; NE, tak pockat a testovat a cekat
;Config
;Dalsi StartI2C
banksel PIR1 ; Data odeslana, jinak bych sem nedosel
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPCON2 ;
bsf SSPCON2,RSEN; opakovany START,
banksel PIR1 ;
btfss PIR1,SSPIF ; dokonceno ?
goto $-1 ; NE, tak pockat a testovat a cekat
;Config
;AdresaI2C read
banksel PIR1 ; Data odeslana, jinak bych sem nedosel
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPBUF
movlw b’10010001’ ; adresa + READ do
movwf SSPBUF ; registru odesilani
banksel PIR1 ; dokonceno ?
btfss PIR1,SSPIF ; vcetne ACK od cidla?
goto $-1 ; NE, tak pockat a testovat a cekat
;Prijem_I2C
banksel PIR1 ; Data odeslana, jinak bych sem nedosel
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPCON2 ;
bsf SSPCON2,RCEN; zapnout prijem
banksel PIR1 ;
btfss PIR1,SSPIF ; precteno?
goto $-1 ; NE, tak pockat a testovat a cekat
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPBUF ;
movf SSPBUF,w ; precist bufer
movwf TeplotaH ; do nizsiho
banksel SSPCON2
bcf SSPCON2,ACKDT ; vyslat AKC
bsf SSPCON2,ACKEN ; nastavit odeslani ACK
btfss SSPCON2,ACKEN ; odeslan?
goto $-1

banksel	PIR1		; dokonceno ? 
btfss	PIR1,SSPIF	; vcetne ACK do cidla?
goto	$-1			; NE, tak pockat a testovat a cekat

;Prijem_I2C
banksel PIR1 ; Data odeslana, jinak bych sem nedosel
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPCON2 ;
bsf SSPCON2,RCEN; zapnout prijem
banksel PIR1 ;
btfss PIR1,SSPIF ; precteno?
goto $-1 ; NE, tak pockat a testovat a cekat
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPBUF ;
movf SSPBUF,w ; precist bufer
movwf TeplotaL ; do nizsiho
banksel SSPCON2
bsf SSPCON2,ACKDT ; nevyslat AKC
bsf SSPCON2,ACKEN ; nastavit odeslani ACK
btfss SSPCON2,ACKEN ; odeslan?
goto $-1

banksel	PIR1		; dokonceno ? 
btfss	PIR1,SSPIF	; vcetne ACK do cidla?
goto	$-1			; NE, tak pockat a testovat a cekat

;StopI2C
banksel PIR1 ; Data odeslana, jinak bych sem nedosel
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPCON2
bsf SSPCON2,PEN ; odeslat STOP
banksel PIR1
btfss PIR1,SSPIF ; odeslan
goto $-1 ; ne
return ; navrat
[/code]

Už jsem to vyřešil. Opět děkuji všem za rady. :blush: :blush: :blush:

Aspoň bys moh napsat co si tam upravil a jak si to vyřešil aby ti to fachalo. Picama se sice nezabejvám a vůbec jim nerozumim, ale třeba by mě to stejně zajímalo… a jiný by to zajímat mohlo taky…
Zdarrr Honza

Teď to mám takhle a jede to už druhej den. Netestovat po STARTU nic jiného než SSPIF.

[code]
;**************************************************************************
;cteni teploty z MCP9800A0
;cteni je ukladano do TeplotaH a TeplotaL
;TeplotaL je nepodstatna
;**************************************************************************
ReadTemp_4
banksel PIR2
bcf PIR2,BCLIF ; vymazat priznak kolize
;StartI2C
banksel PIR1
bcf PIR1,SSPIF ; vynulovat priznak dokonceni
banksel SSPCON2
bsf SSPCON2,SEN ; send i2c START [S] bit
banksel PIR2
btfsc PIR2,BCLIF ; doslo ke kolizi
goto $-12 ; Ano - znova START I2C
; return
banksel PIR1 ;
btfss PIR1,SSPIF ; donkoncen START?
goto $-7 ; NE, tak pockat a testovat kolizi
;AdresaI2C write
banksel PIR1 ; START odeslan, jinak bych sem nedosel
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPBUF ;
movlw b’10010000’ ; adresa + WRITE do
movwf SSPBUF ; registru odesilani
banksel PIR1 ; dokonceno ?
btfss PIR1,SSPIF ; vcetne ACK od cidla?
goto $-1 ; NE, tak pockat a testovat a cekat
;Config
banksel PIR1 ; Data odeslana, jinak bych sem nedosel
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPBUF
movlw b’00000000’ ; zapsat 0x00, cteni teploty
movwf SSPBUF ; zapsat do registru odesilani
banksel PIR1 ; dokonceno ?
btfss PIR1,SSPIF ; vcetne ACK od cidla?
goto $-1 ; NE, tak pockat a testovat a cekat
;Dalsi StartI2C
banksel PIR1 ; Data odeslana, jinak bych sem nedosel
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPCON2 ;
bsf SSPCON2,RSEN; opakovany START,
banksel PIR1 ;
btfss PIR1,SSPIF ; dokonceno ?
goto $-1 ; NE, tak pockat a testovat a cekat
;AdresaI2C read
banksel PIR1 ; Data odeslana, jinak bych sem nedosel
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPBUF
movlw b’10010001’ ; adresa + READ, cteni teploty
movwf SSPBUF ; registru odesilani
banksel PIR1 ; dokonceno ?
btfss PIR1,SSPIF ; vcetne ACK od cidla?
goto $-1 ; NE, tak pockat a testovat a cekat
;Prijem_I2C
banksel PIR1 ; Data odeslana, jinak bych sem nedosel
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPCON2 ;
bsf SSPCON2,RCEN; zapnout prijem
banksel PIR1 ;
btfss PIR1,SSPIF ; precteno?
goto $-1 ; NE, tak pockat a testovat a cekat
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPBUF ;
movf SSPBUF,w ; precist bufer
movwf TeplotaH ; do vyssiho
banksel PIR1 ; Data prectena, jinak bych sem nedosel
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPCON2
bcf SSPCON2,ACKDT ; vyslat AKC
bsf SSPCON2,ACKEN ; nastavit odeslani ACK
; btfss SSPCON2,ACKEN ; odeslan?
; goto $-1

banksel	PIR1		; dokonceno ? 
btfss	PIR1,SSPIF	; vcetne ACK do cidla?
goto	$-1			; NE, tak pockat a testovat a cekat

;Prijem_I2C
banksel PIR1 ; Data odeslana, jinak bych sem nedosel
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPCON2 ;
bsf SSPCON2,RCEN; zapnout prijem
banksel PIR1 ;
btfss PIR1,SSPIF ; precteno?
goto $-1 ; NE, tak pockat a testovat a cekat
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPBUF ;
movf SSPBUF,w ; precist bufer
movwf TeplotaL ; do nizsiho
banksel PIR1 ; Data prectena, jinak bych sem nedosel
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPCON2
bsf SSPCON2,ACKDT ; nevyslat AKC
bsf SSPCON2,ACKEN ; nastavit odeslani ACK
; btfss SSPCON2,ACKEN ; odeslan?
; goto $-1

banksel	PIR1		; dokonceno ? 
btfss	PIR1,SSPIF	; vcetne ACK do cidla?
goto	$-1			; NE, tak pockat a testovat a cekat

;StopI2C
banksel PIR1 ; Data odeslana, jinak bych sem nedosel
bcf PIR1,SSPIF ; vynulovat priznak operace
banksel SSPCON2
bsf SSPCON2,PEN ; odeslat STOP
banksel PIR1
btfss PIR1,SSPIF ; odeslan
goto $-1 ; ne
return ; navrat[/code]

Aha, tak dík no… myslel sem že napíšeš v čem byl problém (sice si něco málo napsal) ale v pochopení problému mi to nepomohlo :open_mouth: :smiley:
Měj se, Honza

Stačí si oba zdrojové kódy hodit do programu na porovnávání (např. UltraCompare) a hned je vidět, co se změnilo.

Změnilo se to, že jsem čekal, asi zbytečně, na dokončení odesílaní ACK. Zrušil jsem ho a čekám jen na SSPIF, na dokončení celé operace včetně ACK. Netvrdím, že to tak má být, ale zatím to funguje :smiley:

Tak jsem zjistil dobrou věc. Když se toto čidlo připojí přímo na +5V bez omezovacího odporu cca 500 ohm, tak je otázka hodin, kdy se čidlo přenese do elektronického nebe. Už jsem tam poslal 2, doufám že třetí přežije. :smiley:
Mohli to někam napsat, v datasheetu o tomto není ani zmíňka. Přitom napajení má od 2,7V do 5,5V. Omezovací odpory na I2C SDA a SCL mám 330 ohm a pullupy 15k.
Přišel jsem na to náhodou, když čidlo 3 dny měřilo a 4 den už ne. Vyměnil jsem ho a to samé, ale o 1 den méně. Pak jsem v jednom schématu našel omezovací odpor na +5V. Tak jsem ho tam dal, zatím to měří. Otázka jak dlouho. :open_mouth:

Napsal bych firmě kerá to vyrábí…
zajímavý ale… :slight_smile:

Vyraba to Microchip. Tym by som ani nepisal :slight_smile: .

Ale vazne. Z mojich skusenosti dost pochybujem, ze by to bolo zlou suciastkou. Respektive pravdepodobnost takej udalosti je velmi velmi mala a u Microchipu by som to nepredpokladal. Predsa sa jedna o renomovaneho vyrobcu. Nechcem tym ale spochybnit Tvoju skusenost. Ak by sa Ti podarilo, skus napajat to cislo podla datasheetu, ale aby si mal urcite priamo na pinoch filtracny kondik 0.1-1uF a daj tam este transil na 5V8. Mozno sa Ti cez Ucc niekde dostavaju pulzy a tie sa mu nepacia. Co sa tyka kondiku, znamy WDG ADM705 bez kondiku priamo na pinoch jednoducho spravne nefunguje.
Ak Ti po tychto opatreniach cislo neodide, nie je chyba v nepritomnosti odporu.
V prvom prispevku si pisal, ze Ti cca po 20 min. prestalo cidlo komunikovat, ale s PC Ti komunikovalo. Ako si ho napajal pri komunikacii s PC? Je to divne a bolo by dobre zistit wocogo.

Martin

S PC to jelo celou noc, ale je tam 5 odporu, z toho jeden na napajeni 100 ohm. Ale až asi za dva dny jsem kouknul do logu, co dělal ten program co 5 minut a 13x byly naměřeny nesmysly. Hodinu to čidlo nemeřilo a pak se komunikace zase “chytla”.Takže taky to nebylo bez chyby.

Jinak to čidlo mám na malém plošnáčku, kondik 100nF 5mm od napájecích pinů IO v keramice, SMD doma nemám. A mám to zapojeno podle výrobce. Součástkou, jako typem, to asi určitě nebude, chyba bude u mě, ale nevím v čem a silně pochybuji o tom, že bych I2C komunikaci odrovnal špatně napsaným programem.

A až teď ráno jsem zjistil jednu věc. Já vždy při INIT procesoru jsem nastavoval čidlo, a upravoval jsem teplotní kompenzaci na ON 80°C a OFF 50°C a když to “špatné” čidlo teď připojím k 877A, tak 1 ze 3 ještě jede, ale ty 2 sice pomocí I2C nekomunikují, ale “funkce” ALERT je funkční, když ho zahřeji, zmení log. hodnotu. Nastaveni se zapisuje do vnitřní EEPROM v čidle.

Možná bude chyba v nastavení I2C v PICu, ale zkoušel jsem 3 rychlosti, které PIC nabízí a je to u všech stejný. A s I2C už jsem dělal zesilovač a tam mi jede už asi rok a taky bez problému, ale jen na WRITE do TDA7348. A v zápise a čtení zase tak velký rozdíl není, jen se při volání adresou obvodu nastaví 0 nebo 1 v LSB, jako read nebo write a podle toho se buď povolí příjem pomocí SSPCON2,RCEN nebo zápisem do SSPBUF se odešlou data. Pak jen počkat na ACK nebo odeslat ACK. Takže v tomhle problém nevidím.

A nejhorší je, že když čidlo přestane komunikovat, tak se zacyklí ve smyčce a je to v háji, ale když čidlo odpojím od 5V, tak se nezasukuje ve smyčce a ukazuje 0xFF. Kdyby aspoň při poruše neobsadil I2C komunikaci.

Hodím je do šuplíka a vrátím se zpět k SMT160-30, ten mi jede už 1/2 roku bez chybičky. :blush:

To co popisujes mi pripada, ako keby ten cip bol prudovo pretazovany.
Ak je to tak, potom by Ti mal pocas komunikacie ukazovat cim dalej tym vyssiu teplotu (do urcitej hodnoty) od okamihu zacatia komunikacie, lebo by sa postupne prehrieval velkym prudom.

Ak ti od odpalenia cipu dopomoze seriovy odpor s Ucc, to znamena, ze problem bude pri nastaveni log.1 na vystup, ako by isiel do skoro skratu.
Ak si dal do napajania 100ohm odpor, zmeraj na nom napatie. Spotreba by mala byt cca 200uA. Budes ale musiet pouzit bud osciloskop, alebo aspon merak merajuci maximalnu hodnotu, lebo ak to pretazovanie trva radovo desatiny milisekund, normalnym merakom nezmerias nic. Aspon cez diodu nabijaj kondik a na nom meraj napatie. Nebude to sice moc presne kvoli ubytku na diode, ale velke (aj ked kratke) prudove spicky by si tak mohol zachytit. Urcite tam daj ten transil, alebo aspon zenerovu diodu 5V1 (seriovy odpor aspon 10R). Neviem aky mas zdroj a ake mas dlhe kabliky od zdroja k senzoru, ale nevhodny zdroj (aj ked sa doteraz mohol zdat dostatocny) uz dopomohol do kalkulackoveho neba mnohym cipom.

Sprav este nasledujuci test. Senzor daj pod napatie nech normalne pracuje, ale SDA a SCL maj nepripojene. Nechaj ho tak 3-4 dni. Ak potom pojde, chyba bude urcite v pripojeni na I2C alebo v jej obsluhe.

A daj vediet, ako to dopadlo.

Martin

Odběr u 1 čidla je 230 uA, ve SLEEP modu 22 uA. u těch 2 mrtvol je 2,47 mA. Takže jsou asi určitě v pr… :blush: :blush:

Jinak to napajím zdrojem vlastní výroby, mám ho asi 1/2 roku, zatím jsem problém neměl. Napajím to 16V a na np mám stabilizátor 78T05. Napajím tím totiž ještě chladící ventilátor.

Teď čidlo napájím přes odpor, cca 1k a jede to 1 den v poho. Uvidím za týden. Jestli přežije kritické 4 dny, tak mám vyhráno. :smiley: :smiley:

jen takova blbost, ale co kdyby :slight_smile:
nevim sice jak I2C funguje u picu, ale mas datovej pin pri prijmu jako vstup?

Mám. :smiley: A když někdy jede a pak ne a když vyměním čidlo, tak zase jede. :smiley: :smiley: On si to PIC řidí sám, ale při inicializaci musí být SDA i SCL, tedy PORTC 3 a 4 jako IN.

To o tom ventilatore sa mi zda velmi zaujimave.

Pri vypinani indukcnost generuje zaporne impulzy bezpecne likvidujuce elektroniku. Preto sa k cievkam rele dava antiparalelne dioda (K na + a A na -). Ak tam das ten odpor, ten i s parazitnymi kapacitami tvori aku taku ochranu pre impulzami a nadprudom. Ak som volakedy ovladal 5V rele na doske s nejakou logikou, a rele boli bez diod, potom pri vypinani rele sa cela logika kompletne rozhodila. Stacilo dat tu diodu a vsetko bolo OK. Cievka pri vypinani zacne generovat za napajani zaporne napatie, lebo sa brani zmene, ktora na nej vznika.

Skratka DAJ na napajanie obvodu TU ZENERKU 5V1 a typujem, ze budes mat po probleme. Bacha aj s pripojovanim takeho niecoko k PC. Lahko mozes zapornymi impulzami zrusit paralelny port.

Raz som mal taky problem, ze som na transformator, z ktoreho som odoberat tak 30-50mA spravil usmernovat z 1N4148. Ved prudovo to bude stacit. Po prvom zapnuti zariadenie bez problemov pracovalo. Vsetko som ponastavoval a okalibroval. zariadenie som vypol a ulozil. Takto som nastavil cca 30 zariadeni. Po opatovnom zapnuti ani jedno nefungovalo, boli odidene tie 1N4148. Odisli pri vypnuti zdroja. Nastastie sa tam dali dat 1N4007 a tie uz nemaju ziaden problem.

Martin

ta dioda je dobrej napad :bulb: , akorat staci obyc usmernovaci paralelne k vetraku tak, aby byla v zavernym smeru… ZD je zbytecna…
Ovsem pokud je honzovo PWM a problem s I2C cidly v jednom zapojeni :wink: ale podle diskuzi mi to spis prijde, ze jsou to nesouvisejici problemy (PWM se nepripojuje pres 7805 :slight_smile: )

To je jasné, dioda 1N4148 je jen na 100V, kdežto 1N4007 je na 1000V proto ty napěťové špičky zvládne.

FAN a I2C je jedno zapojení, ale FAN se mi netočí pořád, jen když zahřeju čidlo zapalovačem. :smiley:

A s tou diodou je to dobrej nápad, úplně jsem ju zazdil. Tak a je tam osazená. Dík panu Anonymní

To jsem nějak nepochopil.

Tak tohle už se mi dlouho nestalo. Akorát jsem nějak nepochopil, co se stalo. Provedu šetření a uvidím.
19052008080.jpg
19052008077.jpg
19052008075.jpg