Dělení

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Odpovědět
Zpráva
Autor
Uživatelský avatar
Aqarel
Příspěvky: 241
Registrován: 04 úno 2007, 01:00
Kontaktovat uživatele:

Dělení

#1 Příspěvek 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

Marie Fùrie

#2 Příspěvek 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.

Uživatelský avatar
gogokt
Příspěvky: 36
Registrován: 13 srp 2008, 02:00

#3 Příspěvek 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

Marie Fùrie

#4 Příspěvek 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.

Uživatelský avatar
Aqarel
Příspěvky: 241
Registrován: 04 úno 2007, 01:00
Kontaktovat uživatele:

#5 Příspěvek 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

Marie Fùrie

#6 Příspěvek 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:

Uživatelský avatar
piitr
Příspěvky: 1003
Registrován: 19 říj 2007, 02:00
Kontaktovat uživatele:

#7 Příspěvek 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ší?

Uživatelský avatar
Aqarel
Příspěvky: 241
Registrován: 04 úno 2007, 01:00
Kontaktovat uživatele:

#8 Příspěvek 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;             
   } 
}

Makovec

#9 Příspěvek 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....

Uživatelský avatar
piitr
Příspěvky: 1003
Registrován: 19 říj 2007, 02:00
Kontaktovat uživatele:

#10 Příspěvek 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--).

xp.

#11 Příspěvek 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

Uživatelský avatar
piitr
Příspěvky: 1003
Registrován: 19 říj 2007, 02:00
Kontaktovat uživatele:

#12 Příspěvek 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.

Makovec

#13 Příspěvek 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;
}

Makovec

#14 Příspěvek od Makovec »

ještì to bude chtít upravit ten cyklus ...

xp.

#15 Příspěvek 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

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“