Fórum témák

» Több friss téma
Fórum » PIC - Miértek, hogyanok haladóknak
Lapozás: OK   1073 / 1320
(#) icserny válasza reechee88 hozzászólására (») Máj 26, 2012 /
 
Melyik a master, melyik a slave? Hogy néz ki a programod?
(#) reechee88 válasza icserny hozzászólására (») Máj 26, 2012 /
 
pic18 a master, pic24 a slave.

pic18 master code:
  1. i2c_testing
  2.  
  3.        call         i2c_start_communication
  4.  
  5.        movlw    b'00100000'; slave address with write option
  6.        call         i2c_choose_slave
  7.  
  8.        movlw    12
  9.        call          i2c_send_data
  10.  
  11. ;movlw23
  12. ;calli2c_send_data
  13.  
  14.       call           i2c_stop_communication
  15.       call           i2c_start_communication
  16.  
  17.       movlw      b'00100001'; slave address with read option
  18.       call           i2c_choose_slave
  19.  
  20. ; wait for answer
  21.  
  22.       bsf           SSPCON2,RCEN
  23.  
  24. wait_for_bf
  25.      btfsc         SSPSTAT,BF
  26.      bra           wait_for_bf
  27.  
  28.      call           waitMSSP   ; wait for SSPIF
  29.  
  30.      movff        SSPBUF,i2c_teszt1
  31.  
  32.      call           i2c_stop_communication
  33.  
  34.      bcf           INTCON,1
  35.  
  36. return


PIC24 slave code:
  1. void __attribute__((interrupt)) _SI2C1Interrupt(void){
  2.  
  3. data[i] = I2C1RCV;
  4.  
  5. if(_R_W && (!I2C1CONbits.SCLREL))
  6. i2c_send_data(d1);
  7.  
  8. IFS1bits.SI2C1IF = 0;
  9.  
  10. i++;
  11.  
  12. }
  13.  
  14. void i2c_send_data(char byte[]){
  15. IEC1bits.SI2C1IE = 0;
  16.  
  17. I2C1TRN = 5;
  18.     I2C1CONbits.SCLREL = 1;
  19.  
  20.  while(I2C1STATbits.TBF);
  21.  
  22. IEC1bits.SI2C1IE = 1;
  23. }
(#) icserny válasza reechee88 hozzászólására (») Máj 26, 2012 / 1
 
A PIC18 program elég hiányos, így nem tudom megállapítani, hogy mi a hiba benne.

A PIC24 program egy kicsit túlbonyolítottnak tűnik. Miért piszkálod az I2C megszakítás engedélyezését? Tudtommal adatküldéshez csak két utasítás kell:
  1. I2C1TRN = adat;  
  2. I2C1CONbits.SCLREL = 1;
Várakozást pedig semmiképp se tegyél a megszakítást kiszolgáló részbe!

A PICula projektem letölthető támogatói könyvtárában az include/picula_i2c.h és common/picula_i2c.c állományokat nézd meg! Különösen az i2c_init(), i2c_getc(), i2c_putc() függvényeket és az i2c_idle() makrót nézd meg!

PIC24-hez pedig a PICkwik projekt letölthető mintapéldái közül a chap13 mappában található i2c_slave_reverse_string.c programot ajánlom figyelmedbe.
(#) _vl_ válasza reechee88 hozzászólására (») Máj 26, 2012 /
 
Annyi mondjuk ennyiből is látszik, hogy a master nagy ívben tojik rá, hogy a slave küldött-e ACK-t, vagy sem, csak tolja a következő byte-ot...
Az ACK ellenőrzése nélkül abban sem lehetsz biztos, hogy a slave egyáltalán képes 0-ra húzni a két vonalat.
(#) reechee88 válasza icserny hozzászólására (») Máj 26, 2012 /
 
A PIC18-as kódban a 20.-ig sorig tökéletesen lefut, azaz az adat jelentkezik a PIC24 oldalán. Ezért nem másoltam be az összes subroutin kódot, úgy kicsit átláthatatlan lenne.

Csak a biztonság kedvéért tiltottam le a megszakítást. De az valóban nem való oda, csak teszt jelleggel írtam bele.

Melyik oldalon valószínűbb a hiba?

Nekem úgy tűnik, mintha az egyik hamarabb letudná a dolgot és vagy már átjött az üzenet és nem figyelte a pic18, vagy már nem figyeli és csak akkor küldi a pic24.
(#) reechee88 válasza _vl_ hozzászólására (») Máj 26, 2012 /
 
A send_data subrutin figyeli az ACK jelet. Az persze itt nem látszik, de egyébként figyelembe vettem és átjön a slave-től.
(#) icserny válasza reechee88 hozzászólására (») Máj 26, 2012 /
 
Idézet:
„A send_data subrutin figyeli az ACK jelet.”
Az alábbi sor nem tudom, hogy mire kell:
  1. call           waitMSSP   ; wait for SSPIF
,
de vagy ott, vagy a buffer kiolvasás után a masternek küldenie kellene egy NAK jelet a slave-nek, mielőtt stop-pal befejezed a tranzakciót.
(#) reechee88 válasza icserny hozzászólására (») Máj 26, 2012 /
 
  1. i2c_read_data
  2.  
  3. wait_for_bf
  4. btfsc SSPSTAT,BF
  5. bra        wait_for_bf
  6.  
  7. movf        SSPBUF,w
  8.  
  9. bsf        SSPCON2,ACKSTAT
  10. bsf        SSPCON2,ACKEN
  11.  
  12. return


Most így néz ki a subrutin. Visszaolvassa azt amit előtte beírt önmagának a master. Semmi nem jön a slave oldaláról. Egyébként a "call waitMSSP" az azért kellett mert az SSPIF is beállítódik amint megtelik a buffer és én azt vettem figyelembe. De egyébként sehogysem működik, nem kap semmit a slave oldaláról.
(#) vilmosd válasza reechee88 hozzászólására (») Máj 26, 2012 / 1
 
Nezd csak mit talaltam. A Philips I2C leiras magyaritasa.

i2c_hu.pdf
    
(#) reechee88 hozzászólása Máj 26, 2012 /
 
Köszi szépen, átolvasom mindjárt. De volt 1 hiba a master kódjában, nem megfelelően nézte az ACKSTAT bitet. Nem jön válasz a slave oldaláról ACK formájában sem. Valószínűleg nem tudja lehúzni a vonalat. Ilyenkor hardveresen van hiba? Mit lehet ilyenkor tenni?
(#) icserny válasza reechee88 hozzászólására (») Máj 27, 2012 /
 
Idézet:
„Mit lehet ilyenkor tenni?”
Pl. megmutatod, hogy hogyan inicializáltad az I2C alegységet és a megszakítási rendszert a PIC24-nél.
(#) reechee88 válasza icserny hozzászólására (») Máj 27, 2012 /
 
Pic24 inic:

  1. void i2c_init(void){
  2. I2C1CONbits.I2CEN = 1;// enable i2c
  3. I2C1CONbits.A10M = 0;// I2CxADD is a 7-bit slave addres
  4. I2C1CONbits.GCEN = 1;// enable global interrupt for I2C
  5. I2C1CONbits.DISSLW = 1; // Disable Slew Rate
  6. //I2C1CONbits.STREN = 1;
  7.  
  8. I2C1BRG = 78;// desired baud rate (100khz) at 8 mhz
  9.  
  10. I2C1MSK = 0x00FF;// Slave Masking
  11.  
  12. I2C1ADD = 0x0020;// Set Slave Address
  13.  
  14. IEC1bits.SI2C1IE = 1; // Slave I2C1 Event Interrupt Enable bit
  15. }


Pic24 interrupt:

  1. void __attribute__((interrupt)) _SI2C1Interrupt(void){
  2.  
  3. data[i] = I2C1RCV;
  4.  
  5.   //if(I2C1STATbits.R_W && !I2C1CONbits.SCLREL)    // R/W
  6.   //{
  7. //i2c_send_data(d1);
  8.   //}
  9.  
  10. if(_R_W && (!I2C1CONbits.SCLREL))
  11. i2c_send_data(d1);
  12.  
  13. IFS1bits.SI2C1IF = 0;
  14.  
  15. i++;
  16.  
  17. }
(#) Programmer válasza reechee88 hozzászólására (») Máj 27, 2012 /
 
Én értem, hogy az assembly programozás/regiszterek direkt kezelése szép feladat vagy kihívás, de nem célravezető. Nem kell feltalálni a kereket, meg különféle makrókat saját magunknak definiálni, ezt megtette már a Microchip.
Jogosan tevődik fel a kérdés: miért nem használod ezeket? Amennyiben a tanulás a cél, úgy értem, de ha szeretnél valami biztosat, a leggyorsabb módja ha használod a fordítóhoz mellékelt könyvtárakat..
(#) reechee88 válasza Programmer hozzászólására (») Máj 27, 2012 /
 
Bár a projekt konkrét, de 2 hónapja még abszolút kezdő voltam. Akkor assembly-vel kezdtem, mert szerettem volna mindent megérteni. Most már sok munka lenne átírni az egészet C-be, de a pic24-re már abban fejlesztem tovább.
(#) reechee88 hozzászólása Máj 27, 2012 /
 
Sikerült megoldani a problémát! A pic24 konfigurációs beállításaiban volt a hiba. Köszönöm a segítséget mindenkinek!
(#) icserny válasza reechee88 hozzászólására (») Máj 27, 2012 /
 
Idézet:
„A pic24 konfigurációs beállításaiban volt a hiba.”

I2C1ADD = 0x0020; helyett I2C1ADD = 0x0010; kellett?
(#) reechee88 hozzászólása Máj 27, 2012 /
 
  1. _CONFIG2( IESO_OFF & FNOSC_FRC & FCKSM_CSDCMD & OSCIOFNC_ON & POSCMOD_NONE & I2C1SEL_PRI & IESO_OFF & I2C1SEL_PRI)


I2C1SEL_PRI

Kiemeltem, amit hozzátettem a konfig beállításokhoz. Nem néztem utána mit jelent, de így működik tökéletesen.
(#) _vl_ válasza icserny hozzászólására (») Máj 27, 2012 /
 
Mivel kimaszkolja a MASK = 0xff-el, így gyakorlatilag mindegy mit ír az addresshez
(#) Panzer576 hozzászólása Máj 28, 2012 /
 
Sziasztok!
Szeretném megkérdezni, foglalkozott e valaki a CVfer feszültséggel PIC16F887-esen?
Elvileg RA2-n kelleni kijönnie, de sajnos nem jelenik meg...
A konfigurációm: ansel,2=1 trisa,2=1 vrcon= B'11100000'

Ha valaki tudja mit hagytam ki help pls!
Köszi:
Panzer
(#) Hp41C válasza Panzer576 hozzászólására (») Máj 28, 2012 /
 
Szia!
A VRCON -ba olyan értéket írj, aminek az alsó 4 bitjén nem csak 0 van.
Ha jó bankokban állítottad az ANSEL és TRISA regisztereket, akkor már csak egy probláma lehet: A külső terhelés túl nagy.
(#) watt válasza Panzer576 hozzászólására (») Máj 28, 2012 /
 
ADCON1 / VCFG1 tartozik még ide a folyamatábra szerint.
(#) _vl_ válasza Panzer576 hozzászólására (») Máj 28, 2012 /
 
Nekem megy
Ezek vannak nálam beállítva (nem biztos, hogy mind kell, de ami releváns lehet, azt beírtam):

  1. ANSEL = 0x05;             // AN0 ADC input, AN2/ACVref analog output
  2. TRISA = 0x37;             // AN0, AN2/CVref digital tri-state
  3. ADCON0 = 0x81;          // ADCS=Fosc/32, AN0, ADON=1
  4. ADCON1 = 0x80;          // ADFM=1 (RJ), VCFG=0/0 (Vss/Vdd)
  5. VRCON = 0xe0 | value;  // value: 0..15
(#) Panzer576 válasza _vl_ hozzászólására (») Máj 28, 2012 /
 
Értem!
Nekem majdnem ugyan ez a beállításom:
ANSEL = 0x06;
TRISA = 0x0e;
ADCON0 = 0x85;
ADCON1 = 0x90;
VRCON = 0xe0

csak annyi,hogy én az adc-t külső ref-hez mérem, és a CVref is ennek a függvénye!
A terhelhetősége tudom, hogy kicsi, ezért egy 1x-es műveleti erősítő van rajta, és onnan viszem tovább.
(#) Panzer576 válasza Panzer576 hozzászólására (») Máj 28, 2012 /
 
Megvan a hiba!
A 10-s analóg csatornán állítottam be mérést, de az eszköz a 12-esre van kötve... XD
Minél régebb óta csinálom, annál pitiánerebb dolgokkal szivatom magam!

Köszi azért!
(#) Dave87 hozzászólása Máj 28, 2012 /
 
Sziasztok!
Végső elkeseredésemben írok, mert egyszerűen nem tudok rájönni, mit csinálok rosszul a programomban. Találtam a fórumban egy pic-es lakásriasztó kapcsolást amit megépítettem, úgy gondoltam saját programot írok hozzá, ami részben el is készült, de szeretném tovább fejleszteni szerviz menüvel, pin kód változtatás lehetőséggel, stb. A gond itt kezdődik, ugyanis ha megírom a program ezen részét, egyszerűen nem indul el szimulációban (persze a valóságban sem) Mellékeltem a teljes forráskódot (pascalban írtam) ha valakinek van ideje legyen szíves nézzen bele, mert én teljesen tanácstalan vagyok most már. Köszönöm előre is a segítséget!

Alarm 1.mpas
    
(#) Programmer válasza Dave87 hozzászólására (») Máj 28, 2012 /
 
Első ránézésre túl sok a kód, hogy ki lehessen hámozni a logikát belőle.. Egy tipp(én így szoktam): minden if nél adj meg egy matematikai műveletet, ne hagy hogy a fordító vagy az adattípusok különböző meghatározásai miatt elcsússzanak a feltételek.
Pl:
if not statusbit then ...
helyette:
if (statusbit=0) then ...
Nem állítom, hogy ez a hiba de az átláthatóság kedvéért mindenképp itt kezdeném a javítást...
(#) Dave87 válasza Programmer hozzászólására (») Máj 28, 2012 /
 
Köszönöm a választ, javítottam amit ajánlottál, egyelőre semmi változás. Annyi plusz infóm van még, hogy a szimulációban (ISIS) pörögnek a hibák felváltva ez a kettő:
0x00D3 - Stack underflow executing RETURN instruction
0x00A3 - Stack overflow executing CALL instruction
(#) Programmer válasza Dave87 hozzászólására (») Máj 28, 2012 /
 
Ez bizony elég csúnya.. Megtelik a veremtár, aminek két fő oka lehet: vagy túl kicsire lett beállítva, vagy a programban valahol szerepel egy rekúrzív függvényhívás.
Ellenőrizd a beállításoknál mekkora a verem (stack size).
A megszakítás kezelésében:
TMR1IE_bit := 1;
TMR1IF_bit := 0;
A második sor gondolom az interrupt flag törlése, de az első? Az engedélyező bit? Szerintem azt nem kell kapcsolgatni minden megszakításnál(?)
(#) Dave87 válasza Programmer hozzászólására (») Máj 28, 2012 /
 
TMR1IE valóban nem szükséges, törölve. Amennyiben a főprogramból kihagyom a "armtmch: ..." (464. sor) illetve "baltmch: ..." (496. sor) részt a program hibátlanul fut. Hülye kérdés, de lehet probléma az, ha egy változó "túl sokszor" kap (más-más) értéket a programban? Gondolok itt pl a sor2-re például... a stack dolognak holnap utánanézek meló után, köszönöm az eddigi segítséged is!
(#) Programmer válasza Dave87 hozzászólására (») Máj 28, 2012 /
 
Itt is látok egy valószínű problémát:
const _service = 1;
_monitor = 2;
_arming = 3;
_armed = 4;
_alarm = 5;

chpin = 1;
armtmch = 2;
baltmch = 3;
altmch = 4;
Ezek a szimbólumok a case elágazás lehetséges értékei. Nem emlékszem pontosan a Pascal hogyan kezeli ha egy case-ben több blokk szerepel ugyanazon értékre. Ugyanis lefordítva nálad ez történik. Ez szerintem nem jó így. A chpin től nem kéne újrakezdeni a számozást hanem folytatni (6, 7 stb).
case mode of
1: begin end;
2: begin end;
....................
1: begin end;
....................
end;
Nálad valami ilyesmi van jelen. Lehet, hogy ez teljesen fejreállítja a program futását, lehet nincs akkora hatása de akkor is ki kéne javítani s csak utána tovább lépni.
Következő: »»   1073 / 1320
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem