Fórum témák

» Több friss téma
Fórum » PIC kezdőknek
 
Témaindító: Placi84, idő: Okt 3, 2005
Témakörök:
- A PIC ÖSSZES Vdd és Vss (AVdd és AVss) (tápfeszültség) lábát be kell kötni!
- A táplábak mellé a lehető legközelebb 100nF-os KERÁMIA kondenzátorokat kell elhelyezni.
- Az MCLR lábat, 10kohm-mal fel kell húzni a Vdd tápfeszültségre.
- Külső kvarc használatakor 4MHz-ig XT, a fölött pedig HS konfigurációt kell beállítani.
- Stabilizált tápegységet kell használni, a kapcsoló üzemű "telefon töltő" adapterek okozhatnak hibákat.
- Programozáshoz, használj lehetőleg PICKIT2 vagy 3 programozót. Kerülendő a JDM (soros porti) programozó.
- A PIC adatlapja (PDF), tartalmazza a lábak kiosztását és a PIC minden paraméterét. Az adatlap ingyen letölthető!
- Egyes PIC típusoknál az RA4 nyitott nyelőelektródás (Csak lefelé húz L szintre, H szintet nem ad ki!)
- Ha a PGM lábat digitális ki-/bemenetnek használod, az alacsony feszültségű programozási lehetőséget le kell tiltani.
Lapozás: OK   716 / 1210
(#) lastewer válasza proli007 hozzászólására (») Okt 25, 2015 /
 
Nem , ez csak az ADC-nek kell leosztani. Jó lesz igazad van , köszönöm.
(#) diablo hozzászólása Okt 25, 2015 /
 
Hali!
18F-es PIC-en lévő DACOUT kimenettel lehetne direktbe (műveleti erősítő stb. nélkül) állítani egy karakteres kijelző kontrasztját? Még nem használtam ezt a kimenetet.

További kérdésem, hogy viszonylag pontos, a program futása alatt változtatható késleltetésekhez mit ajánlanátok? Olyan 100us (de inkább 10us) - 500ms-os tartományban kellene változtatnom a késleltetést.
Jelenleg a timer2 modult használom (1:4 és 1:1-es osztókkal) és a PR2 regisztert feltöltöm 100-zal, így 100us-onként kapok egy TMR2IF flag bitet (16Mhz-es órajel esetén) amit while ciklusban figyelek, majd ezt a függvényt hívom meg többször attól függően, hogy hány ms kell. Ez mind működik csak 10ms helyett 12ms-os késleltetést kapok. Ha külső 16MHz-ről ketyegne a PIC akkor mennyivel lenne pontosabb? Vagy a SOSCI-SOSCO bemenetekre tegyek pl. egy 3,2768MHz-es kvarcot és használjak más timer-t? Kinek mi vállt be?
(#) lastewer hozzászólása Okt 25, 2015 /
 
Helló!

Miért írja ki mindig ezt a fordítóm : 158 317 Operator '' is not applicable to these operands '' lcd.c

Szerintetek mi lehet itt a hiba ?(A display_v egy változó. )
  1. if(display_v > 2) { Lcd_Out(2,8,display_v); }


MikroC a fordító.
A hozzászólás módosítva: Okt 25, 2015
(#) Hp41C válasza lastewer hozzászólására (») Okt 25, 2015 /
 
No de milyen típusú és "látszik -e" onnan, ahol ez a sor van?
(#) lastewer válasza Hp41C hozzászólására (») Okt 25, 2015 /
 
  1. char *display_v = "0.000";
Látszik , mivel ha az IF részből kiszedem akkor kiírja a várt eredményt. ( Tehát ha csak ennyit hagyok meg :
  1. Lcd_Out(2,8,display_v);
)
A hozzászólás módosítva: Okt 25, 2015
(#) Hp41C válasza lastewer hozzászólására (») Okt 25, 2015 /
 
A > művelet nem értelmezett karakterfüzérre...
A hozzászólás módosítva: Okt 25, 2015
(#) lastewer válasza Hp41C hozzászólására (») Okt 25, 2015 /
 
És hogy tudom értelmezni?
(#) Hp41C válasza lastewer hozzászólására (») Okt 25, 2015 /
 
Előbb a karakterfüzért kell álalakítani egész (signed vagy unsigned)(int vagy char) esetleg float típusba.
A hozzászólás módosítva: Okt 25, 2015
(#) lastewer válasza Hp41C hozzászólására (») Okt 25, 2015 /
 
De mikor létrehoztam , már meg van adva :
Idézet:
„char *display_v = "0.000";”


Így nem értem miért kellene még egyszer.
A hozzászólás módosítva: Okt 25, 2015
(#) Hp41C válasza lastewer hozzászólására (») Okt 25, 2015 /
 
Ez a fordító egy sime C fordító. Nem értelmezi a karakterfüzér (char*) és az egész (singed vagy unsigned)(int vagy char) között a nagyobb műveletet.
Két megoldás van:
- a (char*) -ot konvertálod egyészre vagy float-ra.
- megírod az összehasonlítást: f (display_v[0] >= 49)...
A hozzászólás módosítva: Okt 26, 2015
(#) foxi63 válasza diablo hozzászólására (») Okt 25, 2015 /
 
Szia!
A 100usec megszakítás jó. A megszakítás rendre figyel egy int változót (időzítő).
Ha ennek értéke 0 nem foglalkozik vele.
Ha van benne valamilyen érték akkor minden megszakításkor csökkenti. Ha elérte a 0-t akkor bebillent egy jelzőbitet és kész.
A főprogramban csak ezt a bitet kell figyelni ha 1 törülni kell és végrehajtani az adott feladatot.
rendkívül rugalmas 100us és 6,5531 s között bármilyen időzítésre jó (és pontos).
16MHz esetén PR2=199 T2post=2. A PR2 regiszterbe mindig 1 -el kisebb számot kell írni.
indítás: a változóba csak be kell írni a számot és figyelni a jelzőbitet.
Ha egészen pontos idő kell TMR2-őt nullázni kell. Hosszabb időknél nem fontos...

üdv.: Foxi
A hozzászólás módosítva: Okt 25, 2015
(#) Hp41C válasza Hp41C hozzászólására (») Okt 26, 2015 /
 
Avagy:
if (strcomp(display_v,"2.000") > 0) ...
Bővebben: Link
(#) diablo válasza foxi63 hozzászólására (») Okt 26, 2015 /
 
Helló!
Nekem most nem szükséges a megszakítás, tehát blokkoló függvény is lehet. Viszont arra tényleg nem gondoltam, hogy eggyel kevesebbet kellene beírni a PR2 regiszterbe. Ki fogom próbálni köszi a tippet!
Szerintem annyit fogok még csinálni ha mégse jönne be, hogy bekapcsolom a PLL-t (azaz Fosc = 64MHz), hogy az utasítási idők végrehajtási ideje is csökkenjen.
(#) diablo hozzászólása Okt 28, 2015 /
 
Ha hivatalosan egy PIC 16MHz-es kvarcot támogat maximum, de van belső négyszerezője (PLL), akkor kikapcsolt PLL-lel tehetek rá mondjuk egy 32,768MHz-es kvarcot? Másik kérdés, hogy bekapcsolt PLL-lel a 16,384MHz-es kvarcot bírnia kellene még?
(#) Pali79 válasza diablo hozzászólására (») Okt 28, 2015 /
 
Nem és nem.
(#) diablo válasza Pali79 hozzászólására (») Okt 28, 2015 /
 
A válasz nem elfogadható okfejtés nélkül! Szakmai fórumon szakmai választ várok! A 16 és 16,384 nincs olyan messze egymástól, hogy nagyon beleszóljon a működésbe. Ha valami más van a háttérben, akkor kéretik azt leírni. Még belső tunningra is van lehetőség a pic-ekben órajel kalibrálás céljából, ezért kételkedem a második nemleges válaszodban.
(#) bbalazs_ válasza diablo hozzászólására (») Okt 28, 2015 /
 
A belso primer oszci ennyivel birkozik meg csak HIVATALOSAN, magyaran a gyarto ezt garantalja MINDEN darab eseten. Ergo rateheted, csak lehet hogy egyaltalan nem megy es az is lehet, hogy siman akar tiz darab is megy vele, az utolso meg mar nem. Es akkor nem fogod tudni, mi a baj....
A masodik kerdesre ugyanez a valasz, annyival megspekelve, hogy itt az elteres 4x-es lesz, tehat meg valoszinubb valami problema. Tehat ez a zona incerta lesz innentol.
(Szerintem felesleges bizonytalansagot vinni a rendszerbe, nincs akkora kulonbseg a 16 es a 16.384 kozott, hogy ez megerje. Irjal hatekonyabb kodot inkabb )
(#) diablo válasza bbalazs_ hozzászólására (») Okt 28, 2015 /
 
Köszi a választ.
Nem is húzni akarom. Csak azért vetődött fel bennem az ötlet, hogy megspóroljak két lábat amire menne egy olyan értékű kvarc aminek kettő hatványa a pontos időzítések végett. Pontosabban másra kell az a két láb. Bár így is megspórolható ha beérem alacsonyabb órajellel is, azaz nem 16,384MHz-eset teszek rá, hanem pl. csak a felét és azt négyszerezem. Ez így már járható út, nem? Vagy az is elő van írva, hogy csak 4;8;16 és 20MHz-es lehet az órajel?
(#) foxi63 válasza diablo hozzászólására (») Okt 28, 2015 /
 
Szia! A timer2 -vel pontos másodperc alapú időzítéseket tudsz csinálni, és nem kell semmiféle hókusz-pókusz. pl 16MHz esetén PR2 regisztert beállítod 199-re a TMR2 utó osztóját 2-re, és máris van 0,001sec pontos megszakításod. ebből igen egyszerű akár másodperces órajelet előállítani.
(#) diablo válasza foxi63 hozzászólására (») Okt 28, 2015 /
 
Csak elméleti kérdés volt
A panelt most tervezem a pic-hez ami több projekthez is fel lesz használva, és a későbbiekben jól jöhet a még pontosabb időzítés. De ha nem muszáj akkor nem pazarolnék el még két lábat egy másik kvarcra. Ezért volt a poszt.
(#) DJozso hozzászólása Okt 28, 2015 /
 
Kedves fórumtársak! Ti vagytok az utolsó reményeim... A bajom a következő: rádiófrekvencián szeretnék adatot továbbítani. Adott egy 16f88 PIC , mely a bemeneteinek függvényében generál egy kódot, melyet USART kódként tovább küld egy RF adó bemenetére (plussz kiírja az LCD-re a küldött adatot). A kód sugárzása folyamatos, míg a tápfeszültség megvan. A másik oldalt van egy RF vevő, melynek a kimenete megy egy másik 16f88 PIC rx lábára, mely próbálja értelmezni a kapott kódot. Na most itt van a baj. Az átküldött kód sok hamis karaktert tartalmaz a vevő oldalán. Irtam egy progit, ami folyamatosan írja az LCD-re az olvasott adatot. Hébe-hóba van közte helyesnek tűnő karakter is, de több a valótlan. A kérdésem az lenne, mi okozhatja ezt? A rádiófrekvenciás zavart( más adó által okozott) kizárnám, mivel az saját adó kikapcsolása után már-már teljesen megáll az új fogadott karakterek kijelzése. Az adó vevő távolsága 10-20cm. Arra gondoltam, hogy az nem lehet baj, hogy az adó oldalon külső kvarc az órajel(16Mhz), míg a vevő oldalon pedig a belső RC az ütemadója a PIC-nek 8Mhz-en. Azért kell a belső oszcillátort használni, mert tapasztalataim szerint az lcd-t nem lehet a B portra rakni , ha az usart modult akarom használni, mert az Usart init() parancs után az lcd kijelzés leáll. Hiába configolom az lcd, úgy hogy a rx láb szabad legyen, valahogy az eredmény ugyanaz, az lcd nem frissül(kifagy).Ha viszont az LCD az A porton van, működik az usart modul, viszont a külső osc. alkalmazása nem lehet. Végül a két kód:
Adó oldal
  1. // AN0-Fényerő mérése
  2. // AN1-Beállított Idő beolvasása:  egy poti értékének olvasása
  3. // RA2 - 1. bem  Lampa1 állapot beolvasása (0-ki; 1-be)
  4. // RA3 - 2. bem  Lampa2 állapot beolvasása
  5. // RA4 - 3. bem  Lampa3 állapot beolvasása
  6. // PortB - LCD
  7. // RB1 - Tx láb szoftveres usart kimenet
  8. // HS: 16Mhz
  9.  
  10. char key_cnt = 0;
  11. char i = 0;
  12. char key[] = "Lampa:000T000s"; // küldeni szánt kód
  13. char Feny[] = "0000"; //Fényerő értékének változója  (AN0 értéke)
  14. char Ido[] = "000s"; // Idő értéke (AN1)
  15. char Input[] = "000"; //RA2-RA4 bemenetek státusza
  16. unsigned int adc_rd, sec;
  17. unsigned short hiba; //ha értéke nulla megy a küldés, ellenkező esetben az lcd kiírja a beolvasott értékeket
  18.  
  19.  
  20. void main () {
  21.      OSCCON = 0x76;
  22.      INTCON = 0;
  23.      TRISA = 0xFF;
  24.      PORTA = 0;
  25.      TRISB = 0x00;
  26.      PORTB = 0;
  27.      ANSEL = 0x03;
  28.      ADCON0 = 0;
  29.      ADCON1 = 0b10000000;
  30.      sec = 0;
  31.      hiba = 0;
  32.      Soft_UART_Init(PORTB, 0, 1, 2400, 0);
  33.      Lcd_Init(&PORTB);
  34.      LCD_Cmd(LCD_CLEAR);
  35.      LCD_Cmd(LCD_CURSOR_OFF);
  36.      adc_rd  = ADC_read(0); //fényerő olvasása
  37.      Feny[0] = adc_rd/1000+48;
  38.      Feny[1] = adc_rd%1000/100+48;
  39.      Feny[2] = adc_rd%1000%100/10+48;
  40.      Feny[3] = adc_rd%10+48;
  41.      if (adc_rd > 5) hiba = 1; //AN0 bemenet szerint ha világos van, nincs küldés
  42.      delay_ms(30);
  43.      if (PORTA.F2 == 0 & PORTA.F3 == 0 & PORTA.F4 == 0) hiba = 2; //Hiba, ha a 3 bemenet küzöl egy sem aktív
  44.      if (PORTA.F2 == 1) {     // bemenetek státusz beírása az Input változóba és a kulcs változóba
  45.            Input[0] = '1';
  46.            Key[6] = '1';}
  47.      if (PORTA.F3 == 1) {
  48.            Input[1] = '1';
  49.            Key[7] = '1';}
  50.      if (PORTA.F4 == 1){
  51.           Input[2] = '1';
  52.           Key[8] = '1';}
  53.      adc_rd  = ADC_read(1);
  54.      if (adc_rd > 1017) sec = 300; // Átkonvertálás: ido bemeneti fesz. konvertálása másodpercé. (ADC= 1023 akkor sec=300)
  55.      if (adc_rd == 0) sec = 0;
  56.      if (adc_rd < 1017 & adc_rd > 0) sec = adc_rd*10/34;
  57.      Ido[0] = sec/100+48;      //ido változóba érték beírása
  58.      Ido[1] = sec%100/10+48;
  59.      Ido[2] = sec%10+48;
  60.      key[10] = sec/100+48;
  61.      key[11] = sec%100/10+48;
  62.      key[12] = sec%10+48;
  63.      if (sec == 0) hiba = 3;
  64.      if (hiba == 0) {  // ha nincs hiba mehet a küldés
  65.          LCD_Cmd(LCD_CLEAR);
  66.          LCD_Cmd(LCD_CURSOR_OFF);
  67.          Lcd_Out(1,1,"Adat kuldes:");  // LCD kijelzőn küldött adat kijezése
  68.          Lcd_Out(2,1, key);
  69.          while(1){  //küldés folyamatosan
  70.             delay_ms(15);  // két küldés közti várakozás
  71.             for (key_cnt=0; key_cnt<(sizeof(key)-1); key_cnt++){
  72.               Soft_UART_Write(key[key_cnt]);}}}
  73.          else { //Hiba esetén ez fut le, amely kijelzi a bemenetek értékeit, és kiírja, hogy nem volt küldés!
  74.             Lcd_Out(1,1,"F:");
  75.             Lcd_Out(1,3,Feny);
  76.             Lcd_Out(1,7, ";");
  77.             Lcd_Out(1,9, "I:");
  78.             Lcd_Out(1,11,Ido);
  79.             Lcd_Out(2,1,"Bem:");
  80.             Lcd_Out(2,5, Input);
  81.             Lcd_Out(2,8, ";");
  82.             Lcd_Out(2,10,"No RF!");}}

Vevő oldal:
  1. char ADAT[] = "Lampa:---T---s";
  2. unsigned short karakterszam = 0, rx_adat = 0;
  3. char karakter = 0;
  4.  
  5. void interrupt () {
  6.   if (PIR1.RCIF == 1 ){
  7.     if (Usart_Data_Ready()){
  8.     karakter = USART_Read();
  9.     PIR1.RCIF = 0;
  10.     if (karakter < 33 |  karakter > 122)  rx_adat = 0; // karakterek szűrése, de csak próbálkozás volt
  11.     else rx_adat = 1;}}}
  12.  
  13.  
  14. void main () {
  15.      OSCCON = 0x76;
  16.      INTCON.PEIE = 1; //Megszakítások
  17.      INTCON.GIE = 1;
  18.      TRISA = 0xFF;
  19.      PORTA = 0;
  20.      TRISB = 0x04;
  21.      PORTB = 0;
  22.      ANSEL = 0x00; //bemenetek digitalisak
  23.      ADCON0 = 0;
  24.      ADCON1 = 0;
  25.      USART_Init(2400);
  26.      Delay_ms(500);
  27.      PIE1.RCIE = 1;
  28.      PIR1.RCIF = 0;
  29.      Lcd_Config(&PORTA,1,3,0,7,6,2,4);
  30.      LCD_Cmd(LCD_CLEAR);
  31.      LCD_Cmd(LCD_CURSOR_OFF);
  32.      Lcd_Out(1,1, ADAT); //Eredeti adat megjelenítése az első sorban
  33.      delay_ms(2000);
  34.      while(1) {
  35.         if (rx_adat == 1 & karakterszam < 14) {
  36.             rx_adat = 0;
  37.             ADAT[karakterszam] = karakter;
  38.             Lcd_Out(2,1,ADAT);// olvasott karakterek megjelenítése
  39.             karakterszam++;
  40.             if (karakterszam == 14) karakterszam = 0;}}} //karakterek nullázása ha tele a váltózó

Szkóppal nézve az RF adó bemenete és az RF vevő kimenete nagyon hasonló jeleket produkál. Pontosan nem összehasonlítható, mert a szkóp nem tárolós. A kijelzett helyen azonos a két jel futása.
Van valami ötlete valakinek, hogy mi lehet a rossz?
A hozzászólás módosítva: Okt 28, 2015
(#) cross51 hozzászólása Okt 28, 2015 /
 
Az UART-ra vonatkozó megszakítás jelzők hardveresen törlődnek, nem kell őket szoftveresen piszkálni.
Nálam ez okozott olyan hibát, hogy hol működött hol nem.
(#) Bakman válasza DJozso hozzászólására (») Okt 28, 2015 / 1
 
Egy logikai analizátorral kb. egy perc lenne megnézni, hogy az RF vevő mit küld a PIC felé. Nem drága eszköz, érdemes beszerezni. Ez viszont:
Idézet:
„A rádiófrekvenciás zavart( más adó által okozott) kizárnám, mivel az saját adó kikapcsolása után már-már teljesen megáll az új fogadott karakterek kijelzése.”
Ha az adást lekapcsolod, akkor a vételnek is meg kell(ene) szűnnie azonnal, nem?
(#) bbalazs_ válasza DJozso hozzászólására (») Okt 28, 2015 / 1
 
Eloszor kosd ossze az adot a vevovel droton, hogy lasd, az biztosan jo-e. Ha igen, akkor lehet a radiokban keresni a hibat.
(#) DJozso válasza cross51 hozzászólására (») Okt 28, 2015 /
 
Köszönöm válaszod. PIR1.RCIF = 0; utasításra gondolsz az interrupt-ba? Kínomban írtam bele, hogy RCIF regiszter biztos üres legyen az új karakter fogadása előtt. De kiveszem a progiból, biztos ami biztos.
(#) cross51 válasza DJozso hozzászólására (») Okt 28, 2015 / 1
 
Ien arra gondoltam, de azt elfelejtettem kérdezni, hogy milyen PIC mert azt nem tudom, hogy minden PIC-nél hardveres-e.
(#) DJozso válasza cross51 hozzászólására (») Okt 28, 2015 /
 
Köszönök minden segítséget. Ha az adót lekapcsolod, a környezetből szedhet össze valamilyen haszontalan jelet a vevő. A drótós összekötés nem rossz ötlet, csak akkor valahogy az egészet egy tápról kell hajtani.Próbálkozom, majd jelentkezem.
cross51:
Most éppen ezekkel játszadozom. Próbálom a sebességeket állítani, mind adó, mind vevő oldalon, de csak rosszabb. Az Rf modulom, 4800 sebességnél már nem is működik. Az általad írt regiszter nullázásának kivétele a megszakításból is hatástalan (vagyis feleslegesen van a progiba). Esetleg valami más ötlet? Egyébként a 16f88-nak van hardveres UART modulja.
A hozzászólás módosítva: Okt 28, 2015
(#) sonajkniz válasza DJozso hozzászólására (») Okt 29, 2015 / 1
 
Szia!
Ugyanezzel küzdöttem a múlt héten. Egy olcsó, egyszerű adó-vevő párt használtam, amiben semmi kódolás nincs. Gyakorlatilag közel ugyanez volt a gondom.
Nekem most úgy működik, hogy minden egyes byte után újabb szinkronizáló jelet küld.
És még így sem tökéletes. Az adó-vevő elvi távolsága 25-30m. Tiszta átsugárzás esetén 5-6m-ig hibátlanul mennek az adatok, majd egyre több lessz a hibás karakter.
A vevő beállításai
(#) bbalazs_ válasza DJozso hozzászólására (») Okt 29, 2015 / 1
 
Nem kell egy taprol hajtani - eleg, ha a foldeket osszekotod (feltetelezve, hogy azonos feszultsegen mukodik mindket PIC).
(#) Hp41C válasza DJozso hozzászólására (») Okt 29, 2015 / 1
 
Ötletek:
1 - Valóban nem kell törölni az RCIF és TXIF biteket. Ha nem akarsz adni a TXIE -t 0 -ra kell állítani.
2 - Okozhatja a hibás vételt a karakterek egymásrafutása. Minden karakter után van egy kiíratás...
3 - Nincs lekezelve a vételi hiba (FERR és OERR)

Válaszd ketté a funkciót. Vegyél fel egy buffert, amibe a vett karakterek kerülnek. A mérete legyen vagyobb, mint a leghosszabb táviratod. Hozzá három adat kell még:
A bufferbenn levő karatkarak száma, a beírási és kiolvasási index.
A vételi megszakítási rutin feladata:
- RCIF bit vizsgálata, csak akkor hajtsa végre az alábbiakat, ha valóban vételi megszakítás volt
- RCSTA kiolvasása (csak egyszer) és eltárolása
- A tárolt értéken a FERR és OERR jelzőbitek vizsgálata
- Ha FERR == 0 és OERR == 0: RCREG kiolvasása, a vett adatot írja be a bufferbe, a vételi indexet növelje (ha a buffer végére ért, nullázza) és növelje a bufferben levő karakteker számát.
- Ha FERR != 0 vagy OERR != 0: Tiltsa le a vevvőt, olvassa ki a RCREG -et (dobja el a vett értéket), engedélyezze a vevőt.

A kiírató rutin feladatai:
- Figyelje, hogy hány adat van a bufferben.
- Ha van adat, vegye ki a soron következőt, növelje a kiolvasási indexet (ha a buffer végére ért, nullázza), primitív művelettel csökkentse (megszakítás nem juthat érvényre a kezdetétől a végéig) a bufferben levő karakterek számát.
- Dolgozza fel az adatot - írja ki.
A hozzászólás módosítva: Okt 29, 2015
Következő: »»   716 / 1210
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