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:
Lapozás: OK   2 / 3
(#) kobela1969 válasza MPi-c hozzászólására (») Aug 27, 2008 /
 
é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.
(#) lidi válasza kobela1969 hozzászólására (») Aug 27, 2008 /
 
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?
(#) kobela1969 válasza lidi hozzászólására (») Aug 27, 2008 /
 
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);
}

(#) lidi válasza kobela1969 hozzászólására (») Aug 27, 2008 /
 
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.
(#) kobela1969 válasza lidi hozzászólására (») Aug 27, 2008 /
 
kipróbáltam, sajnos nem jó.
mellékelem a kapott dolgokat.
(#) kobela1969 válasza lidi hozzászólására (») Aug 27, 2008 /
 
é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.

2byte_tal.JPG
    
(#) lidi válasza kobela1969 hozzászólására (») Aug 27, 2008 /
 
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.
(#) kobela1969 válasza lidi hozzászólására (») Aug 27, 2008 /
 
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.
(#) MPi-c válasza kobela1969 hozzászólására (») Aug 27, 2008 / 4
 
Úgy, ahogy lidi mondja megszakításból kellene az adatokat beolvasni.
Kb, így lehetne megoldani a megszakítást:
  1. #int_RDA        //UART vétel megszakítás
  2. void RDA_isr()
  3. {
  4.   char ertek;
  5.   static int RXMod;
  6.   static char vett_adat[9];
  7.   char *RING = "RING";
  8.                
  9.   ertek = getc();
  10.        
  11.   switch (RXMod)
  12.   {
  13.     case 0:    
  14.             if(ertek == 'R')
  15.             {
  16.               vett_adat[0] = ertek;
  17.               RXMod = 1;
  18.             }
  19.             break;
  20.     case 1:
  21.     case 2:
  22.     case 3:
  23.             vett_adat[RXmod] = ertek;
  24.             RXmod++;
  25.             if(RXmod == 4)
  26.             {
  27.               RXmod = 0;
  28.               if(strcmp(RING, vett_adat))
  29.               {
  30.                 flag_ring = 1;
  31.               }        
  32.             }  
  33.             break;
  34.     default: RXMod = 0;
  35.   }
  36. }


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.
(#) szdavid válasza kobela1969 hozzászólására (») Aug 27, 2008 /
 
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.
(#) pici hozzászólása Aug 27, 2008 / 4
 
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.


(#) szdavid válasza szdavid hozzászólására (») Aug 27, 2008 /
 
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.
(#) kobela1969 válasza pici hozzászólására (») Aug 27, 2008 /
 
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.
(#) pici válasza kobela1969 hozzászólására (») Aug 27, 2008 /
 
Köszi, bár nem ezért...
ASM-ben tudsz programozni?
(#) accesid válasza pici hozzászólására (») Aug 27, 2008 /
 
akkor most neked sikerult megoldani?

megyen?

es a Q volt a hiba vagy a program esetleg mindketto?
(#) cua válasza kobela1969 hozzászólására (») Aug 27, 2008 /
 

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,

(#) lidi válasza accesid hozzászólására (») Aug 28, 2008 /
 
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
(#) kobela1969 válasza pici hozzászólására (») Aug 28, 2008 /
 
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...
(#) kobela1969 válasza accesid hozzászólására (») Aug 28, 2008 /
 
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.
(#) pici válasza kobela1969 hozzászólására (») Aug 28, 2008 /
 
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
(#) pako hozzászólása Aug 28, 2008 /
 
Ü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.
(#) MPi-c hozzászólása Dec 8, 2008 /
 
Ü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.

main.c
    
(#) Strons hozzászólása Aug 15, 2012 /
 
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.

i2c.txt
    
(#) vilmosd válasza Strons hozzászólására (») Aug 15, 2012 /
 
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.
(#) Strons válasza vilmosd hozzászólására (») Aug 15, 2012 /
 
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.
(#) vilmosd válasza Strons hozzászólására (») Aug 15, 2012 /
 
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).
(#) Strons hozzászólása Aug 15, 2012 /
 
É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.
(#) Hp41C válasza Strons hozzászólására (») Aug 15, 2012 /
 
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).
(#) Strons válasza Hp41C hozzászólására (») Aug 15, 2012 /
 
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?
(#) Strons hozzászólása Aug 15, 2012 /
 
Eddig erre jutottam, gondoltam megosztom veletek.
Mind a 2 asm rendben működik 24c64-es eeprommal.

Építő kritikát szivesen fogadok.
Következő: »»   2 / 3
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