Fórum témák

» Több friss téma
Fórum » PIC programozása C nyelven, C-Compiler
Lapozás: OK   80 / 153
(#) icserny válasza usane hozzászólására (») Aug 28, 2013 /
 
Idézet:
„Nem kell egyebet csinálnia, mint 8 bemeneten figyelni a gombokat és ki-be kapcsonli a hozzájuk rendelt kimenetet.”
Szerintem fölösleges összerendelni azokat a jeleket, amelyek amúgy is függetlenek egymástól.
(#) usane válasza watt hozzászólására (») Aug 28, 2013 /
 
Hát egy tömbbel ciklusban 1 if elég lett volna, de mint _vl_ is kifejtette ez nem a kényelemről szól.
Megírom az if-eket.
Köszönöm a véleményeket.
(#) watt válasza usane hozzászólására (») Aug 28, 2013 /
 
A C-ben arra kell vigyázni, hogy amit rövidnek és egyszerűnek látsz a forrásban, lehet, hogy a lefordított program méretében sebességében egy agyrém lesz.
(#) killbill válasza usane hozzászólására (») Aug 28, 2013 /
 
Ciklus, tömb, egy if. Lehet, hogy a PORTx es LATx nem volatile unsigned char, de sok mas nem lehet. A kod nem feltetlenul lesz rovid, viszont atlathato. Mondjuk erre a 8 pin-re tenyleg egyszerubb a 8 if. Foleg egy 8 bites PIC-en. Egy komolyabb processzoron, ahol vannak rendes pointerek, ott ebbol eleg jo kod fordul.

  1. typedef unsigned char ubyte;
  2.  
  3. struct _tp {
  4.     volatile ubyte *iport;
  5.     ubyte           inmask;
  6.     volatile ubyte *oport;
  7.     ubyte           omask;
  8. } table[] = {
  9.  {&PORTA, 1<<3, &LATA, 1<<2},
  10.  {&PORTC, 1<<1, &LATC, 1<<4},
  11.  ...
  12. };
  13.  
  14. #define TABSIZE (sizeof(table) / sizeof(struct _tp))
  15.  
  16. void copybits(void)
  17. {
  18. struct _tp *x;
  19.  
  20.  for(x = table, x < table + TABSIZE; ++x){
  21.    if(*(x->iport) & x->imask)
  22.      *(x->oport) |= x->omask;
  23.    else
  24.      *(x->oport) &= ~(x->omask);
  25. }

Ha egy porton lenne az osszes bemenet es egy masikon az osszes kimenet, akkor egyetlen 256 byte-os tablazattal meg lehetne oldani a dolgot.
(#) killbill válasza _vl_ hozzászólására (») Aug 28, 2013 /
 
Idézet:
„A C nyelv nem a kényelemről szól.”

Mihez kepest? Assembly-hez, Pascal-hoz, Basic-hez? Lenyegesen kenyelmesebb, es mindent meg lehet oldani benne, amit assembly-ben. Persze, egy php, JavaScript vagy egyeb magaszintu nyelv, ahol egy valtozonak a tipusa implicit modon dol el minden ertekadasnal, es mondjuk asszociativ tombok vannak, az sokszor kenyelmesebb, de semmikeppen nem hasznalhato hardverkozeli programozasra. Foleg nem 8 bites mikrokontrollereken. Nem veletlenul talaltak ki a C-t annakidejen. Rendszerprogramozasi nyelvnek indult, es ez a tulajdonsaga meg is maradt. Ezen felul nagyon jo nyelv hardverkozeli programozashoz.
A tobbivel egyetertek, jol kell a hw-t megtervezni, es erteni kell a programozashoz annyira, hogy legalabb sejtsd, hogy a kododbol mi fog fordulni. Bar, sokszor nagyon meglepo dolgokat tud produkalni pl. a gcc. AVR-re is, meg ARM-re is. De dsPIC-re is lattam gcc altal forditott kodot.
(#) watt válasza killbill hozzászólására (») Aug 28, 2013 /
 
Érdekes megoldás, tetszik! Azzal is egyetértek, hogy a 8 if jobban vennné ki magát!
(#) usane válasza killbill hozzászólására (») Aug 28, 2013 /
 
Hát ez egy elég gagyi pic. Még LAT regisztere sincs, de a célnak megfelel.
Idézet:
„Idézet:
„A C nyelv nem a kényelemről szól.”
Mihez kepest? Assembly-hez, Pascal-hoz, Basic-hez?”

Én is erre gondoltam, azért nem szenvedek az assemblyvel.
(#) usane válasza usane hozzászólására (») Aug 28, 2013 /
 
Újabb kérdés.
Megírtam a kódot if-ekkel, még kicsit finomításra szorul a debounce meg a delay,de müködik rendesen.
  1. /*
  2.  * File:   main.c
  3.  * Author: Usane
  4.  *
  5.  * Created on 2013. augusztus 28., 14:37
  6.  */
  7.  
  8.  
  9. #include <xc.h>
  10. #include <pic16f690.h>
  11.  
  12. #define in1  PORTBbits.RB6
  13. #define in2  PORTBbits.RB5
  14. #define in3  PORTBbits.RB4
  15. #define in4  PORTCbits.RC2
  16. #define in5  PORTCbits.RC1
  17. #define in6  PORTCbits.RC0
  18. #define in7  PORTAbits.RA2
  19. #define in8  PORTAbits.RA1
  20.  
  21. #define out1 PORTBbits.RB7
  22. #define out2 PORTCbits.RC7
  23. #define out3 PORTCbits.RC6
  24. #define out4 PORTCbits.RC3
  25. #define out5 PORTCbits.RC4
  26. #define out6 PORTCbits.RC5
  27. #define out7 PORTAbits.RA4
  28. #define out8 PORTAbits.RA5
  29.  
  30. // CONFIG
  31. #pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
  32. #pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
  33. #pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
  34. #pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
  35. #pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
  36. #pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
  37. #pragma config BOREN = ON       // Brown-out Reset Selection bits (BOR enabled)
  38. #pragma config IESO = OFF        // Internal External Switchover bit (Internal External Switchover mode is disabled)
  39. #pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
  40.  
  41.  
  42. void delay(int cycle)
  43. {
  44.     int i;
  45.     for (i=1; i<=cycle; i++)
  46.     {
  47.         i=i;
  48.     }
  49.     return;
  50. }
  51. /*
  52. void bitset(unsigned char input, unsigned char output)
  53. {
  54.     unsigned char *input;
  55.     if (*input==1)
  56.         {
  57.             output=!output;
  58.             while (input==1)
  59.             {
  60.                 delay(1000);
  61.                 input=input;
  62.             }
  63.         }
  64.         else
  65.         {
  66.             output=output;
  67.         }
  68.     return;
  69. }
  70. */
  71. void main(void)
  72. {
  73.  
  74.  
  75.     OSCCON=0b1100000;
  76.     TRISA=0xCF;
  77.     TRISB=0x7F;
  78.     TRISC=0x07;
  79.     while(1)
  80.     {
  81. /*
  82.         bitset(in1,out1);
  83.         bitset(in2,out2);
  84.         bitset(in3,out3);
  85.         bitset(in4,out4);
  86.         bitset(in5,out5);
  87.         bitset(in6,out6);
  88.         bitset(in7,out7);
  89.         bitset(in8,out8);
  90. */
  91.         if (in1==1)                     // 1-es csatorna
  92.         {
  93.             out1=!out1;
  94.             while (in1==1)
  95.             {
  96.                 delay(1000);
  97.             }        
  98.         }
  99.         else
  100.         {
  101.             out1=out1;
  102.         }
  103.         if (in2==1)                     // 2-es csatorna
  104.         {
  105.             out2=!out2;
  106.             while (in2==1)
  107.             {
  108.                 delay(1000);
  109.             }
  110.         }
  111.         else
  112.         {
  113.             out2=out2;
  114.         }if (in3==1)                    // 3-as csatorna
  115.         {
  116.             out3=!out3;
  117.             while (in3==1)
  118.             {
  119.                 delay(1000);
  120.             }
  121.         }
  122.         else
  123.         {
  124.             out3=out3;
  125.         }if (in4==1)                    // 4-es csatorna
  126.         {
  127.             out4=!out4;
  128.             while (in4==1)
  129.             {
  130.                 delay(1000);
  131.             }
  132.         }
  133.         else
  134.         {
  135.             out4=out4;
  136.         }if (in5==1)                    // 5-ös csatorna
  137.         {
  138.             out5=!out5;
  139.             while (in5==1)
  140.             {
  141.                 delay(1000);
  142.             }
  143.         }
  144.         else
  145.         {
  146.             out5=out5;
  147.         }if (in6==1)                    // 6-os csatorna
  148.         {
  149.             out6=!out6;
  150.             while (in6==1)
  151.             {
  152.                 delay(1000);
  153.             }
  154.         }
  155.         else
  156.         {
  157.             out6=out6;
  158.         }if (in7==1)                    // 7-es csatorna
  159.         {
  160.             out7=!out7;
  161.             while (in7==1)
  162.             {
  163.                 delay(1000);
  164.             }
  165.         }
  166.         else
  167.         {
  168.             out7=out7;
  169.         }if (in8==1)                    // 8-as csatorna
  170.         {
  171.             out8=!out8;
  172.             while (in8==1)
  173.             {
  174.                 delay(1000);
  175.             }
  176.         }
  177.         else
  178.         {
  179.             out8=out8;
  180.         }
  181. //*/
  182.     }
  183.  
  184.     return;
  185. }

A kérdés az, hogy meg tudom-e oldani valahogy, hogy az if-ek helyett a kikommentezett függvényt használjam, vagy valami hasonlót.
Fele akkora helyet foglalna az EEPROM-ban, igaz több RAM-ot, de az bővíthető külső ramokkal.
Ennél a kapcsolónál lényegtelen, de a későbbiekben szükségem lehet rá, hogy rövidebb legyen a kód. Próbálgattam a volatile-t beiktatni, de nem jöttem rá hogy kellene, hogy működjön is.
A hozzászólás módosítva: Aug 28, 2013
(#) _vl_ válasza usane hozzászólására (») Aug 28, 2013 /
 
Nem, nem tudod. A dolog lényege az, hogy a lentebb killbill által belinkelt, pointeres-maszkos megoldás kivételével nincs igazából olyan megoldás, ami végül nem 8 if-re fordul le, ha a bitjeid össze-vissza vannak, tehát enni fogja a flash-t.
Továbbá megjegyzem, hogy az, hogy az if-en belül bármeddig várakozol (delay), pláne úgy, hogy akár végtelen ideig is képes vagy várakozni (while (in == 1) delay), az szerintem nem lesz korrekt működés (mivel párhuzamosan kellene a 8 bemenetet figyelni, és a delay-eknek párhuzamosan kéne működniük, mert így feltartják egymást is, és az tuti nem az, mint amit szeretnél).
A hozzászólás módosítva: Aug 28, 2013
(#) _vl_ válasza killbill hozzászólására (») Aug 28, 2013 /
 
Idézet:
„„A C nyelv nem a kényelemről szól.”
Mihez kepest?”

A magasszintű nyelvekhez képest.
A mondat értelme az lenne, hogy a C nyelv annyira hardverközeli nyelv, hogy a benne megfogalmazott kód elég közvetlenül meghatározza, hogy az assembly kód milyen algoritmust végezzen, hogy milyen assembly kód készüljön belőle - és nem mellesleg pont ezért jó hardverközeli dolgokra. Ebből az is következik, hogy minden olyan nyelvi megoldás, ami az adott platformon assembly-be nehezen, bonyolultan fordítható át, nagyfokú kreativitást enged a fordítónak, így elvesztve a kontrollt a végeredmény felett. A C fordítónak alapvetően nem feladata helyettünk gondolkodni, így ha ezt mi sem tesszük, akkor valami random eredmény fog kisülni
(#) killbill válasza _vl_ hozzászólására (») Aug 29, 2013 /
 
Erdekes, amit mondasz. En utoljara 1988-ban tudtam kiszamolni elore, hogy a Manx C compiler milyen kodot fog generalni, mert az nem optimalizalt egyaltalan. A for( ; ; ) sokkal stilusosabb, mint a while(1), merthogy a nyelv definicioja szerint a for feltetelenek elhagyasa azt jelenti, hogy a feltetel mindig igaz. Ezzel szemben a while(1)-nel az optimalizacio ismeri fel, hogy konstans a feltetel. Szoval van kulonbseg a ketto kozott, de ma mar mindegy, mert ugyanazt forditjak belole a forditok. De a CP/M-es Manx fordito a while(1)-re bizony meg betoltott 1-et a HL-be, majd megnezte, hogy nullatol kulonbozik-e... Tapasztalatom szerint a mai forditok, akarmennyire is nem akarom, helyettem gondolkodnak. Es ez nem mindig jo. Persze a volatile sokmindent megold. A gcc olyan szinten irja at az altalad leirt C kodot, hogy sosem ismersz ra. Azon mar nem is csodalkozom, hogy komplett fuggvenyeket tuntet el (nemhogy par lokalis valtozot). Ciklustorzseket kirakja cikluson kivulre, mert latja, hogy mi lesz a vegeredmeny, stb.. Akarmilyen amator modon leirhatsz egy ciklust, amiben egy tombot olvasol vegig index-szel, a gcc siman atirja az egeszet pointeresre. Szoval, en mar nem hiszek abban, hogy tulzottan tudnam befolyasolni a forditot abban, hogy milyen kodot allitson elo.

De szerintem a C nyelv nagyon kenyelmes. Talan pont azert, met mindenfele adattipus van, csinalhatsz strukturat, uniont, fuggvenypointert, bitmezot (sosem hasznaltam), es gyakorlatilag mindent. A logikai operatorok (== != < > stb) is int eredmenyt adnak, igy nem csak felteteles utasitasoknal lehet oket hasznalni, mint megannyi magasszintu nyelvben.
  1. valtozo = masik_valtozo != 10;

Minden muvelet eredmenye onmagaban lehet jobbertek, atadhato fuggvenynek, vagy akar lehet feltetel egy felteteles utasitasnal. Ez utobbi persze megint nem nagy dolog a mai forditok ismereteben, de eredetileg segitette a hatekony assembly eloallitasat:
  1. c = getchar();
  2.  if(c == EOF)
  3.  
  4. vagy
  5.  
  6. if((c = getchar()) == EOF)

Az elso esetben a forditott kod azt csinalta, amit odairtak. Meghivta a getchar()-t, letette a kodot a 'c' valtozoba, majd felvette onnan az erteket es vizsgalta. A masodik esetben egyreszt tomorebben irhatod a C kodot, masreszt a forditonak segitettel, hogy a kapott int-et tegye le 'c'-be, majd ugyanazt a szamot vizsgalja meg. Megsporolt egy indirekt memoria olvasast, ami draga dolog. Ezt ma mar magatol is igy csinalja a fordito, akarhogy is irod le, es nagy valoszinuseggel a 'c' valtozot eltunteni, nem fog semmit a stack-en irkalni. De maga az irasmod meg mindig megvan, es szerintem nagyon kenyelmes es beszedes.
Vagy ott van a C nyelvben kitalalt (ma mar mindenki atvette), ? : operator, meg a logikai && es || kezelese.
  1. if(ptr != NULL && *ptr == 'e')..

egy if, de amig a ptr nulla, addig nem dereferencialja (hogy mondjak ezt magyarul?).
Vagy masik ket kedvencem:
  1. if(timer && !--timer)
  2.   most_jart_le();
  3.  
  4. is_valami(str) || is_egyeb(str) || is_komment(str) || printf("ismeretlen parancs: %s\n", str);

Rettentoen jo nyelv, ha ismeri az ember (tudom, hogy te ismered) az osszes lehetoseget.

Igazabol kellene egy C topic, mert az itt (es az AVR-en is) felmerulo kerdesek sokszor messze nem az adott architekturarol szolnak, hanem a C nyelv alapjairol. Amig valaki nem tudja, hogy a PORTAbits.PA3 mit is jelent pontosan, addig ez nem PIC kerdes, hanem C nyelvi kerdes.
A hozzászólás módosítva: Aug 29, 2013
(#) usane válasza _vl_ hozzászólására (») Aug 29, 2013 /
 
Idézet:
„pláne úgy, hogy akár végtelen ideig is képes vagy várakozni (while (in == 1) delay), az szerintem nem lesz korrekt működés (mivel párhuzamosan kellene a 8 bemenetet figyelni, és a delay-eknek párhuzamosan kéne működniük, mert így feltartják egymást is, és az tuti nem az, mint amit szeretnél).”

Működés szempontjából jó. Mint említettem 8 bemenetet figyel, ami manuális gombnyomás, és a normális emberek egyszerre 1 gombot nyomnak meg. (tudom vannak kivételek, pl: billentyűzet shift+ és egyebek, de egy vezérlő eszközön nem. És nem végtelenségig várakozik, csak ameddig nyomva tartják. Viszont amit a főciklusban online figyel, azt a függvénybe nem tudtam még bevinni, mert oda csak a meghívás pillanatában levő érték megy be, a rekurzió meg ugyebár felejtős a uC-erek esetében.Mint mondtam itt próbáltam a volatile-t, de pointerek nélkül, ami eddig sikertelen, úgyhogy mint mondtad valószínűleg csak az említett pointeres megoldással tudom megcsinálni.
(#) usane válasza killbill hozzászólására (») Aug 29, 2013 /
 
Idézet:
„Igazabol kellene egy C topic, mert az itt (es az AVR-en is) felmerulo kerdesek sokszor messze nem az adott architekturarol szolnak, hanem a C nyelv alapjairol. Amig valaki nem tudja, hogy a PORTAbits.PA3 mit is jelent pontosan, addig ez nem PIC kerdes, hanem C nyelvi kerdes.

Igazad lehet, bár a uC erősen korlátozó tényező. Esetemben meg ráadásul gagyi is(16f690), de a célnak megfelel.
(#) killbill válasza usane hozzászólására (») Aug 29, 2013 /
 
Eppen ezert kell tenyelg tudni, hogy mi tortenik, mi micsoda. Szerintem _vl_ is errol beszelt.
Mellesleg a rekurzio nem felejtendo el mukrokontrolleren. Miert lenne az??? Csak stack kell hozza. Igaz, a regi PIC-eken nincs igazi rendes stack, de valahogy emulaljak. Viszont a te problemadhoz nem rekurzio kell, hanem az, hogy atadj a fuggvenyednek egy strukturapointert, ami strukturaban benne van a bemenetet leiro pointer es bitmaszk, a kimenetre ugyanez, es mondjuk egy utolso allapota a bemenetnek (abbol latod, hogy most nyomtak meg). A prellmentesiteshez meg csak annyi kell, hogy ezt a fuggvenyt ne esz nelkul hivogasd, hanem mondjuk 20..50ms-onkent.
  1. struct bill_leiro {
  2.  volatile char *iprt;
  3.  char imsk;
  4.  volatile char *oprt;
  5.  char omsk;
  6.  char elozo;
  7. } billentyuk[] = {
  8.  kitoltod, ahogy az elozo peldaban is volt
  9. };
  10.  
  11.  
  12.  
  13. /*
  14.  * Ezt a fuggvenyt 20..50 millisec-enkent kell meghivni
  15.  */
  16. gombozikl()
  17. {
  18. struct bill_leiro *p;
  19. char                  most;
  20.  
  21.   for(p = billentyuk; p < billentyuk + TABSIZE; ++p){
  22.     most = *(p->iprt) & p->imsk; // a bemenet pillanatnyi allapota most
  23.     if(most != p->elozo){        // ha megvaltozott az allapota,
  24.       p->elozo = most;           // akkor eltaroljuk az uj allapotot
  25.       if(most)                   // ha most nyomtak meg a gombot,
  26.         *(p->oprt) ^= p->omsk;  // akkor megnegaljuk a kimeneti bitet
  27.     }
  28.   }
  29. }
A hozzászólás módosítva: Aug 29, 2013
(#) usane válasza killbill hozzászólására (») Aug 29, 2013 /
 
Ok, holnap kipróbálom ha esz rá időm.
Köszi szépen az infokat meg a kódot.
A hozzászólás módosítva: Aug 29, 2013
(#) janimester hozzászólása Szept 3, 2013 /
 
Üdv. Ebben a programban mit kéne változtatnom hogyha nincs eredmény ugorjon tovább a program? Azért lenne ez fontos mert több mindent tettem ez mellé a program mellé és ha nincs érték megáll az egész programom ami egyébként tökéletesen működik.
  1. /*******************************************************************************
  2.   18F2520
  3. *******************************************************************************/
  4.  
  5. // Lcd pinout settings (Global variables)
  6. sbit LCD_RS at RC0_bit;
  7. sbit LCD_EN at RC1_bit;
  8. sbit LCD_D4 at RC2_bit;
  9. sbit LCD_D5 at RC3_bit;
  10. sbit LCD_D6 at RC4_bit;
  11. sbit LCD_D7 at RC5_bit;
  12. // Pin direction
  13. sbit LCD_RS_Direction at TRISC0_bit;
  14. sbit LCD_EN_Direction at TRISC1_bit;
  15. sbit LCD_D4_Direction at TRISC2_bit;
  16. sbit LCD_D5_Direction at TRISC3_bit;
  17. sbit LCD_D6_Direction at TRISC4_bit;
  18. sbit LCD_D7_Direction at TRISC5_bit;
  19.  
  20. unsigned short int falling_edge = 0;
  21. unsigned short int TMR0H_value, TMR0L_value;
  22. unsigned int TMR0_value;
  23. char TMR0_value_to_LCD[7];
  24. unsigned int rev;
  25. char rev_to_LCD[7];
  26.  
  27. void interrupt() {
  28.     if(INTCON.INT0IF) {
  29.         falling_edge++;
  30.         if(falling_edge == 1) {
  31.             TMR0H = TMR0L = 0;
  32.         }
  33.         if(falling_edge == 2) {
  34.             TMR0H_value = TMR0H;
  35.             TMR0L_value = TMR0L;
  36.             TMR0_value = (TMR0H << 8) + TMR0L; // két nyolcbites változó összefűzése 16 bitessé
  37.             rev = 234375 / TMR0_value;         // (1000 * 1000) / (256 * 4 * TMR0_value)
  38.             TMR0H = TMR0L = 0;
  39.             falling_edge = 0;
  40.         }
  41.         INTCON.INT0IF = 0;
  42.     }
  43. }
  44.  
  45. void main() {
  46.     OSCCON = 0x62;
  47.     ADCON1 = 0x0F;
  48.     CMCON = 0x07;
  49.     RCON.IPEN = 0;              // pdf 104.
  50.     INTCON = 0b11110000;        // pdf 95.
  51.     INTCON2.INTEDG0 = 0;        // falling edge, pdf 96.
  52. //    INTCON2.TMR0IP = 0;         // low interrupt priority
  53.     T0CON = 0b10000111;         // 1:256, pdf 125.
  54.     TMR0H = TMR0L = 0;
  55.     TRISB = 0b00000001;
  56.     LATB = 0;
  57.     TRISC = 0;
  58.     LATC = 0;
  59.  
  60.     Lcd_Init();
  61.     delay_ms(100);
  62.     Lcd_Cmd(_LCD_CURSOR_OFF);
  63.  
  64.     while(1) {
  65.         if(rev <= 300) {
  66.             Lcd_Out(1, 1, "-----");
  67.             Lcd_Out_Cp(" RPM");
  68.             Lcd_Out(2, 1, "-----");
  69.             Lcd_Out_Cp(" TMR0");
  70.         }
  71.         else {
  72.             WordToStr(rev, rev_to_LCD);
  73.             Lcd_Out(1, 1, rev_to_LCD);
  74.             Lcd_Out_Cp(" RPM");
  75.  
  76.             WordToStr(TMR0_value, TMR0_value_to_LCD);   // IntToStr előjeles 2 bájt, WordToStr előjel nélküli 2 bájt
  77.             Lcd_Out(2, 1, TMR0_value_to_LCD);
  78.             Lcd_Out_Cp(" TMR0");
  79.         }
  80.         delay_ms(10);
  81.     }
  82. }
(#) potyo válasza janimester hozzászólására (») Szept 3, 2013 /
 
Honnan és hová ugorjon tovább?
(#) janimester válasza potyo hozzászólására (») Szept 3, 2013 /
 
Itt van a majdnem teljes progi a kijelző definiálást most nem másolom be de ha nincs érték a hőmérséklet mérés és a feszültség mérés pár másodperc után megáll vagy el sem indul az egész ha nem kap jelet a fentebb említett programrész. Úgy kellene továb ugornia hogy a main programnál ugyanúgy frissítse tovább az értékeket azaz olvassa a hőmérsékletet be az adc értékét és ha elér megint ide és azt érzékeli hogy nincs bemenő impulzus ne álljon meg hanem ugorja át és ha van érték akkor pedig ugyanúgy írja ki a kijelzőre. 137 sor alatt van az a parancs ha az érték 300 alatti írjon ki pár vonalat a kijelzőre de ezzel nem jó így.
  1. char message1[] = "FORDULAT";
  2. char *volt = "00.0";
  3. char *text = "000.0";
  4. unsigned long temp;
  5. unsigned int ADC_Value, DisplayVolt;
  6. const unsigned short TEMP_RESOLUTION = 9;
  7. unsigned short int falling_edge = 0;
  8. unsigned short int TMR0H_value, TMR0L_value;
  9. unsigned int TMR0_value;
  10. unsigned int rev;
  11. char rev_to_LCD[6];
  12.  
  13.  void interrupt() {
  14.     if(INTCON.INT0IF) {
  15.         falling_edge++;
  16.         if(falling_edge == 1) {
  17.             TMR0H = TMR0L = 0;
  18.         }
  19.         if(falling_edge == 2) {
  20.             TMR0H_value = TMR0H;
  21.             TMR0L_value = TMR0L;
  22.             TMR0_value = (TMR0H << 8) + TMR0L; // két nyolcbites változó összefűzése 16 bitessé
  23.             rev = 1171875 / TMR0_value;         // (1000 * 1000) / (256 * 4 * TMR0_value)
  24.             TMR0H = TMR0L = 0;
  25.             falling_edge = 0;
  26.         }
  27.         INTCON.INT0IF = 0;
  28.     }
  29.  
  30. }
  31.  
  32.  
  33. void Display_Temperature(unsigned int temp2write) {
  34.   const unsigned short RES_SHIFT = 4;
  35.   char temp_whole;
  36.   unsigned int temp_fraction;
  37.  
  38.   if (temp2write & 0x8000) {
  39.      text[0] = ' ';
  40.      temp2write = ~temp2write + 1;
  41.      }
  42.   temp_whole = temp2write >> RES_SHIFT ;
  43.   if (temp_whole/100)
  44.   text[0] = temp_whole/100  + 48;
  45.   else
  46.   text[0] = ' ';
  47.   text[1] = (temp_whole/10)%10 + 48;             // Extract tens digit
  48.   text[2] =  temp_whole%10     + 48;             // Extract ones digit
  49.   temp_fraction  = temp2write << (4-RES_SHIFT);
  50.   temp_fraction &= 0x000F;
  51.   temp_fraction *= 628;
  52.   text[4] =  temp_fraction/1000    + 48;         // Extract thousands digit
  53.   Lcd_Out(1, 14, text);
  54.  
  55.   if(temp >= 34*0x1C )       //hűtőventillátor bekapcsolása 60foknál.
  56.     {
  57.     PORTC.B4 = 0x01;
  58.     }
  59.     else
  60.     PORTC.B4 = 0x00;
  61. }
  62.  
  63.  
  64. void main() {
  65.  
  66.  Lcd_Init();
  67.  Lcd_Cmd(_lcd_clear);
  68.  Lcd_Cmd(_lcd_cursor_off);
  69.  Lcd_out(1,1,"Simson Race Technic");
  70.  Delay_ms(500);
  71.  Lcd_out(2,7,"S80/5M");
  72.  Delay_ms(500);
  73.  Lcd_out(3,3,"by: Fekete Janos");
  74.  Delay_ms(500);
  75.  Lcd_out(4,1,"Computer inditasa...");
  76.  Delay_ms(500);
  77.  
  78. // TRISB = 0;                            // PORTB all output to LED
  79. //  PORTB = 0;                            //port b lábak alaphelyzetben 0-án
  80.  
  81.  
  82.  
  83.   CMCON = 0x07;   // Disable comparators
  84.   ADCON0= 0x01;    //voltmérőé
  85.   ADCON1= 0x0E;    //voltmérőé      (0x0e)
  86.   PORTA = 0;
  87.   TRISA = 0b00010000;
  88.   PORTC = 0;
  89.   TRISC = 0;
  90.     RCON.IPEN = 0;              // pdf 104.
  91.     INTCON = 0b11110000;        // pdf 95.
  92.     INTCON2.INTEDG0 = 0;        // falling edge, pdf 96.
  93.     T0CON = 0b10000111;         // 1:256, pdf 125.
  94.     TMR0H = TMR0L = 0;
  95.     TRISB = 0b00000001;
  96.  
  97.  
  98. Lcd_Init();
  99. Lcd_Cmd(_LCD_CLEAR);
  100. Lcd_Cmd(_LCD_CURSOR_OFF);
  101.  
  102. LCD_Out(2,1,"AKKU");
  103. Lcd_Out(3,1,message1);
  104. Delay_ms(100);
  105. Lcd_Out(1,1,"HENGER");
  106. Lcd_Chr(1,19,223);
  107. Lcd_Chr(1,20,'C');
  108. Lcd_Chr(2,20,'V');
  109.  
  110.  do {
  111.  
  112.    ADC_Value = ADC_Read(0);
  113.    DisplayVolt = ADC_Value * 2;
  114.    volt[0] = DisplayVolt/1000 + 48;
  115.    volt[1] = (DisplayVolt/100)%10 + 48;
  116.    volt[3] = (DisplayVolt/10)%10 + 48;
  117.    Lcd_Out(2,15,volt);
  118.    delay_ms(95);
  119.  
  120.    Ow_Reset(&PORTA, 1);                         // Onewire reset signal
  121.    Delay_ms(10);
  122.    Ow_Write(&PORTA, 1, 0xCC);                   // Issue command SKIP_ROM
  123.    Delay_ms(10);
  124.    Ow_Write(&PORTA, 1, 0x44);                   // Issue command CONVERT_T
  125.    Delay_us(10);
  126.    Ow_Reset(&PORTA, 1);
  127.    Delay_ms(10);
  128.    Ow_Write(&PORTA, 1, 0xCC);                   // Issue command SKIP_ROM
  129.    Delay_ms(10);
  130.    Ow_Write(&PORTA, 1, 0xBE);                   // Issue command READ_SCRATCHPAD
  131.    Delay_ms(10);
  132.    temp =  Ow_Read(&PORTA, 1);
  133.    temp = (Ow_Read(&PORTA, 1) << 8) + temp;
  134.    Display_Temperature(temp);
  135.    Delay_ms(95);
  136.  
  137.    if(rev <= 300) {
  138.  
  139.  
  140.        
  141.    Lcd_Out(3, 13, "-----");
  142.    Lcd_Out_Cp("RPM");
  143.  
  144.    }
  145.    else {
  146.    WordToStr(rev, rev_to_LCD);
  147.    Lcd_Out(3, 13, rev_to_LCD);
  148.    Lcd_Out_Cp("RPM");
  149.    }
  150.   } while(1);
  151. }
A hozzászólás módosítva: Szept 3, 2013
(#) Attila86 hozzászólása Szept 17, 2013 /
 
Olvasgatom a páromtól kapott Kónya-féle C-programozós könyvet és ismerkedem a C nyelvvel. Eddig két dolog nem világos:

1.- A main függvény végén van egy kapcsos zárójel, annak is a bezárós fele ugyebár. Ha oda jut a PIC akkor mi történik? Az a zárójel olyan mint assembly-ben az END utasítás, azaz ott megáll a fordító? Hogyha nincs előtte valamiféle ciklus amiben végtelenül szaladgálhat vagy minimum egy goto$, akkor mi történik? A programszámláló az utolsó sor után elszabadul és megy amerre lát?

2.- Nem értem teljesen ezt az utóbb inkrementálunk-dekrementálunk dolgot. Például konkrétan ennek:
a=++b+c+++d++
Mi lesz az eredménye ha mondjuk b=1, c=2 és d=3? Egyáltalán értelmezhető ez így, a c-betű után három darab pluszjellel? Az eredmény ez lesz?
a=7, b=2, c=3 , d=4

3.- Ha van három számom (a, b, c) és mind a három unsigned char majd ezt írom:
a=b*c
De a szorzat eredménye már két bájtos lesz, azaz az a-nak az unsigned char már nem elég, akkor mi történik? Beírja csak az alsó vagy csak a felső bájtot az a-ba? És a fordító ilyen esetben szól egyébként hogy gond van?
A hozzászólás módosítva: Szept 17, 2013
(#) Hp41C válasza Attila86 hozzászólására (») Szept 17, 2013 /
 
1, } : Egy szintaktikai egység vége. Egy függvény esetében kilépés a függvényből. Normál (számítógépes) környezetben a main() -ből való visszatérés a programból való kilépés. Mikrokontrolleres környezetben Neked kell gondoskodni, hogy a main() ből soha ne lépjen ki a vezérlés.

2, a=++b+c+++d++, ahol a=7, b=2, c=3 , d=4 :
a=(++b)+(c++)+(d++) eredménye a=12, b=3, c= 4, d=5
Sokkal érdekesebb lenne a=(++b)+(c++)+(++c)+(b++)... Sajnos a C optimalizálása megváltoztathaja a műveletek sorrendjét, így a nem egyértelmű műveletsorozatok használata kerülendő.
Egyébként a változó előtt álló ++ vagy -- a változó értékének felhasználása előtt növel vagy csökkent, a változó után álló ++ vagy -- a változó értékének felhasználása után növel vagy csökkent.

3, Csonkolódik a megadott számábrázolásnak megfelelő bitszámra - az alsó 8 bitet kapod meg. Van olyan fordító, ami szól érte (worning level beállítása), van amelyik nem.
A hozzászólás módosítva: Szept 17, 2013
(#) Attila86 válasza Hp41C hozzászólására (») Szept 17, 2013 /
 
Köszönöm a válaszokat!
Idézet:
„a=++b+c+++d++, ahol a=7, b=2, c=3 , d=4”

Ezt akkor jól eltaláltam.
Idézet:
„a=(++b)+(c++)+(d++) eredménye a=12, b=3, c= 4, d=5”

Ezt viszont nem értem, ez hogyan jön ki?

Amúgy még csak alig olvastam bele a könyvbe de elképesztő hogy miket lehet így C-ben megvalósítani... Illetve nem is az hogy miket hanem hogy milyen egyszerűen és ami számomra még jobban hangzik hogy sokkal-sokkal átláthatóbban! Egyetlen sorba belefér az ami assembly-ben 30-40 sor meg vagy három szubrutinhívás volt. És akkor csak elosztottam két 32 bites számot (a 8 bites PIC-kel), kivontam belőlük egy harmadikat és megnéztem hogy az eredmény kisebb vagy nagyobb-e mint valamennyi. Ez mostantól akkor csak egy sor lesz?! Te jó ég, és én még komplett menürendszereket írtam assembly-ben!
(#) Hp41C válasza Attila86 hozzászólására (») Szept 17, 2013 /
 
a=(++b)+(c++)+(d++), ahol b=2, c=3 , d=4: Elírtam...
++b = 3, mivel elöl van a ++, a 3 -at használjuk fel, 3 + 3 + 4 = 10, de közben növeljük c és d értékét is.

Ne várj csodákat. Amit így leírsz egyetlen sorban, az minimum kétszer hosszabb lesz assembly kódban, mint amit magad írtál volna...
A hozzászólás módosítva: Szept 17, 2013
(#) Attila86 válasza Hp41C hozzászólására (») Szept 17, 2013 /
 
Abban biztos is vagyok, de hogy nekem könnyebb lesz átlátnom a programot az is biztos! Illetve csökken a hibalehetőségek száma mert én személy szerint mindig azt csinálom hogy ha pl egy három bájtos kivonásra van szükségem akkor lusta vagyok begépelni, inkább rákeresek a programomban a subwfb szóra, mert biztos hogy valahol már leprogramoztam egy ilyet. Onnan kimásolom, beillesztem és átírom címkéket és persze a regiszterneveket. Kb a programhibák felét nálam az okozza hogy valamit ezek közül elfelejtek átírni.
(#) icserny válasza Attila86 hozzászólására (») Szept 17, 2013 /
 
Idézet:
„Onnan kimásolom, beillesztem és átírom címkéket és persze a regiszterneveket.”
Pedig makrókat is használhattál volna erre a célra! Azt pont erre találták ki...
(#) Attila86 válasza icserny hozzászólására (») Szept 17, 2013 /
 
Használok azokat is, de nem mindig. A bonyolultabb dolgokra amik többek mondjuk 6-8 sornál, ott jön szóba a makró nálam. Osztásra, gyökvonásra, hatványozásra, sokbájtos szorzásra szubrutint hívok de a 2-3 bájtos inkrementálásokat/dekrementálásokat vagy kivonásokat/összadásokat, pár bájtos összehasonlításokat inkább beírogatom csak.
A hozzászólás módosítva: Szept 17, 2013
(#) potyo válasza Attila86 hozzászólására (») Szept 17, 2013 /
 
Idézet:
„Eddig két dolog nem világos”


Ez három volt
(#) Attila86 válasza potyo hozzászólására (») Szept 17, 2013 /
 
Kis szemfüles! Igen, közben szerkesztettem.
(#) Attila86 hozzászólása Szept 18, 2013 /
 
Elolvastam mindent és nagy részben értem is szerencsére. Úgyhogy elkezdenék programozgatni!

1.- Jól gondolom ugye, hogy ha PIC18(F25K80)-at szeretnék programozni akkor a Microchip C18 fordítója kell nekem? Olvastam hogy ez nem freeware, miféle korlátozásokat tartalmaz az ingyenes verzió? És mennyibe kerül a teljes verzió? Bár gondolom mivel ez egy fejlesztőeszköz aminek a segítségével anyagi haszonra lehet szert tenni, nem a hobbistáknak szóló ára van. Ez esetben elég lesz nekem az ingyenes verzió vagy rákeressek az nCore-on?

2.- Assembly-ben van egy csomó szuper jó kis szubrutinom, mint például LCD inicializáló, kiírató, kijelző-törlő rutinjaim, időzítő rutinok, bináris-decimális átalakítók, négyzetgyökvonás és pár hasonló matematikai algoritmus stb. Ezekre itt is szükségem lenne, honnan lehet ilyeneket letölteni? Némelyiket megírom újra de egy hat bájtos négyzetgyökvonást vagy egy 8 digites átalakítót nem szeretnék bepötyögni. Főleg hogy később trigonometriai függvényekre is szükség lesz a fogyasztásmérőmnél. Sőt, úgy hallottam hogy C-re van kész FFT is amit csak beillesztek és megy is. Igaz ez?

3.- A legnagyobb szám a "long long" lehet 32 bittel, oké. Na de nekem már assembly-ben is egy csomószor 48 bites számokkal kellett dolgoznom! Akkor az most hogyan lesz? Ugyan úgy mint ahogy assembly-ben bájtonként számolgattam manuálisan, most "long long"-onként kell majd csak C-ben?

4.- Ha átváltok assembly-re mert bizonyos feladatoknál erre a programrész lefutásának ideje miatt szükségem lesz, akkor ott használhatom konkrétan például ezt:
movf regiszter+1, W //regiszter felső bájtjának mozgatása a W-be
A "+1"-et úgy fogja értelmezni a C fordító ahogyan én? Nem próbál meg hozzáadni egyet, ugye? (Azt már tudom hogy noha asm-re váltottam de a kommentelés akkor is két /-jellel történik és nem pontosvesszővel mint assembly-ben.
A hozzászólás módosítva: Szept 18, 2013
(#) potyo válasza Attila86 hozzászólására (») Szept 18, 2013 /
 
1. XC8 vagy C18, használhatod bármelyiket. C18-ban egyik optimalizálás és a csak egyes chipekben benne levő bővített utasításkészlet használata volt tiltva, minden más tekintetben teljes értékűen működött. Az árát nézd meg chipcad-nél, de szerintem be fogod érni a demo verzióval is. XC8 demóról megoszlanak a vélemények, éppen itt írta vilmosd, ha jól emlékszem, hogy milyen ócska kódot fordít a demó

2. LCD kezelésre van kész C kód a fordító csomagjában is, de én azokat nem szeretem, ezért arra írtam sajátot. Egyszer kell normálisra megírni, aztán újrafelhasználható lesz az is. Van itt az oldalon is ilyen kód már, nemis kell nulláról megírni. Matematikai dolgok ott vannak a math.h-ban. Időzítő (bár ha jól sejtem, inkább késleltetőről lehet szó) rutinok léteznek, valami delay.h vagy ilyesmibe nézz bele. BCD rutinokat nem láttam alapból a csomagban, ezért vagy keresel neten, vagy megírod egyszer.

3. Erre én is kíváncsi lennék, hogy lehet 32 bitnél többet kezelni egyben. Megoldani meg lehet, a kérdés csak az, hogy hogyan. Egyébként a sima long már 32 bites, a long long az 64 bites lenne, de a C18-ban tényleg csak 32 bites az is.

4. Használhatod. Ha átváltasz assemblyre, akkor ott minden úgy fog történni, ahogy assemblyben megszoktad.
(#) mps válasza Attila86 hozzászólására (») Szept 18, 2013 /
 
Szia! Nem tudom, hogy ismered e, de ez egy nagyon jó könyv a C-hez: Bővebben: Link
Következő: »»   80 / 153
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