Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

programski jezici za mikrokontrolere pitanja i odgovori

[es] :: Elektronika :: Mikrokontroleri :: programski jezici za mikrokontrolere pitanja i odgovori

Strane: < .. 1 2 3 4 5 6 7

[ Pregleda: 17779 | Odgovora: 120 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori09.08.2008. u 21:46 - pre 191 meseci
Sledi dvobajtna neoznacena varijabla (word) i konstanta. Kompajler bi morao razdvojiti konstantu u LO HI oblik i tako je ubaciti u instrukcije.

@korak
Definisite mi kako MMA uzima LO HI oblik iz dvobajtne i iz visebajtnih varijabli, kako bih kasnije pisao kod ispravnom sintaksom. Ovde sam podelio varijablu GODINA u LO_GODINA i HI_GODINA.


if GODINA > konstante 2008 (HI-7, LO-216) then inc else dec
Code:

  if GODINA > 2008 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

 $00FF : movf    HI_GODINA,W;
 $0100 : sublw   $07;
 $0101 : btfsc   STATUS,Z;
 $0102 : goto    $0107;
 $0103 : btfsc   STATUS,C;
 $0104 : goto    $010B;
 $0105 : incf    [$31],W;
 $0106 : goto    $010C;
 $0107 : movf    LO_GODINA,W;
 $0108 : sublw   $D8;
 $0109 : btfss   STATUS,C;
 $010A : goto    $0105;
 $010B : decf    [$31],W;
 $010C : nop;


if GODINA < konstante 2008 (HI-7, LO-216) then inc else dec
Code:

  if GODINA < 2008 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;


 $0101 : movlw   $07;
 $0102 : subwf   HI_GODINA,W;
 $0103 : btfsc   STATUS,Z;
 $0104 : goto    $0109;
 $0105 : btfsc   STATUS,C;
 $0106 : goto    $010D;
 $0107 : incf    [$31],W;
 $0108 : goto    $010E;
 $0109 : movlw   $D8;
 $010A : subwf   LO_GODINA,W;
 $010B : btfss   STATUS,C;
 $010C : goto    $0107;
 $010D : decf    [$31],W;
 $010E : nop;


if GODINA >= konstante 2008 (HI-7, LO-216) then inc else dec
Code:

  if GODINA >= 2008 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

  
 $00FF : movf    HI_GODINA,W;
 $0100 : sublw   $07;
 $0101 : btfsc   STATUS,Z;
 $0102 : goto    $0107;
 $0103 : btfsc   STATUS,C;
 $0104 : goto    $010B;
 $0105 : incf    [$31],W;
 $0106 : goto    $010C;
 $0107 : movlw   $D8;
 $0108 : subwf   LO_GODINA,W;
 $0109 : btfsc   STATUS,C;
 $010A : goto    $0105;
 $010B : decf    [$31],W;
 $010C : nop;


if GODINA <= konstante 2008 (HI-7, LO-216) then inc else dec
Code:

  if GODINA <= 2008 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

  
 $0101 : movlw   $07;
 $0102 : subwf   HI_GODINA,W;
 $0103 : btfsc   STATUS,Z;
 $0104 : goto    $0109;
 $0105 : btfsc   STATUS,C;
 $0106 : goto    $010D;
 $0107 : incf    [$31],W;
 $0108 : goto    $010E;
 $0109 : movf    LO_GODINA,W
 $010A : sublw   $D8;
 $010B : btfsc   STATUS,C;
 $010C : goto    $0107;
 $010D : decf    [$31],0;
 $010E : nop;


if GODINA == konstanta 2008 (HI-7, LO-216) then inc else dec
Code:

  if GODINA == 2008 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

  
 $00FF : movf    HI_GODINA,W;
 $0100 : xorlw   $07;
 $0101 : btfss   STATUS,Z;
 $0102 : goto    $0109;
 $0103 : movf    LO_GODINA,W;
 $0104 : xorlw   $D8;
 $0105 : btfss   STATUS,Z;
 $0106 : goto    $0109;
 $0107 : incf    [$31],W;
 $0108 : goto    $010A;
 $0109 : decf    [$31],W;
 $010A : nop;


if GODINA <> konstante 2008 (HI-7, LO-216) then inc else dec
Code:

  if GODINA <> 2008 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

  
 $00FF : movf    HI_GODINA,W;
 $0100 : xorlw   $07;
 $0101 : btfss   STATUS,Z;
 $0102 : goto    $0107;
 $0103 : movf    LO_GODINA,W;
 $0104 : xorlw   $D8;
 $0105 : btfsc   STATUS,Z;
 $0106 : goto    $0109;
 $0107 : incf    [$31],W;
 $0108 : goto    $010A;
 $0109 : decf    [$31],W;
 $010A : nop;



A sada konstanta i dvobajtna neoznacena varijabla (word).

if konstanta 2008 < GODINA then inc else dec
Code:

  if 2008 < GODINA then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

  
 $00FF : movf    HI_GODINA,W;
 $0100 : sublw   $07;
 $0101 : btfsc   STATUS,Z;
 $0102 : goto    $0107;
 $0103 : btfsc   STATUS,C;
 $0104 : goto    $010B;
 $0105 : incf    [$31],W;
 $0106 : goto    $010C;
 $0107 : movf    LO_GODINA,W;
 $0108 : sublw   $D8;
 $0109 : btfss   STATUS,C;
 $010A : goto    $0105;
 $010B : decf    [$31],W;
 $010C : nop;


if konstanta 2008 > GODINA then inc else dec
Code:

  if 2008 > GODINA then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;


 $0101 : movlw   $07;
 $0102 : subwf   HI_GODINA,W;
 $0103 : btfsc   STATUS,Z;
 $0104 : goto    $0109;
 $0105 : btfsc   STATUS,C;
 $0106 : goto    $010D;
 $0107 : incf    [$31],W;
 $0108 : goto    $010E;
 $0109 : movlw   $D8;
 $010A : subwf   LO_GODINA,W;
 $010B : btfss   STATUS,C;
 $010C : goto    $0107;
 $010D : decf    [$31],W;
 $010E : nop;


if konstanta 2008 <= GODINA then inc else dec
Code:

  if 2008 <= GODINA then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;


 $00FF : movf    HI_GODINA,W;
 $0100 : sublw   $07;
 $0101 : btfsc   STATUS,Z;
 $0102 : goto    $0107;
 $0103 : btfsc   STATUS,C;
 $0104 : goto    $010B;
 $0105 : incf    [$31],W;
 $0106 : goto    $010C;
 $0107 : movlw   $D8;
 $0108 : subwf   LO_GODINA,W;
 $0109 : btfsc   STATUS,C;
 $010A : goto    $0105;
 $010B : decf    [$31],W;
 $010C : nop;


if konstanta 2008 >= GODINA then inc else dec
Code:

  if 2008 >= GODINA then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

 $0101 : movlw   $07;
 $0102 : subwf   HI_GODINA,W;
 $0103 : btfsc   STATUS,Z;
 $0104 : goto    $0109;
 $0105 : btfsc   STATUS,C;
 $0106 : goto    $010D;
 $0107 : incf    [$31],W;
 $0108 : goto    $010E;
 $0109 : movf    LO_GODINA,W;
 $010A : sublw   $D8;
 $010B : btfsc   STATUS,C;
 $010C : goto    $0107;
 $010D : decf    [$31],W;
 $010E : nop;


if konstanta 2008 == GODINA then inc else dec
Code:

  if 2008 == GODINA then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

 $00FF : movf    HI_GODINA,W;
 $0100 : xorlw   $07;
 $0101 : btfss   STATUS,Z;
 $0102 : goto    $0109;
 $0103 : movf    LO_GODINA,W;
 $0104 : xorlw   $D8;
 $0105 : btfss   STATUS,Z;
 $0106 : goto    $0109;
 $0107 : incf    [$31],W;
 $0108 : goto    $010A;
 $0109 : decf    [$31],W;
 $010A : nop;


if konstanta 2008 <> GODINA then inc else dec
Code:

  if 2008 <> GODINA then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

  
 $00FF : movf    HI_GODINA,W;
 $0100 : xorlw   $07;
 $0101 : btfss   STATUS,Z;
 $0102 : goto    $0107;
 $0103 : movf    LO_GODINA,W;
 $0104 : xorlw   $D8;
 $0105 : btfsc   STATUS,Z;
 $0106 : goto    $0109;
 $0107 : incf    [$31],W;
 $0108 : goto    $010A;
 $0109 : decf    [$31],W;
 $010A : nop;


Svi kodovi su pisani iz glave (uz par prepisivanja), i nisu simulirani. Veoma je moguce da se potkrao neki bag. On ce se ipak lakse otkriti kasnije, kada se rutine ubace u MMA, i pojedinacno testiraju.
 
Odgovor na temu

korak
Nis

Član broj: 125522
Poruke: 622
*.dynamic.sbb.rs.



+7 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori10.08.2008. u 07:47 - pre 191 meseci
Ovako:

Visebajtna vrednost mora da ima mogucnost da se pristupi svakom bajtu. Ako je ona tipa longint (4 bajta) i ima vrednost $12345678 (ovo mi se vise svidja od (0x12345678, mada je to stvar ukusa). Ako je ime varijable Brojac, onda najstarijem bajtu pristupam sa Brojac.0. Dakle:

Brojac.0 = $12
Brojac.1 = $34
Brojsc.2 = $56
Brojac.3 = $78

ali ce Brojac.4 biti prijavljeno od kompajlera kao greska.

Kada 16-to bitni registar uzima vrednosti onda:

ldhx [Brojac.0]; //u HX je $1234
ldhx [Brojac.1]; //u HX je $3456
ldhx [Brojac.2]; //u HX je $5678

a ldhx [Brojac.3] ce prijaviti gresku.

Kod Motorole u smeru rasta memorijskih adresa ide prvo bajt najvece tezine, a na kraju je bajt najmanje tezine. Zato se bajtu najvece tezine pristupa sa .0 (dodaje na adresu 0 i t. d.). Kod Intela je obrnuto, a mislim da je tako i kod PIC-a, potvrdi mi ovo. Ako je tako ti pristupaj bajtu najmanje tezine sa .0 i tako redom koliko ima bajtova. Kada iza tacke stoji ime, onda se radi o pristupanju polju record tipa, to kompajler lako razlikuje.

Kada deklarises varijablu, ti je upises u neku tablicu koja sadrzi mnoge podatke o varijabli. Obavezno mora da sadrzi adresu varijable i njen tip. Kada kompajler naidje na ime te varijable, on ime zamenjuje sa adresom. Tako ako napisem

ldhx Brojac; //HX uzima adresu varijable brojac
a
ldhx [Brojac.0]; //HX uzima dva visa bajta varijable Brojac.

Ovakvu sintaksu Motorola koristi kod MC68000 i kasnijih 32-o bitnih procesora, dok kod 8-o bitnih koristi:

ldhx #Brijac; //da HX uznme adresu varijable Brojac (literal kod PIC-a)
i
ldhx Brojac; //da HX uzme dva bajta vece tezine
a
ldhx Brojac+2;//da HX uzme dva niza bajta varijable Brojac (ovde nema zastite od promasenog pristupa bajtu varijable)

Ovo mi se ne svidja, zbog jednog znaka # mogu da napravim gresku i da se ubijem trazeci ga u 10..20000 redova programa. Mnogo je teze izostaviti istovremeno obe zagrade ([ i ]) pa su i greske redje. Nisu dzabe presli na drugu sintaksu kod 32-o bitnih procesora.

 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.smin-1.sezampro.yu.



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori13.08.2008. u 16:40 - pre 191 meseci
@korak
16F serija je osmobitna, pa nema apsolutno nikakvu preddefinisanu strukturu LO/HI oblika. Potpuno je svejedno, jer se registrima može pristupati iskljucivo pojedinacno. Na programeru je da odabere koji ce format koristiti (little ili big endian). Cak su moguce i egzibicije poput cuvanja LO dela na adresi $4C a HI dela na $25.

Sledi case...of... struktura za word. Uzeo sam little endian slucaj, pa je GODINA.0 isto što i HI_GODINA, a GODINA.1 je isto što i LO_GODINA.

Code:

var shared_bank [0x70..0x7E]
  <
   GODINA  : word
  >

case GODINA of
2005, 2008, 2012..2015 : incf [49],F;
2018..2030, 2040..2050 : decf [49],F;
else clrf [49];
end;
nop;

$0100 : movf    GODINA.0,W;   // GODINA = 2005 ($07,D5)
$0101 : xorlw   $07;
$0102 : btfss   STATUS,Z;
$0103 : goto    _2008
$0104 : movf    GODINA.1,W;
$0105 : xorlw   $D5
$0106 : btfss   STATUS,Z;
$0107 : goto    $010A;

$0108 : incf    $31,W;        // inc
$0109 : goto    $0154;

$010A : movf    GODINA.0,W;   // GODINA = 2008 ($07,D8)
$010B : xorlw   $07;
$010C : btfss   STATUS,Z;
$010D : goto    $0112;
$010E : movf    GODINA.1,W;
$010F : xorlw   $D8;
$0110 : btfsc   STATUS,Z;
$0111 : goto    $0108;


$0112 : movf    GODINA.0,W;   // GODINA >= 2012($07,#DC)
$0113 : sublw   $07;
$0114 : btfsc   STATUS,Z;
$0115 : goto    $0119;
$0116 : btfsc   STATUS,C;
$0117 : goto    $0127;
$0118 : goto    $011D;
$0119 : movlw   $DC
$011A : subwf   GODINA.1,W;
$011B : btfss   STATUS,C;
$011C : goto    $0127;
$011D : movlw   $07;           // GOSINA <= 2015 ($07,$DF)
$011E : subwf   GODINA.0,W;
$011F : btfsc   STATUS,Z;
$0120 : goto    $0123;
$0121 : btfsc   STATUS,C;
$0122 : goto    $0127
$0123 : movf    GODINA.1,W;
$0124 : sublw   $DF;
$0125 : btfsc   STATUS,C;
$0126 : goto    $0108;



$0127 : movf    GODINA.0,W;   // GODINA >= 2018($07,#E2)
$0128 : sublw   $07;
$0129 : btfsc   STATUS,Z;
$012A : goto    $012E;
$012B : btfsc   STATUS,C;
$012C : goto    $013E;
$012D : goto    $0132;
$012E : movlw   $E2
$012F : subwf   GODINA.1,W;
$0130 : btfss   STATUS,C;
$0131 : goto    $013E
$0132 : movlw   $07;           // GOSINA <= 2020 ($07,$E4)
$0133 : subwf   GODINA.0,W;
$0134 : btfsc   STATUS,Z;
$0135 : goto    $0138;
$0136 : btfsc   STATUS,C;
$0137 : goto    $013E
$0138 : movf    GODINA.1,W;
$0139 : sublw   $E4;
$013A : btfss   STATUS,C;
$013B : goto    $013E

$013C : decf    $31,W;         // dec
$013D : goto    $0154;


$013E : movf    GODINA.0,W;   // GODINA >= 2040 ($07,#F8)
$013F : sublw   $07;
$0140 : btfsc   STATUS,Z;
$0141 : goto    $0145;
$0142 : btfsc   STATUS,C;
$0143 : goto    $0153;
$0144 : goto    $0149;
$0145 : movlw   $F8
$0146 : subwf   GODINA.1,W;
$0147 : btfss   STATUS,C;
$0148 : goto    $0153
$0149 : movlw   $08;           // GOSINA <= 2050 ($08,$02)
$014A : subwf   GODINA.0,W;
$014B : btfsc   STATUS,Z;
$014C : goto    $014F;
$014D : btfsc   STATUS,C;
$014E : goto    $0153
$014F : movf    GODINA.1,W;
$0150 : sublw   $02;
$0151 : btfsc   STATUS,C;
$0152 : goto    $013C;

$0153 : clrf    0x31;         // else
$0154 : nop                   // end
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori14.08.2008. u 04:30 - pre 191 meseci
repeat...until programska struktura malo je teza za word varijablu, zbog cestog postojanja potrebe direktne izmene varijable unutar strukture. Kako ne zelite ubacivati izraze u kompajler, mislim da je najbolje prepustiti sav racun asembleru, a kompajleru ostaviti samo testiranje.

Potrebno je obraditi sve moguce slucajeve (<, >, <=, >=, ==). Test razlicitosti je, mislim, ovde suvisan.

repeat GODINA + 5 until GODINA > 2050
Code:

 repeat
   movlw   5;
   addwf   LO_GODINA,F;
   btfsc   STATUS,C;
   incf    HI_GODINA,F;
 until GODINA > 2050
 nop;

$0100 : movlw   $05;
$0101 : addwf   LO_GODINA,F;      // GODINA = GODINA+5
$0102 : btfsc   STATUS,C;
$0103 : incf    HI_GODINA,F;
        
$0104 : movlw   $08;             // GODINA > 2050 ($08,$02)?
$0105 : subwf   HI_GODINA,W;
$0106 : btfsc   STATUS,Z;
$0107 : goto    $010B;
$0108 : btfsc   STATUS,C;
$0109 : goto    $0100;
$010A : goto    $010F;
$010B : movf    LO_GODINA,W
$010C : sublw   $02;
$010D : btfsc   STATUS,C;
$010E : goto    $0100;
$010F : nop;



repeat GODINA + 5 until GODINA >= 2050
Code:

 repeat
   movlw   5;
   addwf   LO_GODINA,F;
   btfsc   STATUS,C;
   incf    HI_GODINA,F;
 until GODINA >= 2050
 nop;

$0100 : movlw   $05;
$0101 : addwf   LO_GODINA,F;      // GODINA = GODINA+5
$0102 : btfsc   STATUS,C;
$0103 : incf    HI_GODINA,F;

$0104 : movlw   $08;              // GODINA >= 2050?
$0105 : subwf   HI_GODINA,W;
$0106 : btfsc   STATUS,Z;
$0107 : goto    $010B;
$0108 : btfsc   STATUS,C;
$0109 : goto    $0100;
$010A : goto    _nop;
$010B : movlw   $02;
$010C : subwf   LO_GODINA,W
$010D : btfsc   STATUS,C;
$010E : goto    $0100;
$010F : nop



repeat GODINA - 5 until GODINA < 2000
Code:

 repeat
   movlw   5;
   subwf   LO_GODINA,F;
   btfsc   STATUS,C;
   decf    HI_GODINA,F;
 until GODINA < 2000
 nop;

$0100 : movlw   $05;              // GODINA = GODINA-5
$0101 : subwf   LO_GODINA,F;
$0102 : btfsc   STATUS,C;
$0103 : decf    HI_GODINA,F;

$0104 : movlw   $07;              // GODINA < 2000 ($07,$DA)?
$0105 : subwf   HI_GODINA,W;
$0106 : btfsc   STATUS,Z;
$0107 : goto    $010B;
$0108 : btfsc   STATUS,C;
$0109 : goto    $010F;
$010A : goto    $0100;
$010B : movlw   $DA;
$010C : subwf   LO_GODINA,W
$010D : btfss   STATUS,C;
$010E : goto    $0100;
$010F : nop



repeat GODINA - 5 until GODINA <= 2000
Code:

 repeat
   movlw   5;
   subwf   LO_GODINA,F;
   btfsc   STATUS,C;
   decf    HI_GODINA,F;
 until GODINA <= 2000
 nop;

$0100 : movlw   $05;              // GODINA = GODINA-5
$0101 : subwf   LO_GODINA,F;
$0102 : btfsc   STATUS,C;
$0103 : decf    HI_GODINA,F;

$0104 : movlw   $07;              // GODINA <= 2000 ($07,$DA)?
$0105 : subwf   HI_GODINA,W;
$0106 : btfsc   STATUS,Z;
$0107 : goto    $010B;
$0108 : btfsc   STATUS,C;
$0109 : goto    $010F;
$010A : goto    $0100;
$010B : movf    LO_GODINA,W
$010C : sublw   $DA;
$010D : btfsc   STATUS,C;
$010E : goto    $0100;
$010F : nop



repeat GODINA + 1 until GODINA == 2050
Code:

 repeat
   incf    LO_GODINA,F;
   btfsc   STATUS,Z;
   incf    HI_GODINA,F;
 until GODINA == 2050
 nop;

$0100 : incf    LO_GODINA,F;     // GODINA = GODINA+1
$0101 : btfsc   STATUS,Z;
$0102 : incf    HI_GODINA,F;

$0103 : movf    HI_GODINA,W;     //  GODINA == 2050 ($08,$02)?
$0104 : xorlw   $08;
$0105 : btfss   STATUS,Z;
$0106 : goto    $010B;
$0107 : movf    LO_GODINA,W;
$0108 : xorlw   $02;
$0109 : btfsc   STATUS,Z;
$010A : goto    $0100;
$010B : nop;
 
Odgovor na temu

korak
Nis

Član broj: 125522
Poruke: 622
*.dynamic.sbb.rs.



+7 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori14.08.2008. u 09:09 - pre 191 meseci
Bez obzira sto je mikrokontroler 8-o bitni, cak je za njega to vaznije, on obradjuje u visebajtne podatke. Programer mora oznaciti koji bajt visebajtnog podatka trenutn obradjuje. Zato sam uveo notaciju o kojoj san oisao. 32-o bitnim mikrokontrolerima to ne treba, oni ce uzeti u obradu odjednom 4 bajta.

U if..then..else kao uslov uzimas ceo izraz (GODINA > 2050) ali ne valja ako ga ogranicavas. Sa druge strane ako imas komplikovan izraz onda kompajler mora da prevodi izraze, a onda na kraju jrajeva svi asemblerski iskazi mogu da budu zamenjeni takvim izrazima, i vec si napustio asembler i imas neki visi programski jezik.

Moj pristup je da napises kod koji oduzima od GODINA vrednost 2050, u asembleru, a onda napises samo if > then.

Inace sve si dobro napisao, ostaje samo da se napravi kompajler koji ce sam da generise kod koji si naoisao.

Pozdrav.

Na odmoru sam od danas 7 dana.
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori23.08.2008. u 20:06 - pre 191 meseci
Mislim da se nismo najbolje razumeli. PIC16 serija apsolutno nema ijednu instrukciju (niti adresni mod) kojom bi bilo moguce adresiranje dva bajta. Takodje nema ni "povlascene" sesnaestobitne registre (kao sto AVR ima X, Y i Z).

Znaci za sledecu situaciju:
Code:

var bank 0 [0x20..0x6F]
  <
   GODINA : word
  >

je potpuno svejedno da li ce GODINA.0 biti HI ili LO bajt. Neka bude kako je zgodnije za kompajler.

Sledi if...then...else... struktura za dve dvobajtne varijable (word). Namerno sam pisao LO_GODINA1 umesto npr. GODINA1.0 jer je zamena laka (Edit - Replace), a lakse je za razumevanje.

if GODINA1 >= GODINA2 then inc else dec
Code:

$0100 : movf    HI_GODINA1,W;
$0101 : subwf   HI_GODINA2,W;
$0102 : btfsc   STATUS,Z;
$0103 : goto    $0108;
$0104 : btfsc   STATUS,C;
$0105 : goto    $010C;
$0106 : incf    $31,W;
$0107 : goto    $010D;
$0108 : movf    LO_GODINA2,W;
$0109 : subwf   LO_GODINA1,W;
$010A : btfsc   STATUS,C;
$010B : goto    $0106;
$010C : decf    $31,W;
$010D : nop;


if GODINA1 <= GODINA2 then inc else dec
Code:

$0100 : movf    HI_GODINA1,W;
$0101 : subwf   HI_GODINA2,W;
$0102 : btfsc   STATUS,Z;
$0103 : goto    $0108;
$0104 : btfss   STATUS,C;
$0105 : goto    $010C;
$0106 : incf    $31,W;
$0107 : goto    $010D;
$0108 : movf    LO_GODINA1,W;
$0109 : subwf   LO_GODINA2, W;
$010A : btfsc   STATUS,C;
$010B : goto    $0106;
$010C : decf    $31,W;
$010D : nop;


if GODINA1 > GODINA2 then inc else dec
Code:

$0100 : movf    HI_GODINA1,W;
$0101 : subwf   HI_GODINA2,W;
$0102 : btfsc   STATUS,Z;
$0103 : goto    $0108;
$0104 : btfsc   STATUS,C;
$0105 : goto    $010E;
$0106 : incf    $31,W;
$0107 : goto    $010F;
$0108 : movf    LO_GODINA2,W;
$0109 : subwf   LO_GODINA1,W;
$010A : btfsc   STATUS,Z;
$010B : goto    $010E;
$010C : btfsc   STATUS,C;
$010D : goto    $0106;
$010E : decf    $31,W;
$010F : nop;


if GODINA1 < GODINA2 then inc else dec
Code:

$0100 : movf    HI_GODINA1,W;
$0101 : subwf   HI_GODINA2,W;
$0102 : btfsc   STATUS,Z;
$0103 : goto    $0108;
$0104 : btfss   STATUS,C;
$0105 : goto    $010E;
$0106 : incf    $31,W;
$0107 : goto    $010F;
$0108 : movf    LO_GODINA1,W;
$0109 : subwf   LO_GODINA2,W;
$010A : btfsc   STATUS,Z;
$010B : goto    $010E;
$010C : btfsc   STATUS,C;
$010D : goto    $0106;
$010E : decf    $31,W;
$010F : nop;


if GODINA1 == GODINA2 then inc else dec
Code:

$0100 : movf    HI_GODINA1,W;
$0101 : xorwf   HI_GODINA2,W;
$0102 : btfss   STATUS,Z;
$0103 : goto    $010A;
$0104 : movf    LO_GODINA1,W;
$0105 : xorwf   LO_GODINA2,W;
$0106 : btfss   STATUS,Z;
$0107 : goto    $010A;
$0108 : incf    $31,W;
$0109 : goto    $010B;
$010A : decf    $31,W;
$010B : nop;


if GODINA1 <> GODINA2 then inc else dec
Code:

$0100 : movf    HI_GODINA1,W;
$0101 : xorwf   HI_GODINA2,W;
$0102 : btfss   STATUS,Z;
$0103 : goto    $0106;
$0104 : incf    $31,W;
$0105 : goto    $010B;
$0106 : movf    LO_GODINA1,W;
$0107 : xorwf   LO_GODINA2,W;
$0108 : btfss   STATUS,Z;
$0109 : goto    $0104;
$010A : decf    $31,W;
$010B : nop;
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori23.08.2008. u 22:01 - pre 191 meseci
Uops, provukla mi se losa optimizacija (dve instrukcije duza) kod primera sa < i >.
Trebali bi biti ovakvi:

if GODINA1 < GODINA2 then inc else dec
Code:

$0100 : movf    HI_GODINA1,W;
$0101 : subwf   HI_GODINA2,W;
$0102 : btfsc   STATUS,Z;
$0103 : goto    $0108;
$0104 : btfsc   STATUS,C;
$0105 : goto    $010C;
$0106 : decf    $31,W;
$0107 : goto    $010D;
$0108 : movf    LO_GODINA2,W;
$0109 : subwf   LO_GODINA1,W;
$010A : btfsc   STATUS,C;
$010B : goto    $0106;
$010C : incf    $31,W;
$010D : nop;



if GODINA1 > GODINA2 then inc else dec
Code:

$0100 : movf    HI_GODINA1,W;
$0101 : subwf   HI_GODINA2,W;
$0102 : btfsc   STATUS,Z;
$0103 : goto    $0108;
$0104 : btfss   STATUS,C;
$0105 : goto    $010C;
$0106 : decf    $31,W;
$0107 : goto    $010D;
$0108 : movf    LO_GODINA1,W;
$0109 : subwf   LO_GODINA2,W;
$010A : btfsc   STATUS,C;
$010B : goto    $0106;
$010C : incf    $31,W;
$010D : nop;
 
Odgovor na temu

korak
Nis

Član broj: 125522
Poruke: 622
89.216.105.*



+7 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori24.08.2008. u 11:03 - pre 191 meseci
Da, nismo se razumeli.

Ako je MCU 8-o bitni a treba da obradjuje podatke koji su u opstem slucaju visebajtni, onda sintaksa kompajlera treba da to omoguci programeru. Kada deklarises varijablu GODINA, kompajler imenu GODINA dodeljuje u jednoj tablici imena adresu na kojoj pocinje varijabla, tip vatijable (iz cega proistice i duzina u bajtovima) i t. d. Kada napises u programu ime GODINA, kompajler ga odnah zamenjuje njegovom adresom. Dakle:

movf GODINA,W;

ce u W staviti prvi bajt od varijable GODINA u W. Ali kako se GODINA sastoji od 2 bajta, a ti zelis onaj drugi, mozes to sa:

movf GODINA+1,W;

i u W ce biti bajt sa adrese za 1 vece od one koja je pridruzena varijabli GODINA, dakle onaj koji ti treba.

Ja sam samo uveo sintaksu u kojoj je GODINA i GODINA.0 isto, a drugom bajtu se pristupa sa GODINA.1.

Ti umesto jedne varijable GODINA uvodis dve HI_GODINA i LO_GODINA, sto je potpuno nepotrebno, neprakticno i nepregledno, sto znaci i da je vise podlozno gresci.

Sta raditi sa varijablom koja ima 4 bajta? Na primer imas brojac ciklusa koje obavi jedna masina i to cuvas u varijabli:

BrCiklusa : longWord; //cetvorobajtna varijabla

Uvek svakom bajtu ove varijable mozes da pristupis sa BrCiklusa.0, BrCiklusa.1, BrCiklusa.2 i BrCiklusa.3.

Suprotno ovome, MCU koji je 32-o bitni ne mora to da radi jer on odmah pristupa celoj varijabli BrCikljusa. Dakle, ova sintaksa je upravo namenjena 8-o bitnim MCU-ovima.

Pozdrav.
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori24.08.2008. u 13:38 - pre 191 meseci
Kazem, konverzija je laka, i svakako da je sintaksa koju predlazete bolja. LO_GODINA i HI_GODINA napisao sam samo zbog ostalih clanova foruma (nismo sami) kako bi po potrebi mogli koristiti ove strukture u svojim programima. Za NJIH je LO HI oblik razumljiviji, jer ne moraju lutati po postovima i traziti da li je LO_GODINA isto sto i GODINA,0.
 
Odgovor na temu

korak
Nis

Član broj: 125522
Poruke: 622
89.216.105.*



+7 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori24.08.2008. u 16:27 - pre 191 meseci
OK,

logicno je. Ali ne mislim da treba stalno da se drzimo nekih davnasnjih stvari koje je neko mozda slucajno tako definisao. Oko nas se sve menja, pa treba dati oduska kreativnosti i ici napred. Ko ima problem da shvati, treba mu objasniti. Samo tako se obezbedjuje napredak. U suprotnom bice u pravu globalisti koji kazu da predstoji vreme bez istorije, a to ce biti vreme kada ce sve da stane i nista se novo nece desavati.

Umetnik nikada ne pravi dva ista dela, uvek pravi nova i nova, a to treba da vazi za svaku profesiju.

Pozdrav.
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori25.08.2008. u 21:43 - pre 191 meseci
Sledi repeat...until... struktura uz poredjenje dve dvobajtne varijable (word).

GODINA.0 je bajt vece (HI), a GODINA.1 je bajt manje tezine(LO).


repeat GODINA1 + 4 until GODINA1 > GODINA2
Code:

repeat
   movlw   4;
   addwf   GODINA1.1,F;
   btfsc   STATUS,C;
   incf    GODINA1.0,F;
until GODINA1 > GODINA2
nop;

$0100 : movlw   $04;
$0101 : addwf   GODINA1.1,F;      // GODINA1 = GODINA1+4
$0102 : btfsc   STATUS,C;
$0103 : incf    GODINA1.0,F;

$0104 : movf    GODINA1.0,W;      // GODINA1 > GODINA2?
$0105 : subwf   GODINA2.0,W;
$0106 : btfsc   STATUS,Z;
$0107 : goto    $010B;
$0108 : btfss   STATUS,C;
$0109 : goto    $010F;
$010A : goto    $0100;
$010B : movf    GODINA1.1,W;
$010C : subwf   GODINA2.0,W;
$010D : btfsc   STATUS,C;
$010E : goto    $0100;
$010F : nop;



repeat GODINA1 + 4 until GODINA1 >= GODINA2
Code:

repeat
   movlw   4;
   addwf   GODINA1.1,F;
   btfsc   STATUS,C;
   incf    GODINA1.0,F;
until GODINA1 >= GODINA2
nop;

$0100 : movlw   $04;
$0101 : addwf   GODINA1.1,F;      // GODINA1 = GODINA1+4
$0102 : btfsc   STATUS,C;
$0103 : incf    GODINA1.0,F;

$0104 : movf    GODINA1.0,W;      // GODINA1 >= GODINA2?
$0105 : subwf   GODINA2.0,W;
$0106 : btfsc   STATUS,Z;
$0107 : goto    $010B;
$0108 : btfss   STATUS,C;
$0109 : goto    $010F;
$010A : goto    $0100;
$010B : movf    GODINA2.0,W;
$010C : subwf   GODINA1.1,W;
$010D : btfss   STATUS,C;
$010E : goto    $0100;
$010F : nop;



repeat GODINA1 - 5 until GODINA1 < GODINA2
Code:

repeat
   movlw   5;
   subwf   GODINA1.1,F;
   btfss   STATUS,C;
   decf    GODINA1.0,F;
until GODINA1 < GODINA2
nop;

$0100 : movlw   $05;
$0101 : subwf   GODINA1.1,F;      // GODINA1 = GODINA1-5
$0102 : btfss   STATUS,C;
$0103 : decf    GODINA1.0,F;

$0104 : movf    GODINA1.0,W;      // GODINA1 < GODINA2?
$0105 : subwf   GODINA2.0,W;
$0106 : btfsc   STATUS,Z;
$0107 : goto    $010B;
$0108 : btfsc   STATUS,C;
$0109 : goto    $010F;
$010A : goto    $0100;
$010B : movf    GODINA2.0,W;
$010C : subwf   GODINA1.1,W;
$010D : btfsc   STATUS,C;
$010E : goto    $0100;
$010F : nop;



repeat GODINA1 - 5 until GODINA1 <= GODINA2
Code:

repeat
   movlw   5;
   subwf   GODINA1.1,F;
   btfss   STATUS,C;
   decf    GODINA1.0,F;
until GODINA1 <= GODINA2
nop;

$0100 : movlw   $05;
$0101 : subwf   GODINA1.1,F;      // GODINA1 = GODINA1-5
$0102 : btfss   STATUS,C;
$0103 : decf    GODINA1.0,F;

$0104 : movf    GODINA1.0,W;      // GODINA1 <= GODINA2?
$0105 : subwf   GODINA2.0,W;
$0106 : btfsc   STATUS,Z;
$0107 : goto    $010B;
$0108 : btfsc   STATUS,C;
$0109 : goto    $010F;
$010A : goto    $0100;
$010B : movf    GODINA1.1,W;
$010C : subwf   GODINA2.0,W;
$010D : btfss   STATUS,C;
$010E : goto    $0100;
$010F : nop;



repeat GODINA1 - 1 until GODINA1 = GODINA2
Code:

repeat
   decfsz   GODINA1.1,F;
   goto     $+2;
   decf     GODINA1.0,F;
until GODINA1 = GODINA2
nop;

$0100 : decfsz  GODINA1.1,F;      // GODINA1 = GODINA1-1
$0101 : goto    $+2;
$0102 : decf    GODINA1.0,F;

$0103 : movf    GODINA1.0,W;      // GODINA1 = GODINA2?
$0104 : xorwf   GODINA2.0,W;
$0105 : btfss   STATUS,Z;
$0106 : goto    $0100;
$0107 : movf    GODINA1.1,W;
$0108 : xorwf   GODINA2.0,W;
$0109 : btfss   STATUS,C;
$010A : goto    $0100;
$010B : nop;



Mislim da je test razlicitosti i ovde suvisan.

Korak, mislim da bi bilo prakticno (a svakako bi bilo lakse) da umesto kompletnog kompajlera za PIC napravite samo preprocesor. Znaci, on bi samo raspakovao osnovne programske strukture (eventualno bi ubacio svoje nazive registara, labele i komentare kako bi korisnik znao da ne cacka taj deo koda), a sve ostalo bi samo prekopirao i dobio novi .asm fajl. Na taj nacin omogucio bi naknadnu izmenu koda standardnim (i besplatnim) microchipovim alatima, uz zadrzavanje asemblerske snage osnovnih programskih struktura. Korisniku je ovo samo par klika dalje.
 
Odgovor na temu

korak
Nis

Član broj: 125522
Poruke: 622
89.216.105.*



+7 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori26.08.2008. u 12:05 - pre 191 meseci
Vidim da razumes u potpunosti sta treba da bude rezultat onoga sto treba da uradi komapajler, a vidim da imas i volju za to.

Skrenuo bih ti paznju na sledece. if..then i repeat..until struktura imaju svoj uslov koji je izraz. Napisati until Izraz, dovodi do toga da kompajler mora da prevodi izraze, a tada vec zalazimo u sveru visih programskih jezika. Ja sam izabrao da se taj izraz napise na asembleru, a da se kao uslov koristi stanje flega.

dakle until GODINA1 > GODINA2, zahteva da kompajler prevede izraz iza until. Ja to radim tako sto ispred until (znaci na kraju petlje) u asembleru izrazunam ovaj izraz pa tako da imam samo until >; Kompajler samo treba da na oznovu znaka uslova '>' ubaci potrebnu naredbu uslovnog skoka. Na ovaj nacin petlju mozes ubrzati, ako je GODINA1.0 > GODINA2.0 odmah izlazis iz petlje, a ako ne, vec je GODINA1.0 = GODINA2.0, onda izlazis iz petlje ako je GODINA1.0 > GODINA2.0.

Sto se tvog predloga tice, imam jednu ideju, alo ne znam dali da je realizujem. Ako bi je realizovao onda bih naptavio kompajler za bilo koji MCU. Sam programer bi napravio pomocu makroa sve naredbe svog MCU-a. Jedini mi je problem kako bi onda trebalo da definisem disassembler i softverski simulator, ako bi i to resio, mozda bi se odlucio da ubacim i tu opciju u svoj kompajler.

Pozdrav
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori26.08.2008. u 18:42 - pre 191 meseci
Jeste. GODINA1 < GODINA2 je svakako izraz, ali ukoliko je vec taj izraz maksimalno optimizovan pri prevodjenju u asembler, koga je briga za to. Svi grese. I meni se u pretproslom postu potkrala losa optimizacija. Ovako prevedeni izrazi bili bi maksimalno optimizovani u okviru date programske strukture, programer bi ih brze napisao, razumljiviji su, ne bi se koristile labele pa sto se onda ne bi koristili! Zamislite tek rucni kod za poredjenje longword varijabli! U svakom slucaju kao programer bih zeleo da izbegnem njegovo pisanje od nule, pa makar koristio copy/paste metod. Jeste, zagazilo bi se malo u oblast visih programskih jezika, ali upravo zato sam u proslom postu predlozio samo preprocesor umesto kompletnog kompajlera.

Problem sa flegovima je sto PIC16 serija jednostavno nema dovoljno flegova u STATUS registru (od koristi za strukture su samo Zero i Carry) kojima bi se odgovarajuci test mogao nedvosmisleno predstaviti njihovim stanjem, a samim tim ni odgovarajuce instrukcije uslovnog skoka. U strukturama koje sam napisao uslovni skok se nekad obavlja sa setovanim, a nekad sa resetovanim Carry flegom. Mogao bih u zavisnosti od rezultata osnovnih izraza postavljati bitove (koji bi sluzili kao flagovi C, Z, N, V) u posebnom registru, ali tek bi to onda licilo na visi programski jezik.

PIC18 serija je tu mocnija jer ima obilje instrukcija uslovnog skoka (kao AVR).

Mislim da Vam se potkrala greska ovde: "Na ovaj nacin petlju mozes ubrzati, ako je GODINA1.0 > GODINA2.0 odmah izlazis iz petlje, a ako ne, vec je GODINA1.0 = GODINA2.0, onda izlazis iz petlje ako je GODINA1.0 > GODINA2.0.". To bi valjda trebalo da glasi ovako "Na ovaj nacin petlju mozes ubrzati, ako je GODINA1.0 > GODINA2.0 odmah izlazis iz petlje, a ako ne, vec je GODINA1.0 = GODINA2.0, onda izlazis iz petlje ako je GODINA1.1 > GODINA2.1.".
To nisam mogao implementirati u izrazima, jer se Carry menja (setuje ili resetuje, u zavisnosti od toga kako je realizovano oduzimanje) i ukoliko je rezultat oduzimanja 0. Zato sam morao najpre testirati jednakost (Zero flag), pa tek onda (kada GODINA1.0 nije isto sto i GODINA2.0) prekoracenje. Bilo bi brze kada bi PIC16 serija imala instrukciju uslovnog skoka koja istovremeno testira i Carry i Zero fleg, ali eto, nema je. U svakom slucaju ovo jeste maksimalna moguca optimizacija za PIC16 seriju.

Kompajler za bilo koji mikrokontroler? Pa jos i simulator? Mislim da je ovo preveliki posao (bez uvrede) za jednog coveka.
Jos jedna prednost preprocesora bila bi sto je moguce koristiti gotove asemblerske rutine (iz Microchipovih Aplication Notes ili sa neta), i odmah simulirati njihovo izvodjenje MPLAB SIM-om. Da bi ovo bilo moguce u Vasem kompajleru, bilo bi potrebno ubaciti u kompajler sve moguce direktive koje standardno podrzava Microchipov MPASM asembler (sa svim svojim specificnostima), a to je ipak preveliki posao. Mene na primer uopste ne interesuje kako radi Microchipova rutina za mnozenje dva broja. Za mene je ona "black box". Najpre je testiram (da li stvarno radi i koliko dobro), onda je kopiram, pozovem u okviru potprograma i to je sve.
 
Odgovor na temu

korak
Nis

Član broj: 125522
Poruke: 622
*.dynamic.sbb.rs.



+7 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori27.08.2008. u 13:19 - pre 191 meseci
Da, omakla mi se greska jer sam kopirao prvi izraz, a u drugom nisam umeso 0 stavio 1, hvala na ispravci. U pravu si da bi ovakav metod ispitivanja bio komplikovan za PIC16, ali sam ga naveo kao mogucnost.

A kompajler za sve MCU-ove nije problem, problem je samo disasembler i simulator. Kompajler bi lako generisao kod jer bi u jednom modulu bili makroi za sve naredbe zeljenog MCU-a. Ime makroa bi bilo ime asemblerske naredbe, a u samom makrou bi se generisao kod za du naredbu. Moj kompajler je tako koncipiran da to ne bi bilo tesko, osim dosadnog pisanja drfinicija svih naredbi. Problem je zaista disasembler koji iz koda treba da prepozna naredbu, a ako mu to nije definisano on to ne moze ni da uradi. Isto se odnosi i na softverski simulator. Mogu da predpostavim da disasembler i nije toliko neophodan, ali ne znam koliko programera koristi softverski simulator i koliko je on potreban. Eto to mi je dilema.

Pozdrav.
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori27.08.2008. u 21:22 - pre 191 meseci
A sto ne probate promeniti pristup? Umesto da makroi generisu .hex, neka generisu .asm kod, ili eventualno oba fajla istovremeno. Tako se ne bi izgubila osnovna korisnicki definisana struktura koda (prazni redovi i komentari ostali bi u .asm kodu na mestima gde su bili u source fajlu).

Mmmmmmmm Simulator!
Licno ga dosta koristim. Medjutim, ne bi li posao oko njegovog razvoja bio previse veliki? Jeste da ga u osnovi cine sitnice, ali ima ih previse. Pa jos za bilo koji mikrokontroler!!!
MPLAB SIM na primer u PIC16 seriji cak nema mogucnost simuliranja tajmer 1 modula jer on koristi sopstveni kristalni oscilator. Ovo bi pak bilo jednostavno dodati, ali, to bi zahtevalo izmenu programskog menija, dodavanje jos jednog oscilatora, njegove stoperice, njegovu (sto je moguce precizniju) sinhronizaciju sa glavnim oscilatorom prilikom simulacije, novih pravila stimulusa... Previse posla.
Ukoliko ima ikoga ko se bavi mikrokontrolerima a ne koristi simulator, neka ga obavezno nauci.

Evo, danas sam na primer simulirao deo koda objavljenog u prethodnim postovima, i nasao gomilu gresaka. Nazalost, MPLAB SIM ne prihvata oblik GODINA.0 (jer tacka prefiksa u njemu oznacava decimalni broj), pa se mozda opet potkrala neka. Postovacu izmene ovde, kada proverim sav kod.

Ne razumem sta je to toliko tesko oko disasemblera. Pa binarni kod svake instrukcije je potpuno nedvosmisleno predstavljen. Moguce da bi Vam problem predstavljali imenovani registri cije nazive bi morali cupati iz modula sa njihovim definicijama, ili pak potreba za disasembliranjem samo delova koda (neophodna kod Fon Nojmanove arhitekture da ne bi otpocelo disasembliranje od polovine instrukcije).
 
Odgovor na temu

korak
Nis

Član broj: 125522
Poruke: 622
*.dynamic.sbb.rs.



+7 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori28.08.2008. u 14:06 - pre 191 meseci
Da bi se bolje razumeli pokusacu da dam primer kako bi moj kompajler (koji je inace za MC9S08 i MC908) generisao kod recimo za PIC.

macro addwf s;
begin
P1 := KonstVrd(s);

_if Leks.Vrednost <> ',' then ErrorMSG('Nedostaje zarez');
Leks;

P2 := KonstVrd(s);

_if P1 > 127 then ErrorMSG('Prevelika adresa');
_if not(P2 in['f','w']) then ErrorMSG('Neispravno odrdiste');
_if P2 = 'f' then P1 := P1+128;

(7,P1);
end;

Kada napises addwf GODINA.1,f onda se ukljucuje makro addwf sa vrednoscu stringa s = 'GODINA.1,f'. Funkcija KonstVrd(s) analizira string s pomocu proceure Leks, koja izdvaja leksicke simbole. U primeru, ona ce izdvojiti prvo GODINA.1 (kao ime) a onda separator ','. Tako ce KonstVrd da da adresu za GODINA.1 sto ce biti dodeljeno u P1. Pri tome Leks.Vrednost je ',' sto se proverava, a string s je ',f'. Sledeci poziv procedure Leksika dovodi string s na vrednost 'f' sto se preko KonstVrd(s) dodeljuje kao karakter u P2. Dalja analiza i kontrola vrednosti P1 i P2 je jasna. Na kraju kada se nesto napise izmedju malih zagrada, to kompajler direktno upisuje u programsku memoriju. U primeru je to kod i parametar za napisanu asemblersku naredbu.

Ovako bi se definisale sve asemblerske naredbe PIC-a ili nekog drugog MCU-a. Problem je kako sada napraviti disasembler koji ce $07 i P1 da prepozna addwf GODINA.1,f. Jos je veci problem simulator.

Pozdrav.
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori28.08.2008. u 16:56 - pre 191 meseci
Aha, znaci problem je kako zadrzati (imenovane) registre unutar disasemblovanog fajla!

Najjednostavniji nacin bi podrazumevao da se kao izlaz makroa addwf instrukcije doda jos par parametara. Tacnije, najlakse bi bilo dodati samo "addwf "+(originalni string s) kao izlazni parametar, pre bilo kakvog poziva Leks i Leksika procedura. Ja bih pak ovde kao izlazni parametar dodao i kompletne komentare (od pocetka do kraja), kako bi se i oni zadrzali u disasemblovanom fajlu.

Ne vidim da bi bilo koji drugi nacin bio dovoljno dobar zbog nemogucnosti prepoznavanja odgovarajuce banke. Drugim recima ukoliko postoje dva registra sa istom adresom, a unutar razlicitih banaka, disasembler ne bi znao kojoj banci da im pridruzi imena. Vidjao sam disasemblere koji na primer uvek pominju PORTA umesto TRISA (na istoj su adresi gledano u kodu instrukcije).
 
Odgovor na temu

korak
Nis

Član broj: 125522
Poruke: 622
*.dynamic.sbb.rs.



+7 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori29.08.2008. u 11:25 - pre 191 meseci
Da u pravu si, odmah moze i da se generise fajl sa disasemblerskim tekstom, gde bi mu se linije dodavale u svakom makrou.

Dakle, ostaje mi vazniji problem, a to je simulator.

Pozdrav.
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori29.08.2008. u 19:26 - pre 191 meseci
Sledi deo trobajtnih poredjenja. Kako mi je sintaksa sa rednim brojevima programske memorije nezgodna zbog simulacije, preci cu na oznacavanje sa labelama. Za kompajler ovo ne bi trebalo da bude bitno, jer bi on ipak sam sukcesivno dodeljivao programsku memoriju, a bitne su mu samo tacke skokova koje su ionako ovde oznacene labelama.

Labele sam namerno oznacavao sa donjom crtom prefiksa jer su THEN i ELSE rezervisane reci u MPLAB asembleru, pa bi smetale simulaciji.

if BROJ > 10000000 (0-152, 1-150, 2-128) then inc else dec
Code:

                movf    BROJ.0,W
                sublw   d'152'
                btfsc   STATUS,Z
                goto    _eq0
                btfsc   STATUS,C
                goto    _else
_then           incf    0x31,W
                goto    _end

_eq0            movf    BROJ.1,W
                sublw   d'150'
                btfsc   STATUS,Z
                goto    _equal
                btfss   STATUS,C
                goto    _then
                goto    _else

_equal          movf    BROJ.2,W
                sublw   d'128'
                btfss   STATUS,C
                goto    _then
_else           decf    0x31,W
_end            nop



if BROJ >= 10000000 (0-152, 1-150, 2-128) then inc else dec
Code:

                movf    BROJ.0,W
                sublw   d'152'
                btfsc   STATUS,Z
                goto    _eq0
                btfsc   STATUS,C
                goto    _else
_then           incf    0x31,W
                goto    _end

_eq0            movf    BROJ.1,W
                sublw   d'150'
                btfsc   STATUS,Z
                goto    _equal
                btfss   STATUS,C
                goto    _then
                goto    _else

_equal          movlw   d'128'
                subwf   BROJ.2,W
                btfsc   STATUS,C
                goto    _then
_else           decf    0x31,W
_end            nop



if BROJ < 10000000 (0-152, 1-150, 2-128) then inc else dec
Code:

                movf    BROJ.0,W
                sublw   d'152'
                btfsc   STATUS,Z
                goto    _eq0
                btfss   STATUS,C
                goto    _else
_then           incf    0x31,W
                goto    _end

_eq0            movf    BROJ.1,W
                sublw   d'150'
                btfsc   STATUS,Z
                goto    _equal
                btfsc   STATUS,C
                goto    _then
                goto    _else

_equal          movlw   d'128'
                subwf   BROJ.2,W
                btfss   STATUS,C
                goto    _then
_else           decf    0x31,W
_end            nop



if BROJ <= 10000000 (0-152, 1-150, 2-128) then inc else dec
Code:

                movf    BROJ.0,W
                sublw   d'152'
                btfsc   STATUS,Z
                goto    _eq0
                btfss   STATUS,C
                goto    _else
_then           incf    0x31,W
                goto    _end

_eq0            movf    BROJ.1,W
                sublw   d'150'
                btfsc   STATUS,Z
                goto    _equal
                btfsc   STATUS,C
                goto    _then
                goto    _else

_equal          movf    BROJ.2,W
                sublw   d'128'
                btfsc   STATUS,C
                goto    _then
_else           decf    0x31,W
_end            nop



if BROJ == 10000000 (0-152, 1-150, 2-128) then inc else dec
Code:

                movf    BROJ.0,W
                xorlw   d'152'
                btfss   STATUS,Z
                goto    _else

                movf    BROJ.1,W
                xorlw   d'150'
                btfss   STATUS,Z
                goto    _else

                movf    BROJ.2,W
                xorlw   d'128'
                btfss   STATUS,Z
                goto    _else

_then           incf    0x31,W
                goto    _end
_else           decf    0x31,W
_end            nop



if BROJ <> 10000000 (0-152, 1-150, 2-128) then inc else dec
Code:

                movf    BROJ.0,W
                xorlw   d'152'
                btfss   STATUS,Z
                goto    _then

                movf    BROJ.1,W
                xorlw   d'150'
                btfss   STATUS,Z
                goto    _then

                movf    BROJ.2,W
                xorlw   d'128'
                btfsc   STATUS,Z
                goto    _else

_then           incf    0x31,W
                goto    _end
_else           decf    0x31,W
_end            nop


Uzgred, Vasa sintaksa oznacavanja bajtova unutar visebajtnih varijabli unutar .asm fajla bila bi dosta nezgodna za naknadno asembliranje i simulaciju standardnim Microchipovim alatima. Tacnije, korisnik bi morao (edit/replace opcijom) zameniti GODINA.1 u npr. GODINA1 ili GODINA_1 jer je kako sam ranije napomenuo tacka rezervisana za decimalne brojeve. Ipak, mislim da se MPLAB SIM simulator previse koristi da bi mogao biti tek tako ignorisan. Da ne biste menjali strukturu celog kompajlera, najlakse resenje bi bilo (ukoliko zelite to uraditi) da u makrou instrukcije izmenite string s.

Mislim da je pravljenje sopstvenog simulatora previse komplikovan zadatak. Jednostavno, tesko da biste mogli u jednom projektu objediniti sve HARDVERSKE specificnosti, poput na primer integrisane RS232 veze. MPLAB SIM ima na primer cak i mogucnost simulacije AD konverzije sukcesivnim ucitavanjem unapred zadatih vrednosti iz eksternog fajla pri svakoj AD konverziji (Register Injection tab u Stimulus-u), ili snimanje stanja registara u eksternom fajlu (Registar Trace tab). Ne kazem da nije moguce, vec da je komplikovano, i da uvek iskrsavaju nove i nove sitnice.

U prilogu prilazem sve do sada postovane, a ispravljene kodove.
Prikačeni fajlovi
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori12.09.2008. u 09:25 - pre 190 meseci
Nastavljam sa trobajtnim CASE i REPEAT...UNTIL strukturama.


Code:

case BROJ of
  10000000, 11000000, 15000000..16000000 : incf [49],F;
  7000000..8000000, 8500000..9000000 : decf [49],F;
 else clrf [49];
end;
nop;

                movf    BROJ.0,W                ;   // BROJ == 10000000 (h'98 96 80')
                xorlw   0x98                    ;
                btfss   STATUS,Z                ;
                goto    _11000000               ;
                movf    BROJ.1,W                ;
                xorlw   0x96                    ;
                btfss   STATUS,Z                ;
                goto    _11000000               ;
                movf    BROJ.2,W                ;               
                xorlw   0x80                    ;
                btfss   STATUS,Z                ;
                goto    _11000000               ;
                
_then1  incf    0x31,W                          ;   // inc
                goto    _end                    ;

_11000000       
                movf    BROJ.0,W                ;   // BROJ == 11000000 (h'A7 D8 C0')
                xorlw   0xA7                    ;
                btfss   STATUS,Z                ;
                goto    _15000000               ;
                movf    BROJ.1,W                ;
                xorlw   0xD8                    ;
                btfss   STATUS,Z                ;
                goto    _15000000               ;
                movf    BROJ.2,W                ;
                xorlw   0xC0                    ;                       
                btfsc   STATUS,Z                ;
                goto    _then1                  ;


_15000000
                movf    BROJ.0,W                ;   // BROJ >= 15000000 (h'E4 E1 C0')
                sublw   0xE4                    ;
                btfsc   STATUS,Z                ;
                goto    _eq15000000_0           ;
                btfsc   STATUS,C                ;
                goto    _7000000                ;
                goto    _16000000               ;

_eq15000000_0
                movf    BROJ.1,W                ;
                sublw   0xE1                    ;
                btfsc   STATUS,Z                ;
                goto    _eq15000000_1           ;
                btfss   STATUS,C                ;
                goto    _16000000               ;
                goto    _7000000                ;

_eq15000000_1
                movlw   0xC0                    ;
                subwf   BROJ.2,W                ;
                btfss   STATUS,C                ;
                goto    _7000000                ;

_16000000
                movf    BROJ.0,W                ;    // BROJ <= 16000000 (h'F4 24 00')
                sublw   0xF4                    ;
                btfsc   STATUS,Z                ;
                goto    _eq16000000_0           ;
                btfss   STATUS,C                ;
                goto    _7000000                ;
                goto    _then1                  ;

_eq16000000_0
                movf    BROJ.1,W                ;
                sublw   0x24                    ;
                btfsc   STATUS,Z                ;
                goto    _eq16000000_1           ;
                btfsc   STATUS,C                ;
                goto    _then1                  ;
                goto    _7000000                ;

_eq16000000_1
                movf    BROJ.2,W                ;
                sublw   0x00                    ;
                btfsc   STATUS,C                ;
                goto    _then1                  ;
                


_7000000
                movf    BROJ.0,W                ;   // BROJ >= 7000000 (h'6A CF C0')
                sublw   0x6A                    ;
                btfsc   STATUS,Z                ;
                goto    _eq7000000_0            ;
                btfsc   STATUS,C                ;
                goto    _8500000                ;
                goto    _8000000                ;

_eq7000000_0
                movf    BROJ.1,W                ;
                sublw   0xCF                    ;
                btfsc   STATUS,Z                ;
                goto    _eq7000000_1            ;
                btfss   STATUS,C                ;
                goto    _8000000                ;
                goto    _8500000                ;

_eq7000000_1
                movlw   0xC0                    ;
                subwf   BROJ.2,W                ;
                btfss   STATUS,C                ;
                goto    _8500000                ;
        
_8000000
                movf    BROJ.0,W                ;    // BROJ <= 8000000 (h'7A 12 00')
                sublw   0x7A                    ;
                btfsc   STATUS,Z                ;
                goto    _eq8000000_0            ;
                btfss   STATUS,C                ;
                goto    _8500000                ;
                
_then2  decf    0x31,W                          ;   // dec
                goto    _end                    ;

_eq8000000_0
                movf    BROJ.1,W                ;
                sublw   0x12                    ;
                btfsc   STATUS,Z                ;
                goto    _eq8000000_1            ;
                btfsc   STATUS,C                ;
                goto    _then2                  ;
                goto    _8500000                ;

_eq8000000_1
                movf    BROJ.2,W                ;
                sublw   0x00                    ;
                btfsc   STATUS,C                ;
                goto    _then2                  ;


_8500000
                movf    BROJ.0,W                ;   // BROJ >= 8500000 (h'81 B3 20')
                sublw   0x81                    ;
                btfsc   STATUS,Z                ;
                goto    _eq8500000_0            ;
                btfsc   STATUS,C                ;
                goto    _else                   ;
                goto    _9000000                ;

_eq8500000_0
                movf    BROJ.1,W                ;
                sublw   0xB3                    ;
                btfsc   STATUS,Z                ;
                goto    _eq8500000_1            ;
                btfss   STATUS,C                ;
                goto    _9000000                ;
                goto    _else                   ;

_eq8500000_1
                movlw   0x20                    ;
                subwf   BROJ.2,W                ;
                btfss   STATUS,C                ;
                goto    _else                   ;

_9000000
                movf    BROJ.0,W                ;    // BROJ <= 9000000 (h'89 54 40')
                sublw   0x89                    ;
                btfsc   STATUS,Z                ;
                goto    _eq9000000_0            ;
                btfss   STATUS,C                ;
                goto    _else                   ;
                goto    _then2                  ;

_eq9000000_0
                movf    BROJ.1,W                ;
                sublw   0x54                    ;
                btfsc   STATUS,Z                ;
                goto    _eq9000000_1            ;
                btfsc   STATUS,C                ;
                goto    _then2                  ;
                goto    _else                   ;

_eq9000000_1
                movf    BROJ.2,W                ;
                sublw   0x40                    ;
                btfsc   STATUS,C                ;
                goto    _then2                  ;

_else   clrf    0x31                            ;   // else
_end    nop                                     ;   // end



; repeat BROJ + 5 until BROJ > 9000000
Code:

 repeat
   movlw   5;
   addwf   BROJ.2,F;
   btfss   STATUS,C;
   goto    _until;
   incf    BROJ.1,F;
   btfsc       STATUS,Z;
   incf    BROJ.0,F;
 until BROJ > 9000000
nop;

 
_repeat         movlw   0x05                    ;   // BROJ = BROJ+5
                addwf   BROJ.2,F                ;
                btfss   STATUS,C                ;
                goto    _until                  ;
                incf    BROJ.1,F                ;
                btfsc   STATUS,Z                ;
                incf    BROJ.0,F                ;

_until          movf    BROJ.0,W                ;   // BROJ > 9000000 (h'89 54 40')?
                sublw   0x89                    ;
                btfsc   STATUS,Z                ;
                goto    _eq0                    ;
                btfsc   STATUS,C                ;
                goto    _repeat                 ;
                goto    _end                    ;

_eq0    movf    BROJ.1,W                        ;
                sublw   0x54                    ;
                btfsc   STATUS,Z                ;
                goto    _eq1                    ;
                btfss   STATUS,C                ;
                goto    _end                    ;
                goto    _repeat                 ;

_eq1    movf    BROJ.2,W                        ;
                sublw   0x40                    ;
                btfsc   STATUS,C                ;
                goto    _repeat                 ;

_end    nop                                     ;



repeat BROJ + 5 until BROJ >= 9000000
Code:

 repeat
   movlw   5;
   addwf   BROJ.2,F;
   btfss   STATUS,C;
   goto    _until;
   incf    BROJ.1,F;
   btfsc       STATUS,Z;
   incf    BROJ.0,F;
 until BROJ >= 9000000
nop;

_repeat         movlw   0x05                    ;   // BROJ = BROJ+5
                addwf   BROJ.2,F                ;
                btfss   STATUS,C                ;
                goto    _until                  ;   // ovde se moze pisati i goto $+4
                incf    BROJ.1,F                ;
                btfsc   STATUS,Z                ;
                incf    BROJ.0,F                ;

_until          movf    BROJ.0,W                ;       // BROJ >= 9000000 (h'89 54 40')?
                sublw   0x89                    ;
                btfsc   STATUS,Z                ;
                goto    _eq0                    ;
                btfsc   STATUS,C                ;
                goto    _repeat                 ;
                goto    _end

_eq0            movf    BROJ.1,W                ;
                sublw   0x54                    ;
                btfsc   STATUS,Z                ;
                goto    _eq1                    ;
                btfss   STATUS,C                ;
                goto    _end                    ;
                goto    _repeat                 ;

_eq1            movlw   0x40                    ;
                subwf   BROJ.2,W                ;
                btfss   STATUS,C                ;
                goto    _repeat                 ;

_end            nop                             ;



repeat BROJ - 5 until BROJ < 9000000
Code:

 repeat
   movlw   0x05;
   subwf   BROJ.2,F;
   btfsc   STATUS,C;
   goto    _until;
   decf    BROJ.1,F;
   movf    BROJ.1,W;
   xorlw   0xFF;
   btfsc   STATUS,Z;
   decf    BROJ.0,F;
 until BROJ < 9000000
nop;

_repeat         movlw   0x05            ;   // BROJ = BROJ-5
                subwf   BROJ.2,F        ;
                btfsc   STATUS,C        ;
                goto    _until          ;   // ovde se moze pisati i goto $+6
                decf    BROJ.1,F        ;
                movf    BROJ.1,W        ;
                xorlw   0xFF            ;
                btfsc   STATUS,Z        ;
                decf    BROJ.0,F        ;

_until          movlw   0x89            ;  // BROJ < 9000000 (h'89 54 40')?
                subwf   BROJ.0,W        ;
                btfsc   STATUS,Z        ;
                goto    _eq0            ;
                btfsc   STATUS,C        ;
                goto    _repeat         ;
                goto    _end            ;

_eq0            movlw   0x54            ;
                subwf   BROJ.1,W        ;
                btfsc   STATUS,Z        ;
                goto    _eq1            ;
                btfsc   STATUS,C        ;
                goto    _repeat         ;
                goto    _end            ;
        
_eq1            movlw   0x40            ;
                subwf   BROJ.2,W        ;
                btfsc   STATUS,C        ;
                goto    _repeat         ;

_end    nop                             ;



repeat BROJ - 5 until BROJ <= 9000000
Code:

 repeat
   movlw   0x05;
   subwf   BROJ.2,F;
   btfsc   STATUS,C;
   goto    _until;
   decf    BROJ.1,F;
   movf    BROJ.1,W;
   xorlw   0xFF;
   btfsc   STATUS,Z;
   decf    BROJ.0,F;
 until BROJ <= 9000000
nop;

_repeat         movlw   0x05            ;   // BROJ = BROJ-5
                subwf   BROJ.2,F        ;
                btfsc   STATUS,C        ;
                goto    _until          ;   // ovde se moze pisati i goto $+6
                decf    BROJ.1,F        ;
                movf    BROJ.1,W        ;
                xorlw   0xFF            ;
                btfsc   STATUS,Z        ;
                decf    BROJ.0,F        ;

_until          movlw   0x89            ;  // BROJ <= 9000000 (h'89 54 40')?
                subwf   BROJ.0,W        ;
                btfsc   STATUS,Z        ;
                goto    _eq0            ;
                btfsc   STATUS,C        ;
                goto    _repeat         ;
                goto    _end            ;

_eq0            movlw   0x54            ;
                subwf   BROJ.1,W        ;
                btfsc   STATUS,Z        ;
                goto    _eq1            ;
                btfsc   STATUS,C        ;
                goto    _repeat         ;
                goto    _end            ;
        
_eq1            movf    BROJ2,W         ;
                sublw   0x40            ;
                btfss   STATUS,C        ;
                goto    _repeat         ;

_end    nop                             ;



repeat BROJ + 1 until BROJ == 9000000
Code:

 repeat
   incf   BROJ.2,F;
   btfsc  STATUS,Z;
   goto   _until;
   incf   BROJ.1,F;
   btfss  STATUS,Z;
   incf    BROJ.0,F;
 until BROJ == 9000000
nop;

_repeat         incf   BROJ.2,F         ; BROJ = BROJ+1
                btfss  STATUS,Z         ;
                goto   _until           ;
                incf   BROJ.1,F         ;
                btfsc  STATUS,Z         ;
                incf   BROJ.0,F         ;

_until          movlw   0x89            ;  // BROJ == 9000000 (h'89 54 40')?
                xorwf   BROJ.0,W        ;
                btfss   STATUS,Z        ;
                goto    _repeat         ;

_eq0            movlw   0x54            ;
                xorwf   BROJ.1,W        ;
                btfss   STATUS,Z        ;
                goto    _repeat         ;

_eq1            movlw   0x40            ;
                xorwf   BROJ.2,W        ;
                btfss   STATUS,Z        ;
                goto    _repeat         ;       

_end    nop                             ;
 
Odgovor na temu

[es] :: Elektronika :: Mikrokontroleri :: programski jezici za mikrokontrolere pitanja i odgovori

Strane: < .. 1 2 3 4 5 6 7

[ Pregleda: 17779 | Odgovora: 120 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.