Fórum témák

» Több friss téma
Fórum » CCS PIC Compiler
 
Témaindító: (Felhasználó 1542), idő: Ápr 3, 2006
Lapozás: OK   17 / 118
(#) trudnai válasza whalaky hozzászólására (») Jan 6, 2009 /
 
Idézet:
„A hiba az volt, hogy az összes sorosporton érkező utasítást egyetlen függvénnyel akartam lekezelni, és az kinőtte a szegmens lehetséges méretét.”


Valoszinuleg linker scriptet kellene heggesztened ahhoz, hogy elkeruld a problemat - es ne megkeruld
(#) Ven hozzászólása Jan 8, 2009 /
 
Sziasztok!
30F4013-as dsPIC-cel szívok, azon belül is I2C-vel. Egy 24c04-es EEPROM a cél, amelynek lábai így vannak bekötve:1-GND,2-3-Vcc,4-GND,5-F2,6-F3,7-8-Vcc
SDA és SCL 4.7kOhm-os ellenállással a Vcc-re felhúzva.
Mindössze egy darab byte-ot akarok beírni és azt kiolvasni és kiküldeni RS232-re.
#use rs232(UART2,baud=9600,parity=N,bits=8)
#use i2c(Master, Slow, sda=PIN_F2, scl=PIN_F3, force_hw)
.
.
while(1)
{
printf("OK!\n\t");
delay_ms(100);
i2c_start();
i2c_write(0b10101100); // Device address
i2c_write(1); // Byte address
i2c_write(3); //data
i2c_stop();
delay_ms(100);
output_bit(PIN_D2,k);
k=!k;
i2c_start(); // Restart
i2c_write(0b10101100);
i2c_write(1); // Byte address
i2c_start();
i2c_write(0b10101101);
ertek=i2c_read(); // Now read from slave
i2c_stop();
printf("ertek=%d ", ertek);
ertek=99;
}
Ezek a sorok nem akarnak működni. Kétfajta hibajelenség van, attól függően hova adom meg az I2C lábait (gondolom, mikor HW-ben, vagy SW-ben használja az I2C-t). Az első, mikor leírtak szerint van minden, a soros porton -1 -et olvasok ki az ertek változóra. Mondjuk akkor is azt olvasok, ha lehúzom a buszról az EEPROM-ot. HW hiba lenne? Átnéztem már 100-szor legalább. Talán a 24c nincs jól bekötve? Szerintetek?
(#) ccs válasza Ven hozzászólására (») Jan 8, 2009 /
 
Lehet, hogy hülyeséget mondok, de ha így kötöd, be ?
PIC EEPROM
--- A0 (1) GND
--- A1 (2) GND
--- A2 (3) GND
--- VSS(4) GND
PIN_F2 --- SDA(5) 2.2k +5V-ra
PIN_F3 --- SCL(6) 2.2k +5V-ra
--- WP (7) GND
--- VCC(8) +5V

A programrészletedben PIN_D2 a kimeneted, elöl viszont a PIN_F2-3-at adod meg...
(#) icserny válasza Ven hozzászólására (») Jan 8, 2009 /
 
Az adatlap szerint a 24c04 nem használja az a2,a1,a0 címvezetékeket. Viszont 512 bájtos, tehát legfelső címbitet az első bájban kell kiküldeni.

A cím első bájtja ennek megfelelően:

Bináriasan: |1 | 0| 1 | 0 | 0 | 0 | b8 | r/w|

ahol b8 a legmagasabb helyiértékű címbit,
r/w pedig az olvasás/írás bit.

Mintaprogramot is találsz hozzá a CCS-ben: PICC/Drivers/2404.c
(#) icserny válasza ccs hozzászólására (») Jan 8, 2009 /
 
Idézet:
„A programrészletedben PIN_D2 a kimeneted”

Azzal szerintem csak jelezni próbálta a működést...
(#) MPi-c válasza Ven hozzászólására (») Jan 8, 2009 /
 
Szerintem:
ertek=i2c_read(0);
kell a kiolvasásnál.
A PICC/Drivers mappában vannak egyes eszközökre kezelő rutinok. (Ahogy azt icserny is írta )
(#) Ven hozzászólása Jan 8, 2009 /
 
Sziasztok!
Megvan mindkét hiba, azt hiszem.
A HW-s I2C nem akar működni. Olyan szinten nem működik, hogy SDA vonal nem billeg (szókappal rámértem), ellentétben az SCL lábbal. Szerintem kipróbálok majd egy másik IC-t, mert valszeg elszállt az SDA láb.
Viszont SW I2C szépen sikerült. Amit nem igazán értek benne, hogy beáll a program, ha nem kap visszajelzést a slave-től. Köszönöm a hozzászólásokat és a segítséget...
(#) potyo válasza Ven hozzászólására (») Jan 8, 2009 /
 
Idézet:
„Amit nem igazán értek benne, hogy beáll a program, ha nem kap visszajelzést a slave-től.”


Valószínűleg a kész rutinban benne van, hogy várjon az ACK jelre. Aztán ha az nem jön, akkor bukott a dolog.

Írd újra azt a rutint várakozás nélkül.
(#) Ven válasza potyo hozzászólására (») Jan 8, 2009 /
 
Hát arra most nem vállalkoznék. Egyébként én is arra gondolok, hogy nem kap visszajelzést, ACK-t. Bár szerintem azt is le kéne kezelni. Szerencse a HW-s I2C-vel nincs ilyen probléma.
(#) Jossz hozzászólása Jan 17, 2009 /
 
Sziasztok!
Van-e valami ötletetek arra vonatkozóan, hogy hogyan lehet pontosan millisec-ben megmérni két esemény között eltelt időt külső óra IC használata nélkül? A feladat a következő: RF kommunikációban az adó kb 1500 ms-onként ad le egy karakter sorozatot. A vevő oldalán RDA megszakítással érzékeli, hogy érkezik jel az USART-ra, ha igen akkor ellenőrzi, hogy jó-e és a sorban beérkező jelekből összeállítja a karakter-sorozatot. Természetesen manchester kódolással dolgozom, de kíváncsi vagyok, hogy adott adásidő alatt hányszor jön be hiba nélkül a karakter sorozat. Ezért meg szereném mérni pontosan ms-ban, hogy két jó karakter sorozat kiírása között mennyi idő telik el. Így, ha pl. 10 percen keresztül figyelem a folyamatos adást, és feljegyzem egy változóban a min. és max. időértékeket, akkor már tudok arra következtetni, hogy milyen hibaaránnyal dolgozik a rendszer. Ezzel jó összehasonlítási alapom lesz, hogy ha pl. antennát módosítok, árnyékolom az elektronikát, stb. akkor rontottam, vagy javítottam a rendszeren. Tehát az alábbi programrészlet írja ki a hibátlan karakterkészletet és ebbe szeretném beépíteni az időmérést:
 
 while (TRUE) {
      restart_wdt();
      if (data_avail) {
         data_avail = FALSE;
         printf(lcd_putc,"\fAz adat beerkezett!\n");
         for (i = 0; i < 5; i++) {
            printf(lcd_putc,"%c",rx_buffer[i]);
         }
      }
   }

Fontos, hogy a szükséges mérhető időhatár legalább 3000 ms legyen.

Előre is köszi az ötleteket! >
(#) potyo válasza Jossz hozzászólására (») Jan 18, 2009 /
 
Fogsz egy timert, és a megfelelő pillanatokban elindítod és megállítod. Ez utasításciklusokban megmondja neked, hogy mennyi idő telt el. Ha túl gyorsan lefut, akkor kapcsold be az előosztót hozzá.
(#) icserny válasza potyo hozzászólására (») Jan 18, 2009 /
 
Szerintem egyszerűbb megoldás az, ha állandóan fut egy timer (pl. 20 milliszekundumonként interruptot ad), s az interruptkor növelget egy (több bájtos) számlálót.

A program pedig minden érvényes adat beérkezésekor kiolvassa az időszámláló (mint stopper) értékét, és nullázza.

Arra kell csak vigyázni, hogy a nullázás és a növelés ne gabalyodjon össze... (pl. a nullázás idejére le kell tiltani az interruptot)
(#) Jossz válasza icserny hozzászólására (») Jan 18, 2009 /
 
Köszönöm, kipróbálom mindkét ötletet...
(#) Jossz hozzászólása Feb 10, 2009 /
 
Sziasztok!

Most egy eléggé kemény problémám van, legalább is már 2 napja kínlódok vele. Egy drót nélküli alkalmazásban a soros portról olvasok be adatokat egy INT_RDA megszakítási rutin segítségével. Több külső egységet kérdezek le egyiket a másik után, úgy, hogy megszólítom a külső egységet, és várom a visszajelzését a mért értékkel. Erre vár az RDA rutin amelyben megnézem, hogy a megfelelő külső egység válaszolt-e, és ha igaen akkor a lenti kódban látható data_avail változónak igaz értéket adok és ezzel térek vissza a megszakításból. Persze közben egy sztring-tömbben feljegyzem a többi adatát.
Utána visszatérek az alábbi kódhoz:

while(cikl<=3) {

restart_wdt();
if (data_avail) {
data_avail = FALSE;
strncpy(szondakuld,rx_buffer,12);
cikl++;
}
}

A háromszori beolvasás az adatbiztonság miatt van. Eddig nincs is vele gondom, szépen csinálja. No, de mi van ha a hívott egység nem válaszol? akkor a végtelenségig várakoznom kell. Ezért úgy gondoltam, hogy a while ciklus kiértékelésbe berakok egy másik ciklusváltozót és szépen emelhgetem az értékét, ha nem jön adat és így egy idő után ki tudok lépni a ciklusból és hibajelzést tudok kiírni az illető egységhez. Valahogy így:

while(cikl<=3 && timeout<5000) {

restart_wdt();
if (data_avail) {
data_avail = FALSE;
strncpy(szondakuld,rx_buffer,12);
cikl++;
}
else {
timeout++;
}
}


De sajnos ez a dolog nem működik, ugyanis a timeout változó valamiért a legelső pillanatban felveszi a max. értékét, tehát az 5000-et és már tovább is lépett a program, ki a ciklusból, tehát innentől kezdve akkor sem olvas be, ha egyébként lenne külső válasz.
Mi lehet az oka, vagy mi módon leget ezt megcsinálni szerintetek? Már nem nagyon van ötletem, az az igazság... >>>
(#) vicsys válasza Jossz hozzászólására (») Feb 10, 2009 /
 
A ciklus elején nullázod a timeout-ot?
(#) MPi-c válasza Jossz hozzászólására (») Feb 10, 2009 /
 
A timeout változódat megfelelő méretűre definiáltad (int16)?
(#) Jossz válasza MPi-c hozzászólására (») Feb 10, 2009 /
 
Persze, long int a definíciója.
(#) Jossz válasza vicsys hozzászólására (») Feb 10, 2009 /
 
Igen, nullázva is van az értéke.
(#) GLaszlo válasza Jossz hozzászólására (») Feb 10, 2009 /
 
Üdv!

Ahogyan én csináltam a timeout-os sorosporti vételt ccsben /konkrét kódot nem tudok mellékelni most/:

1) timer0 modult beállítottam, hogy meghatározott időközönként generáljon IT-t, emellett a megszakítások beállításai: global interrupt engedélyezve, timer0 tiltva.

2) A timer0-hoz tartozó IT rutin tartalma: timer0 visszaállítása, timeout változó növelése

3) a programban, ahol soros porti vételt kellett kezelni: enable_interrupts(int_rtcc);
while(!sorosportiadatjott&&timeout disable_interrupts(int_rtcc);
timeout=0;

azaz: első körben timer0 megszakítás engedélyezése, utána while ciklusban addig maradni, amíg nem jött soros porton adat, vagy el nem érte a timeout változó a timeout_value értéket, ezután timer0 megszakítás tiltása, majd timeout változó nullázása, hogy a következő hívásnál is megmaradjon az időzítés.

A feltételt a while ciklusban remélem, hogy jól írtam most így fejből, nincs előttem a kód...ezzel a módszerrel nekem hibátlanul működött a timeout kezelés. Biztosan van ennél kevesebb hardvert használó megoldás is, vagy optimálisabb, nekem megfelelt így...

Én a sorosporti kommunikációhoz általában az INT_RDA-n belül mindig egy állapotgépet definiálok, amivel a lehetséges üzeneteket detektálni tudom, nem kell letárolni az adatokat egy bufferben, így csak a lényegi adatokat ki lehet nyerni viszonylag minimális adatmemória felhasználásával /a szükséges adatok tárolásához szükséges, illetve 1-1 "állapotregiszter"/.

üdv:
GLaszlo>
(#) Jossz válasza MPi-c hozzászólására (») Feb 10, 2009 /
 
Amit még megfigyeltem, hogy, ha nem rakom be a ciklusvizsgálathoz a timeout vizsgálatát, csak simán emelgetem belül az értékét, azt megcsinálja. Azonban, ha ott van a vizsgálatnál, akkor azonnal felveszi a vizsgálati határértéket. Ugyanez történik, ha az else ágban beleteszek egy értékvizsgálatot és ennek eredményeképpen a cikl változót beállítom 4-re, hogy a következő ciklus-kiértékeléskor lépjen tovább. Tehát

else {
timeout++;
if (timeout>5000) {
cikl=4;
}
}

ilyenkor az első ciklusban ráfut az else ágra, felveszi az 5000-es értéket, a cikl változót beállítja 4-re, és a következő while kiértékeléskor már ott is hagyta a ciklust és lép tovább...
(#) vicsys válasza Jossz hozzászólására (») Feb 10, 2009 /
 
Nem próbáltad valami másnak definiálni a timeout változót? Adjál neki pl. idolejart, mert lehetséges, hogy a timeout-ot valami más használja.
(#) Jossz válasza vicsys hozzászólására (») Feb 10, 2009 /
 
idolejar, lejar, varak... ezekkel mind kipróbáltam ugyanaz az eredmény
(#) Jossz válasza vicsys hozzászólására (») Feb 10, 2009 /
 
Nem fogjátok elhinni, mi volt a hiba!! Mindenki okulására, hogy milyen hisztis a CCS C... Amellett, hogy milyen jó compiler
Szóval a while feltétel szintaxisa

while (varakozas<10000) {

helyett

while (varakozas < 10000) {

hát ennyi... azóta megy rendesen. Ez került közel két napomba...
(#) potyo válasza Jossz hozzászólására (») Feb 10, 2009 /
 
Na szép. Az ilyenek miatt útálom a CCS-t...
(#) icserny válasza Jossz hozzászólására (») Feb 10, 2009 /
 
A while(1)-nél szerencsére nincs ilyen probléma.
Sőt,az IF-nél sem...
  1. if(t2counts<13) {
  2.     output_high(pin_c3);
  3.   }
(#) Jossz válasza icserny hozzászólására (») Feb 10, 2009 /
 
Azt hiszem, hozzá kell szoknunk, hogy minden ilyen feltételhez, műveleti jelhez, stb. kell tenni szóközt.
(#) potyo válasza Jossz hozzászólására (») Feb 10, 2009 /
 
Vagy le kell szokni a CCS-ről...
(#) Jossz válasza potyo hozzászólására (») Feb 10, 2009 /
 
Potyo, véleményed és tapasztalatod szerint melyik a CCS-nél jobb C compiler? Mert, ha tutira jobb, akkor szívesen átszokom, a lényeg a minőség...
(#) potyo válasza Jossz hozzászólására (») Feb 10, 2009 /
 
Ha 12F vagy 16F picről van szó, akkor szerintem a Hi-Tech C fordítóját érdemes használni. Írtam én is PS2-USB átalakítót CCS-ben, ma is az működik a billentyűzetemben, de emlékszem, hogy mennyi mindennel megszenvedtem, mire minden úgy működött, ahogy kellett. Nem azt mondom, hogy jobb vagy szebb a Hi-Tech fordítója, mert felhasználóbarátságban a CCS biztosan magasabb szinten van, de mi a fontos számunkra, a dizájnos felület, vagy a megbízhatóság, stabilitás? A Hi-Tech fordító sokkal közelebb van az ANSI C-hez, mint a CCS. Emellett nem próbálja elrejteni a hardvert, ami kezdetben ugyan jó dolognak tűnik, egy összetettebb feladatnál viszont akadállyá válik. A szabványhűség pedig akkor fontos, ha több fejlesztőeszközt használsz párhuzamosan, mert egyszerűen a hibalehetőségek számát csökkenti, ha valamely tipus mindegyikben ugyanazt jelenti, ugyanazok az alapértelmezett dolgok, stb.


Ha 18F-ről van szó, akkor egyértelműen a Microchip C18 fordítóját érdemes használni.
(#) Jossz válasza potyo hozzászólására (») Feb 10, 2009 /
 
Én 18F-től felfele dolgozom, és megmondom őszintén a Microchip c18-al, ill. a többi Microchip fordítóval "szemeztem", de aztán leragadtam a CCS-nél. Minden esetre köszönöm, hogy megosztottad a tapasztalataidat, szerintem érdemes lesz - amint egy kis időm lesz kísérletezni - kipróbálnom a C18-at.
Következő: »»   17 / 118
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