Svetelektro.com

Svetelektro.com

Meno:
Heslo:
SVETELEKTRO • programovanie v c

programovanie v c

C,C++,C#

Moderátori: psichac, Moderátori

Re: programovanie v c

Odoslaťod Najgel » 21 Júl 2016, 12:21

Prerušenie, nastaviť prerušenie pinu na rising edge, ked nastane, spustiť timer, nasledne prepnuť nastavenie prerušenia na falling edge a keď nastane prerušenie, stopnuť timer.
Keď neodpisujem tak tu nie som, alebo som a neodpisujem :D

MPLAB & PIC
Texas Instruments DSP TMS320Fxxxxx
Tevo Tarantula 3D
Ponúkam 3D tlač.
Ponúkam návrh a vývoj elektroniky na zákazku.

UNIZA 5.ročník
Najgel
Obrázok používateľa
Ultimate člen
Ultimate člen
Príspevky: 1630
Vek: 24.43
Založený: 02.07.2010
Bydlisko: Námestovo, Žilina(škola)
Karma: 31

Re: programovanie v c

Odoslaťod boraicho » 21 Júl 2016, 12:25

aha, tak ja neviem ktory sposob použiť , napadaju ma 2.
snimať nabežnu hranu zapnuť timer a potom počkať na nabežnu hranu druheho signalu a stopnuť timer.

alebo snimať nabežnu hranu zapnuť 2 timeryjeden na 100mS a druhy bude počitať nabežne hrany po 100mS zastaviť timer a spočitať nabežne hrany a z toho vypočitať otačky.
"Aj nevinne vyzerajúca súčiastka, môže byť príčinou nefunkčnosti zariadenia a tou kondenzator 100% je"
3D REBEL II + PLA + PETG
boraicho
Obrázok používateľa
Ultimate člen
Ultimate člen
Príspevky: 11842
Vek: 30.76
Založený: 03.02.2007
Bydlisko: Prešov
Karma: 44

Re: programovanie v c

Odoslaťod OM0XA » 26 Sep 2016, 21:55

NAzdar, mam ulohu - vyzvu pre programatorov v C:

Co najjednoduchsie naprogramovat takuto funciu. Zaujima ma ci niekto nebude mat lepsi napad ako som to vymysel ja. Idealne pouzitim logickych funkcii. urcite sa treba vyhnut umocnovaniu, ktore je pre 8bit uP narocne. Bezi to na AVRku.

vstup: unsigned int - od 1 do 5
vystup:

0b00010000 ak je vstup 1
0b00011000 ak je vstup 2
0b00011100 ak je vstup 3
0b00011110 ak je vstup 4
0b00011111 ak je vstup 5

Dakujem
OM0XA
Stály člen
Stály člen
Príspevky: 229
Založený: 03.10.2012
Bydlisko: Poprad
Karma: 2

Re: programovanie v c

Odoslaťod peterple » 26 Sep 2016, 23:02

Nepíšeš čo to znamená najjednoduchšie. Najkratší zápis v c? Najkratší kód? Najrýchlejší kód? Najmenej použitých registrov?
Tak tu máš dve na výber. Prvá je menej kódu ale pre väčšie in je pomalšia. Druhá má viac kódu, pre vačšie in je máličko rýchlejšia a nepotrebuje tmp register.
A samozrejme pre ten rozsah je unsigned int plýtvanie takže som si to tiež dovolil optimalizovať.
Kód: Vybrať všetko
char fnc1(char in){
char out, tmp;
   for(out=0, tmp=0x10; in; in--)
      out|=tmp, tmp>>=1;
   return out;   
}

char fnc2(char in){
char out;
   switch (in){
      case 1:
         out = 0x10;
         break;
      case 2:
         out = 0x18;
         break;
      case 3:
         out = 0x1c;
         break;
      case 4:
         out = 0x1e;
         break;
      case 5:
         out = 0x1f;
   }
   return out;
}
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.
peterple
Ultimate člen
Ultimate člen
Príspevky: 1898
Vek: 52.81
Založený: 25.06.2013
Bydlisko: Krajné
Karma: 52

Re: programovanie v c

Odoslaťod lh » 26 Sep 2016, 23:47

Kód: Vybrať všetko
char vystup( int x)
{
   x = 32-(1<<(5-x));
   return x;   
}
lh
Obrázok používateľa
Pokročilý člen
Pokročilý člen
Príspevky: 679
Vek: 41.38
Založený: 23.03.2013
Bydlisko: z južnej strany Poľany
Karma: 2

Re: programovanie v c

Odoslaťod xmilos » 27 Sep 2016, 05:50

nepotrebujes ani funkciu staci pole konstant
Kód: Vybrať všetko
code unsigned char arr[] = {0, 0b00010000, 0b00011000, 0b00011100 ,0b00011110, 0b00011111 };


mno a namiesto funkcie pouzijes polozku pola
x = arr[1];

Zapis som neverikoval.
xmilos
Obrázok používateľa
Ultimate člen
Ultimate člen
Príspevky: 3662
Založený: 04.05.2011
Bydlisko: Povazie
Karma: 14

Re: programovanie v c

Odoslaťod OM0XA » 27 Sep 2016, 09:13

dakujem za napady.

predstavoval som si to tak ako navrhol "lh".
Ostatne riesenia su sice funkcne ale prilis narocne na zdroje uP. Povodne som to mal napisane ako "peterple" cez switch.
OM0XA
Stály člen
Stály člen
Príspevky: 229
Založený: 03.10.2012
Bydlisko: Poprad
Karma: 2

Re: programovanie v c

Odoslaťod lh » 27 Sep 2016, 09:47

No, len taká poznámka... moje riešenie nezodpovedá zadaniu, pretože som sa nevyhol umocňovaniu :D ale práve kvôli nenáročnosti
lh
Obrázok používateľa
Pokročilý člen
Pokročilý člen
Príspevky: 679
Vek: 41.38
Založený: 23.03.2013
Bydlisko: z južnej strany Poľany
Karma: 2

Re: programovanie v c

Odoslaťod pokusnik » 27 Sep 2016, 10:25

Nerad bych zakládal flame.
Ale podle mne je nejlepší řešení od xmilose.
Pokud totiž člověk ví, na jaké instrukce to může dobře napsaný překladač přeložit...
pokusnik
Obrázok používateľa
Okoloidúci
Okoloidúci
Príspevky: 41
Založený: 14.04.2009
Karma: 1

Re: programovanie v c

Odoslaťod OM0XA » 27 Sep 2016, 11:12

lh napísal:No, len taká poznámka... moje riešenie nezodpovedá zadaniu, pretože som sa nevyhol umocňovaniu :D ale práve kvôli nenáročnosti



umocnovanie rotaciou mi nevadi, s tym si uP poradi lahko. Myslel som nepouzivat funkciu z math kniznice. :-)

-- Spojený príspevok 27 Sep 2016, 10:24 --

http://www.atmel.com/Images/doc8453.pdf

mozno niekto oceni, clanok o optimalizacii kodu... mozno to niekto vsetko vie, ale je dobre si niektore veci uvedomit. To len na okraj.
OM0XA
Stály člen
Stály člen
Príspevky: 229
Založený: 03.10.2012
Bydlisko: Poprad
Karma: 2

Re: programovanie v c

Odoslaťod BgDestroy » 27 Sep 2016, 11:29

Pokial sa jedna o riesenie. Tak najviac sa mi paci od xmilos. Za Predpokladu ze sa jedna o tyhto par vystupov. 5B z pamate nie je nic. Ulozenie hotovej hodnoty z pamate mi pride rychlejsie ako matematicke operacie a tie az ulozi.

-- Spojený príspevok 27 Sep 2016, 10:39 --

A to uz je na kazdom ci sa viacej zamera na setrnost na pamat alebo na vykon oboje nie je mozne. Iba nejake kompromisi.
Albert Einstein:
* Dôležitá vec je neprestať sa pýtať.
* Len dve veci sú nekonečné - vesmír a ľudská hlúposť. Ale tou prvou si nie som istý.
* Nie je dôležité, čo si dokázal v škole, ale to, čo dokážeš v živote.
BgDestroy
Obrázok používateľa
Pokročilý člen
Pokročilý člen
Príspevky: 601
Vek: 32.6
Založený: 17.07.2006
Bydlisko: Bazar Enabled, Udaje sa dozvie pri kupe s danym clovekom
Karma: 2

Re: programovanie v c

Odoslaťod peterple » 27 Sep 2016, 19:29

Kedže vieme že cieľová platforma je AVR tak najlepšie riešenie mi príde to od xmilos. Riešenie od lh síce nevyzerá že by tam bol cyklus ale on potvora tam je, lebo AVR vie rotovať iba o jeden bit. Na inej platforme by to mohlo byť tiež dobré riešenie. Takto proti tomu môjmu cyklu ušetril logický súčet čo tam mám v každom cykle.
Riešenie od xmilosa mi príde v tomto prípade najoptimálnejšie v každom smere (pamäť, rýchlosť ..)
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.
peterple
Ultimate člen
Ultimate člen
Príspevky: 1898
Vek: 52.81
Založený: 25.06.2013
Bydlisko: Krajné
Karma: 52

Re: programovanie v c

Odoslaťod BgDestroy » 27 Sep 2016, 19:49

pamat nie, hentaka funkcia sa da este optimalozovat vstupnym parametrom z int x na unsigned char x. int je zbytocny. Pri uvahe ze nahradi int x (2x8bit) na unsigned char (1x8bit) pracuje funkcia len s 3x8bit (32, x a 1 ktory rotuje) takze v podstate s 3B. Xmilos pracuje s array ktory ma 5x8bit (5B) a 1x8bit (1B) cim oznacis o aky udaj z pola sa jedna arr[x].

LH = na pamat ale nie na vypoctovy vykon.
xmilos = na vypoctovy vykon ale nie na pamat.
Albert Einstein:
* Dôležitá vec je neprestať sa pýtať.
* Len dve veci sú nekonečné - vesmír a ľudská hlúposť. Ale tou prvou si nie som istý.
* Nie je dôležité, čo si dokázal v škole, ale to, čo dokážeš v živote.
BgDestroy
Obrázok používateľa
Pokročilý člen
Pokročilý člen
Príspevky: 601
Vek: 32.6
Založený: 17.07.2006
Bydlisko: Bazar Enabled, Udaje sa dozvie pri kupe s danym clovekom
Karma: 2

Re: programovanie v c

Odoslaťod xmilos » 28 Sep 2016, 07:38

Chlapi sem tam mrknite do vystupu co ten prekladac tvori. By ste sa cudovali. Pre AVR lss nic moc, ale podarilo sa mi z toho nieco vytiahnut, mozna som sa o jeden dva riadky netrafil, ale pre obe riesenia je to cca:
Kód: Vybrať všetko
char vystup( char x)
{
   x = 32-(1<<(5-x));
  4a:   45 e0          ldi   r20, 0x05   ; 5
  4c:   50 e0          ldi   r21, 0x00   ; 0
  4e:   21 e0          ldi   r18, 0x01   ; 1
  50:   30 e0          ldi   r19, 0x00   ; 0
  52:   60 e2          ldi   r22, 0x20   ; 32
  5c:   fa 01          movw   r30, r20
  5e:   e8 1b          sub   r30, r24
  60:   f1 09          sbc   r31, r1
  62:   cf 01          movw   r24, r30
  64:   f9 01          movw   r30, r18
  66:   02 c0          rjmp   .+4         ; 0x6c <main+0x24>
  68:   ee 0f          add   r30, r30
  6a:   ff 1f          adc   r31, r31
  6c:   8a 95          dec   r24
  6e:   e2 f7          brpl   .-8         ; 0x68 <main+0x20>
  70:   cf 01          movw   r24, r30
  72:   f6 2f          mov   r31, r22
  74:   f8 1b          sub   r31, r24


tu treba pridat este 5 Bytov pola
Kód: Vybrať všetko
  tmp = arr[tmp];
  64:   e0 91 66 00    lds   r30, 0x0066
  68:   f0 e0          ldi   r31, 0x00   ; 0
  6a:   e0 5a          subi   r30, 0xA0   ; 160
  6c:   ff 4f          sbci   r31, 0xFF   ; 255
  6e:   80 81          ld   r24, Z
  70:   80 93 66 00    sts   0x0066, r24



ciste porovnanie by bolo vytvorit kniznice, ale zial narychlo sa mi nepodarilo donutit Atmel studio aby generoval listing aj pre staticke kniznice.
xmilos
Obrázok používateľa
Ultimate člen
Ultimate člen
Príspevky: 3662
Založený: 04.05.2011
Bydlisko: Povazie
Karma: 14

Re: programovanie v c

Odoslaťod peterple » 28 Sep 2016, 20:46

Xmilos nepovedal celú pravdu. Kedže to pole arr umiestnil do SRAM tak je tam ešte časť kódu ktorá to pole do SRAM musí nainicializovať. A to je ako inak zase cyklus, ktorý tie konštanty má v flash a po resete sa skopírujú do SRAM. Asi takto:
Kód: Vybrať všetko
0000001C  LDI R17,0x00      Load immediate
0000001D  LDI R26,0x60      Load immediate
0000001E  LDI R27,0x00      Load immediate
0000001F  LDI R30,0x74      Load immediate
00000020  LDI R31,0x06      Load immediate
00000021  RJMP PC+0x0003      Relative jump
00000022  LPM R0,Z+      Load program memory and postincrement
00000023  ST X+,R0      Store indirect and postincrement
00000024  CPI R26,0x66      Compare with immediate
00000025  CPC R27,R17      Compare with carry
00000026  BRNE PC-0x04      Branch if not equal

Je pravda že tento kód sa vykoná iba raz po resete, čo ale môže byť tiež istou slabinou, čím sa z toho riešenia stáva riešenie málo robustné. Stačí aby sa ten údaj v SRAM zmenil a je zle.

takže ďalšie otimálne riešenie pre avr architektúru inšpirované xmilošovým riešením
Kód: Vybrať všetko
const unsigned char arr[] PROGMEM = {0, 0b00010000, 0b00011000, 0b00011100 ,0b00011110, 0b00011111 };
char fnc3(char in){
   return pgm_read_byte(arr+in);
}


V kóde to bude takto:
Kód: Vybrať všetko
char fnc3(char in){
   return pgm_read_byte(arr+in);
00000042  MOV R30,R24      Copy register
00000043  LDI R31,0x00      Load immediate
00000044  SUBI R30,0xDA      Subtract immediate
00000045  SBCI R31,0xFF      Subtract immediate with carry
00000046  LPM R24,Z      Load program memory
}
00000047  RET       Subroutine return

plus 6 byte pole v flash pameti
Toto by som ani v asm nenapísal kratšie. Rozdiel je iba v tom že, aby mi to C vygeneroval takto tak do toho musím sakra vidiet. V asm si to napíšem rovno a neriešim či to prekladač urobil optimálne alebo nie. (Ale tiež do toho musím sakra vidieť)
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.
peterple
Ultimate člen
Ultimate člen
Príspevky: 1898
Vek: 52.81
Založený: 25.06.2013
Bydlisko: Krajné
Karma: 52

Re: programovanie v c

Odoslaťod BgDestroy » 28 Sep 2016, 20:58

To peterple.

S tym const mas pravdu, PROGMEM som ani nevedel ze sa to tak aj da bez toho aby to daval do RAM zase som mudrejsi :) len jedna vec mi nejde do hlavy preco vyrvaras novu funkciu ked by stacilo pouzivat len pgm_read_byte(arr+in)?
Albert Einstein:
* Dôležitá vec je neprestať sa pýtať.
* Len dve veci sú nekonečné - vesmír a ľudská hlúposť. Ale tou prvou si nie som istý.
* Nie je dôležité, čo si dokázal v škole, ale to, čo dokážeš v živote.
BgDestroy
Obrázok používateľa
Pokročilý člen
Pokročilý člen
Príspevky: 601
Vek: 32.6
Založený: 17.07.2006
Bydlisko: Bazar Enabled, Udaje sa dozvie pri kupe s danym clovekom
Karma: 2

Re: programovanie v c

Odoslaťod peterple » 28 Sep 2016, 21:13

pretože aj keď sa pgm_read_byte tvári ako funkcia tak je to makro. Takže pri každom použití by sa tam kompilovalo niečo takéhoto:
Kód: Vybrať všetko
   result = pgm_read_byte(arr+in);
0000008B  LDD R30,Y+1      Load indirect with displacement
0000008C  LDI R31,0x00      Load immediate
0000008D  SUBI R30,0xDA      Subtract immediate
0000008E  SBCI R31,0xFF      Subtract immediate with carry
0000008F  LPM R30,Z      Load program memory
00000090  STD Y+2,R30      Store indirect with displacement
   result = pgm_read_byte(arr+4);
00000091  LDI R30,0x2A      Load immediate
00000092  LDI R31,0x00      Load immediate
00000093  LPM R30,Z      Load program memory
00000094  STD Y+2,R30      Store indirect with displacement


Ale ako vidno kompilátor sa snaží otimalizovať čo to dá.
Pomocou funkcie to bude podprogram takže ušetrím pár wordov vo FLASH pri každom volaní. Samozrejme za cenu CALL RET réžie. Tu už to je klasické niečo za niečo.
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.
peterple
Ultimate člen
Ultimate člen
Príspevky: 1898
Vek: 52.81
Založený: 25.06.2013
Bydlisko: Krajné
Karma: 52

Re: programovanie v c

Odoslaťod lh » 28 Sep 2016, 23:06

Nuž peterple, klobúk dolu... asi prestanem prispievať, aby som sa nemusel verejne hanbiť :D budem len potíšku doma :thumbup:
lh
Obrázok používateľa
Pokročilý člen
Pokročilý člen
Príspevky: 679
Vek: 41.38
Založený: 23.03.2013
Bydlisko: z južnej strany Poľany
Karma: 2

Re: programovanie v c

Odoslaťod xmilos » 29 Sep 2016, 06:56

peterple napísal:Xmilos nepovedal celú pravdu

treba poriadne CITAT prispevky:
ako som pisal, je potrebne doplnit 5 bytov pre pole.
Presne tento kod som pouzil aj ja
Kód: Vybrať všetko
const unsigned char arr[]...


- takze v com som nepovedal uplnu pravdu?

Samozrejme ze som to pisal so zamerom umiestnit pole do statickej rom - flash ale
je pravda, ze v rychlosti som nestudoval kam to v reali prekladac umiestnil. Pouzitim "const" som predpokladal ze je to v statickej ROM - flaske, tak ako som zvyknuty z ostatnych prekladacov.

Plati co som spomenul vyssie:
je dobre obcas mrknut do vystupneho kodu a potom by sa mozna castejsie vyhlo "zhovadilostiam" typu "printf" a pod.
Pred casom som prepisoval program pre PIC z asm do C, pretoze s asm som skoncil hooodne davno. A podarilo sa mi napisat KRATSI vystupny kod. Je mi jasne ze je to extrem, clovek co pisal to asm to mozna neoptimalizoval a zapis v C bol dost krkolomny, vyplyva vsak z toho, ze ak clovek vie ako to cca + - robi prekladac, da sa napisat aj v C slusny kod.
Napriklad pre inak spickovy prekladac X51 Keil bolo vyhodnejsie pouzit cyklus do{..} while() nez for(), pretoze to bol jediny pripad, kedy prekladac pouzil jednoduchsiu instrukciu ( tusim djnz ).
Uz vidim rozhorcenych rychlopecenych programnatorov, "sak pamate a vykonu je dost" - a maju pravdu. Uz su prec tie doby, ked sa setrilo kazdou instrukciou.
xmilos
Obrázok používateľa
Ultimate člen
Ultimate člen
Príspevky: 3662
Založený: 04.05.2011
Bydlisko: Povazie
Karma: 14

Re: programovanie v c

Odoslaťod BgDestroy » 29 Sep 2016, 09:48

peterple napísal:pretože aj keď sa pgm_read_byte tvári ako funkcia tak je to makro. Takže pri každom použití by sa tam kompilovalo niečo takéhoto:
Kód: Vybrať všetko
   result = pgm_read_byte(arr+in);
0000008B  LDD R30,Y+1      Load indirect with displacement
0000008C  LDI R31,0x00      Load immediate
0000008D  SUBI R30,0xDA      Subtract immediate
0000008E  SBCI R31,0xFF      Subtract immediate with carry
0000008F  LPM R30,Z      Load program memory
00000090  STD Y+2,R30      Store indirect with displacement
   result = pgm_read_byte(arr+4);
00000091  LDI R30,0x2A      Load immediate
00000092  LDI R31,0x00      Load immediate
00000093  LPM R30,Z      Load program memory
00000094  STD Y+2,R30      Store indirect with displacement


Ale ako vidno kompilátor sa snaží otimalizovať čo to dá.
Pomocou funkcie to bude podprogram takže ušetrím pár wordov vo FLASH pri každom volaní. Samozrejme za cenu CALL RET réžie. Tu už to je klasické niečo za niečo.


Tu funkciu volas tak ci tak, a ked kompilator to spravi lepsie ked je to navyse v tej funkcii obalene tak mi to pride ako velka nedokonalost kompilatora. Pokial chces vytrieskat z avr maximum tak nie vobec vhodne pouzit C ale Asembler? Ci? Aj tak avr je uz podstate len prezitok. Velmi vela slabin na to kolko stoji.
Albert Einstein:
* Dôležitá vec je neprestať sa pýtať.
* Len dve veci sú nekonečné - vesmír a ľudská hlúposť. Ale tou prvou si nie som istý.
* Nie je dôležité, čo si dokázal v škole, ale to, čo dokážeš v živote.
BgDestroy
Obrázok používateľa
Pokročilý člen
Pokročilý člen
Príspevky: 601
Vek: 32.6
Založený: 17.07.2006
Bydlisko: Bazar Enabled, Udaje sa dozvie pri kupe s danym clovekom
Karma: 2

PredchádzajúcaĎalšia

Naspäť na C,C++,C#

Kto je prítomný

Užívatelia prezerajúci si toto fórum: Žiadny registrovaný používateľ a 1 hosť.

Forums ©
Autor stránky je Ondrej Závodský(zawin), o graficky design sa stará Ľuboš Fabo(BUFU).

TOPlist

Powered by Copyright © UNITED-NUKE CMS. All Rights Reserved.
Čas potrebný k spracovaniu stránky 0.80 sekúnd