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

. 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

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