Stránka 1 z 1

Dělení

Napsal: 13 srp 2008, 14:24
od Aqarel
zdravim, začal jsem programovat PIC v C (kompilátor HI-TECH) a narazil jsem na jeden problém se, kterým si už nevím rady.

Kód: Vybrat vše

#include <htc.h>

__CONFIG(INTRCRB4 & WDTDIS & UNPROTECT & MCLRDIS);


void init(void)
{
   TRISB = 0;
   PORTB = 0;
}

void DelayUs(unsigned char us)
{   
   unsigned char time;
   time = (us/25);
   while(--time != 0)
      continue;
}
 
void main(void)
{
   init();
   while (1)
{   
      DelayUs(100);
      RB1 = 0;
      DelayUs(100);
      RB1 = 1;            
   }
}


pokud program spustim tak je výstup RB1 v log 1 místo toho aby se generoval signál s periodou 200us, ale pokud v delay odstranim deleni 25 a místo argumentu 100 napisi 4 tak se na výstupu generuje signál s periodou cca 200us

Napsal: 14 srp 2008, 10:24
od Marie Fůrie
Já tedy v C neprogramuju a na PICech už vůbec ne, ale jestli ten kompiler umí udělat mezipřeklad do assembleru, tak by to chtělo zkouknout, jak to dělení přeložil.

Napsal: 14 srp 2008, 11:21
od gogokt
Podle mne je tvuj proble v pouy\ziti typu promenne CHAR coz je znak. Musis pouzit nejake ciselne typy navic CHAR je ted si nejsem uplne jist jen jeden bit coz je hodnota 0-255.

Zde mas odkaz na typy v jazyce C:

http://programujte.com/index.php?akce=c ... kce-printf

Napsal: 14 srp 2008, 12:05
od Marie Fůrie
gogokt píše:Podle mne je tvuj proble v pouy\ziti typu promenne CHAR coz je znak. Musis pouzit nejake ciselne typy navic CHAR je ted si nejsem uplne jist jen jeden bit coz je hodnota 0-255.

Zde mas odkaz na typy v jazyce C:

http://programujte.com/index.php?akce=c ... kce-printf

Máš na mysli asi jeden byte, do jednoho bitu se toho moc nevejde :wink: . Nějak nevidím důvod proč by neměl jít celočíselně dělit unsigned char unsigned charem a pokud to nejde, tak by to měl překladač ohlásit.

Napsal: 14 srp 2008, 13:26
od Aqarel
tady jeste dodavam vygenerovanej program v assembleru:

Kód: Vybrat vše

---  C:\Program Files\HI-TECH Software\PICC\PRO\9.60\sources\awdiv.c  ----------------------------
1:                 // integer signed division
2:                 
3:                 signed int
4:                 __awdiv(signed int dividend, signed int divisor)
5:                 {
   008     4A3     BCF 0x3, 0x5
---  C:\pic\pokus.c  -----------------------------------------------------------------------------
1:                 #include <htc.h>
2:                 
3:                 unsigned char time;
4:                 
5:                 __CONFIG(INTRCRB4 & WDTDIS & UNPROTECT & MCLRDIS);
6:                 
7:                 void init(void)
8:                 {
   006     4A3     BCF 0x3, 0x5
9:                    TRISB = 0b00000000;
10:                   TRISC = 0b00000000;
11:                   PORTC = 0b00000000;
12:                }
13:               
14:                void DelayUs(unsigned char us)
15:                {   
   004     4A3     BCF 0x3, 0x5
16:                   time = us/25;
17:                   while(--time != 0)
18:                       PORTC = time;
19:                }
20:                 
21:                void main(void)
22:                {
23:                   init();
   138     4A3     BCF 0x3, 0x5
   139     906     CALL 0x6
   13A     4A3     BCF 0x3, 0x5
24:                   while (1)
   155     B3B     GOTO 0x13b
   156     4A3     BCF 0x3, 0x5
   157     A02     GOTO 0x2
25:                {   
26:                      DelayUs(100);
   13B     040     CLRW
   13C     D64     IORLW 0x64
   13D     4A3     BCF 0x3, 0x5
   13E     904     CALL 0x4
   13F     4A3     BCF 0x3, 0x5
27:                      RB1 = 0;
   140     403     BCF 0x3, 0
   141     603     BTFSC 0x3, 0
   142     B45     GOTO 0x145
   143     B47     GOTO 0x147
   144     064     CLRF 0x4
   145     526     BSF 0x6, 0x1
   146     B48     GOTO 0x148
   147     426     BCF 0x6, 0x1
28:                      DelayUs(100);
   148     040     CLRW
   149     D64     IORLW 0x64
   14A     4A3     BCF 0x3, 0x5
   14B     904     CALL 0x4
   14C     4A3     BCF 0x3, 0x5
29:                      RB1 = 1;            
   14D     503     BSF 0x3, 0

Napsal: 15 srp 2008, 10:07
od Marie Fůrie
Teda ten PIC assembler je hrůza. Nechybí tam něco? Nějak v tom nevidím obsah té procedury DelayUs. Chtělo by to někoho kdo dělá s PICama, já se v té hrůze nevyznám :oops:

Napsal: 21 srp 2008, 08:16
od piitr
Taky bych řekl, že tam něco chybí. Jinak, jak zjišťuješ, že to je pořád v 1? Na osciloskopu? On PIC nemá instrukci na dělení. Takže na dělení 25 se bude volat procedura, která bude nejspíš trvat mnohem déle než vlastní čekací smyčka se čtyřmi průchody. Není to spíš tak, že to generuje obdélník, ale mnohem pomalejší?

Napsal: 24 srp 2008, 18:58
od Aqarel
smyčka jako taková je napsaná správně, pokud do PICu nahraju program napsaný výše pak, je výstup v log. 1 (dívám se na osciloskopu), pokud to vydělím přímo, pak to generuje obdelník tak jak má:

Kód: Vybrat vše

void DelayUs(unsigned char us) 
{   
   unsigned char time;
   time = us;
   while(--time != 0)
      continue;
}
 
void main(void)
{
   init();
   while (1)
{   
      DelayUs(4);
      RB1 = 0;
      DelayUs(4);
      RB1 = 1;             
   }
}

Napsal: 24 srp 2008, 22:28
od Makovec
Zkoušel jsi to přetypovat ? Připadá mi to dělení úplně špatně,ale možnosti kompilátoru HI-TECH neznám....

Napsal: 25 srp 2008, 09:51
od piitr
Hmm, kdo ví, jak to pouštíš, předtím jsi tam měl 100 mikrosekund, teď tam máš jen 4. To je další problém. Totiž po dělení 25 ti vyjde 0. A v tom tvém cyklu se nula chová jako 256, respektive 65536, nevím, kolik bitů má ta proměnná. místo while(--time) tam dej while(time--).

Napsal: 25 srp 2008, 12:16
od xp.
ano, zkousel jsme ruzne typy a nic nepomahalo

piitr píše:Hmm, kdo ví, jak to pouštíš, předtím jsi tam měl 100 mikrosekund, teď tam máš jen 4. To je další problém. Totiž po dělení 25 ti vyjde 0. A v tom tvém cyklu se nula chová jako 256, respektive 65536, nevím, kolik bitů má ta proměnná. místo while(--time) tam dej while(time--).


jenže já jsem tentokrát ve funkci DelayUs to dělení vynechal, takže v obou případech by mělo být v proměnné time čtyři

Napsal: 25 srp 2008, 16:08
od piitr
No, on ten překladač možná bude nějakej přiblblej. Ten vygenerovanej kód mi přijde divnej. Zaprvé tam toho dost chybí, a to, co tam je, je podivné. Zkusil bych jiný překladač nebo assembler.

Napsal: 25 srp 2008, 19:46
od Makovec
Zkus tohle:

Kód: Vybrat vše

void DelayUs(signed int us)
{
  signed int time;
  signed int temp;
  temp =30;
  time = temp/us;

   while(--time != 0)
      continue;
}

Napsal: 25 srp 2008, 19:51
od Makovec
ještě to bude chtít upravit ten cyklus ...

Napsal: 29 srp 2008, 17:37
od xp.
Zdravim, tak jsem se konečně zas dostal ve firmě k osciloskopu a mohl jsem vyzkoušet výše uvedený kód. Bohužel výsledek je pořá stejný, tedy výstup se pořád nachází v log. 1. Zkoušel jsem různá nastavení kompilátoru, ale bez výsledku. Má někdo zkušenosti s CCS kompilátorem? díky