Fórum témák
» Több friss téma |
Fórum » PIC16F877 kommunikáció
Témaindító: kobela1969, idő: Aug 26, 2008
Témakörök:
én a windnill comdebug nevű terminál progival próbálkozok. találtam egy siemens m35 telót egy adatkábellel tökéletesen megy oda-vissza az at parancs-válasz.
biztos, hogy a pices dolog körül lesz a hiba. pic-ről telóra at parancs (pl sms küldés simán megy, visszafelé zavaros) most csak a pc-re kötöttem a panelt. ha két karaktert küldök, az jó. mivel 8 változóba írom az érkező karaktereket (ill "int" értékeit) az utolsó két változóba be is írja szépen. ha viszont több karakterrel próbálkozok, téveszt össze-vissza. hiába használom 19200 baud-hoz a SPBRG = 0x0C; RCSTA = 0x90; TXSTA = 0x24; dolgokat, olyan mintha csak két byte-ot fogadna.
A változók deklarációja rendben van ? Azt a részét még nem láttuk a proginak. Más nem használja ugyenezek a változókat ami bekavarhat?
ez a teljes alap progi:
int fogadott1; int fogadott2; int fogadott3; int fogadott4; int fogadott5; int fogadott6; int fogadott7; int fogadott8; void main(){ char rb2lab = 0; TRISB = 0xFF; TRISD = 0; PORTD = 0x0F; USART_Init(19200); SPBRG = 0x0C; RCSTA = 0x90; TXSTA = 0x24; do { if(USART_Data_Ready()) { // ha adat erkezik fogadott1=fogadott2; fogadott2=fogadott3; fogadott3=fogadott4; fogadott4=fogadott5; fogadott5=fogadott6; fogadott6=fogadott7; fogadott7=fogadott8; fogadott8=USART_Read(); // erkezo adatok beolvasasa } if (Button(&PORTB, 2, 1, 1)) rb2lab = 1; if (rb2lab && Button(&PORTB, 2, 1, 0)) { USART_WRITE(fogadott1); USART_WRITE(fogadott2); USART_WRITE(fogadott3); USART_WRITE(fogadott4); USART_WRITE(fogadott5); USART_WRITE(fogadott6); USART_WRITE(fogadott7); USART_WRITE(fogadott8); PORTD = ~PORTD; rb2lab = 0; delay_ms(500); PORTD = ~PORTD; delay_ms(50); } } while(1); }
hmm. Nemtudom nem lehet e gond hogy int-et használsz unsigned char helyett egy byte tárolására. Hitechben az int az 16 bites.
kipróbáltam, sajnos nem jó.
mellékelem a kapott dolgokat.
érdekes, hogy ha csak két karaktert küldök, akkor szépen
feltölti a 8 változót 4 küldés után.
még arra tudok tippelni hogy az lehet a gond, hogy túl sokáig pakolászod az adatokat, és eközben új karakter érkezik. Ezért is jobb a sztring/karakter tömb, mert ott egy változóval nyilvántartva, mindig a szöveg végére írhatsz.
Próbáld ki esetleg, hogy ha jön 1 karakter, azonnal küldd vissza. szerk: most látom hogy van mikor 500ms re "megáll" a program, lehet hogy épp akkor már jönne adat. Szóval ezt nem így szokták megoldani, hanem irq-val. Ha jön adat, akkor megszakitasbol azonnal le kell kezelni.
köszi, értem
nem vagyok egy c guru, de megpróbálom sztringbe tenni a karaktereket és azt vizsgálni, küldeni stb.. az 500ms csak egy led villogtatás miatt van, hogy lássam, hogy küldött. addig nem küldök a pic-nek (most csak pc-vel van összekötve) szóval kipróbáltam először: if(USART_Data_Ready()) { // ha adat erkezik i=USART_Read(); Usart_write(i); } két byte-ot ha küldök az még jó, de három vagy többel már nem.
Úgy, ahogy lidi mondja megszakításból kellene az adatokat beolvasni.
Kb, így lehetne megoldani a megszakítást:
Ez ccs-ben van, de lényeg és az elv látható ! 4 db bájtot vesz, amit tömbben tárol. Ha a 4 bájtot levette ellenőrzi is, hogy megegyezik-e azzal amit vártunk. Az egyezést egy flaggel jelezzük a főprogramnak. Hasonlóan megoldva használok RF modulokat.
Bár én csak 16F62x-el csináltam UART-ot, ráadásul ASM-ben, de ott alapvetőleg arra kellett figyelni, hogy csak 1 byte-os a buffer. Tehát 1 adatot tud hardveresen tárolni, 1-et fogadni. Ez összesen 2. Ha nincs ürítve a 3. byte fogadása előtt a buffer (nem olvasol ki), akkor gubanc van. Épp ezért kell megszakításra bízni a dolgot, ami az adat beérkezésekor a legrövidebb idő alatt menti a buffer tartalmát.
Hali
Ahogy lentebb írtam, fontos az órajel. 4000000Hz-n megy a cucc 4000000/16/19200=13,0208 -1=>12 a hiba: 13,028->0,0208 1 teljes órajelnyi eltolódás: 1/0,0208=48 Azaz minden 48. órajel után elcsúszik 1 órajellel. Egy adat áll: 1 startbit, 8 adatbit, 1 stopbit=10 bit Tehát a folyamatossan küldött adatoknál az 5. byte már hibás lehet. Ezért fontos a pontos órajel. De az adatfeldolgozás is fontos. Amikor jönnek be az adatok, közöttük gyorsan kell feldolgoznod/tárolnod, hogy a proci ne csússzon a következő feldolgozással. Ezt 2 féle képpen teheted meg, optimalizáltabb tárolás (pl asm,direkt tárolás) vagy az órajelet emeled 3686400 ról pl 1843200-ra (esetleg 4Mhz-ről 20Mhz-re) Direkt tárolásnál használd a regisztereket, meg az FSR-t.
Mellesleg én belső RC-ről működtetem a PIC-t, és soha nem hibázott, ezért szerintem nem a kvarc, hanem a programod rossz.
Sziasztok
Először vagyok ezen a fórumon, sokat tanultam ebből. Nem vagyok egy programozó guru, de úgy érzem minden segítséget megkaptam az USART kommunikációról, de főleg az órajelek, oscillátorok, ciklusidő a pic-nél témakörből. Szóval, úgy érzem a többi már rajtam múlik ! Köszenet mindenkinek aki segíteni próbált ! Pontot pici-nek adom, úgy érzem.
Köszi, bár nem ezért...
ASM-ben tudsz programozni?
akkor most neked sikerult megoldani?
megyen? es a Q volt a hiba vagy a program esetleg mindketto?
nem tartozik szorosan a témához de sokkal jobban jártál volna 18f akármi procival. árban ugyanott vagy jobb és sokkal egyszerűbben használható, főleg ha c-ben akarod programozni. regrads,
Igen, engem is érdekelne hogy mi lett végül a megoldás. Bár nekem nincs gondom az usart-tal, de még lehet
![]()
szia
assembly lenne a legalkalmasabb ilyen tipusú feladatokra, tudom, de nem mélyültem el benne. valamikor régen foglalkoztam Allen-Bradley PLC proc utasításkészletével, ott volt szükség nagyon asm-re. talán később rá fogok kényszerülni...
szia
pici és MPi.c válaszából kiderült, hogy két probléma is van ezzel kapcsolatosan: - az órajel pontossága és nagysága (be fogok szerezni kvarcokat) - a rutinom is sánta ill. nem jó az elv sem ahogyan nekikezdtem (nem elég gyors az adatfeldolgozás, tárolás) Dolgozom tovább a dolgon, kipróbálom pontos kvarccal és át kell írnom a progit is. msn címem megírtam, és a fórumokon is tallózgatok.
Szerintem:
1, a megszakítás nem oldja meg a lassú feldolgozás problémáját. Megszakításban is ugyan annyi ideig tart az a fajta megoldás + a push-pop is idő. De a megszakítás használata a célszerű, mert akkor mást is lehet közben csinálni. 2, a 4 karakter beolvasása nagyon specifikus, de nem csak ezt kellene csinálni, hiszen nem az a végleges cél, hogy a RING adatot felismerje, hanem a többi bejövőt is (pl telszám) Ezért érdemes bufferelni, amíg nem kap sorvégjelet. 0x0D 0x0A, ekkor már fel lehet dolgozni az adatokat. De figyelni kell a buffer hosszát, ne szaladjon az adatokra (overflow) lehet másik bankot használni erre. Amíg nincs vége, nincs értelme ellenőrizni, csak idő megy el vele. Ha megjött a végjel, akkor lehet a buffert egyesével ellenőrizni és feldolgozni. Ez a tárolás magja: intben: ... RX: movfw bufhead ;bufferpointer movwf FSR movfw RCREG ;RX movwf INDF decf bufhead ;lefele töltjük adatokat xorlw 0x0A ;sorvége? btfsc STATUS,Z call feldolgozas ... feldolgozas: ... movwl 0x7F movfw bufhead ... inicializáláskor: ... movwl 0x7F movfw bufhead ... Ezen természetesen változtatni kell a feladat igényeinek megfelelően. sztm
Üdv!
Az Interruptos megoldást valahogy így csinálnám meg, néhány dolgot nem írok le részletesen: (Pascal-ban programozok, de szerintem értheto lesz) Program Usart_Rx Const max = 8 //8 karaktert varok beolvasasra Var OK : boolean //logikai valtozo, hogy megjott-e az osszes RX : array[1..8] of boolean //tomb amiben taroljuk a fogadott adatot i : byte //segedvaltozo Procedure Interrupt Begin RX[ i ]:=Usart_Read If i=max then Begin Ok:=1 //megjott az osszes adat i:=1 end else Inc[ i ] end Begin OK:=0 i:=1 Interrupt konfiguralasa While True do Begin Repeat Until Ok . . //RX tombon vegezhetunk muveleteket . OK:=0 end end Celszeru meg egy tombot hasznalni, majd ha az OK valtozo logikai 1 lesz, abba atmasolni a bajtokat, es azon vegezni a muveleteket.
Üdv!
Mellékelek egy rövid c-ben (CCS) írt példa kódot. A program ellenőrzi a mobil jelenlétét és annak eredményét az RB0-RB1 portokra kapcsolt LED-ekkel jelzi. Amennyiben a programban megadott hívószámú készülékről hívás érkezik (a hívónak küldenie kell a telefonszámot) az RB2-RB3 kimenetek állapota ellenkezőjére vált. Minden bejövő hívás után - függetlenül az azonosítástól - a hívást bontja. A program egy változata 18F1320-as PIC-en működik. 16F877A-ra átírva, magyarázatokkal próbáltam érthetővé tenni, hátha valakiben gondolatokat ébreszt… Hangsúlyozom, hogy példa, áramkörben ezt a változatot nem próbáltam ki.
Sziasztok. Segítség kellene PIC16F887 i2c modul beüzemeléséhez.
EEpromba (24c64) szeretnék 1 bájtot beleírni, de valamiért nem sikerül. Valaki hozzáértő légyszives nézze meg mi lehet a gond. Köszi, STR.
Az EEPROM cime 0xA0-nal kezdodik (az A0-A2 labakkal lehet programozni 8 EEPROM-ot). A Te programod 0x00 cimmel akar kommunikalni, es ezert az EEPROM nem valaszol neki.
Szerintem valami más gond lehet mert a programban (real pic sim) az eeprom címe 0000 000 + 0 rw bit.
Megnéztem 2 szimulátorban is (a másik a pic sim ide) és mind a kettő azt írja hogy csak egy stop megy ki, pedig adatlap szerint az sspcon2,sen startot generál. Utána valamiért meg is áll a program mert a végén a led sem kapcsol be.
De a 24C64 cime 0xA0-nal kezdodik, tehat egy 0x00 cimu hivast nem fog figyelembe venni sohasem.
A szimulator nem tudja kezelni jol a I2C HW-t (sajnos).
Értem.
Tehát akkor így helyesen kellene működnie? (a0 a1 a2 fölre húzva) I2CByteWrite call I2CBSTART ; start i2c movlw 0xA0; cím, rw bit 0 call I2CTX ; küldés ;---------------- Kijavítottam de a próbapanelen nem csinál semmit, (nem kapcsol be a led) szimulátorban ezek szerint nincs értelme próbálgatni.
Szia!
Talán így... Az SDA és SCL vonalakra 2k7 felhúzó ellenállás kell a pic +5V -jához, különben soha nem lesz stop kondíció a buszon. Az SCL és SDA vonalak nyitott kollektorosak, mérni csak nagyimpedanciás bemenettel lehet. A PICKit2 logikai analizátora (kiegészítés nélkül) nem jó, mert két bemenetén 4k7 földre húzó ellenállás van. A furaszerelt klón cikjében található egy buffer kártya terve (100k .. 1M bemeneti lehúzó ellenállás kell bele).
Köszönöm az eddigi segítséget, szoftveres megoldással már sikerült adatot írnom az eepromba, de a hardveres az sehogy sem akar működni. Kötöttem ledeket RC3, RC4 lábakra, villogtatni lehet őket róla. Ez mellett lehet h tönkretettem a hardware-t és azért nem működik az i2c?
Eddig erre jutottam, gondoltam megosztom veletek.
Mind a 2 asm rendben működik 24c64-es eeprommal. Építő kritikát szivesen fogadok. |
Bejelentkezés
Hirdetés |