Div 16Bits por 3 em ASM

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Div 16Bits por 3 em ASM

Mensagempor fabim » 07 Out 2008 09:28

psoall, faz um certo tempo que não mexo com carculus em ASM, e estou meio aperdidado..
Como dividir uma word "16 bits" por 3 o mais rapido possivel ?

por 2.
bcf status, c
rrf _var+0, F
rrf _Var+1, F

belezinha 4 ciclos 4uS....

Pelos calculos loucos, eu sei que até 40uS não terá influencia meu aplicativo..

Alguém aí lembra de alguma rotina super rapidona em asm ?

Fabim
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor proex » 07 Out 2008 10:51

Multiplica por 2 e divide por 6.
proex
Dword
 
Mensagens: 2101
Registrado em: 11 Out 2006 14:05
Localização: São Paulo

Mensagempor fabim » 07 Out 2008 11:06

aff. mesmo ?
divide por 100 e multiplica por 33,33333333 ?? Daria certo também né ?
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor ze » 07 Out 2008 11:34

deixou o asm ontem e já esqueceu tudo... é isso que o C faiz?
já que é assim, faça em c e veja o asm que sai dele. Se tiver + de 1 compilador, compare. qquer mom faço no hitech pra ver.
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Mensagempor fabim » 07 Out 2008 11:49

á mano então né..
como eu disse, eles usam liby de 16 x 16 e 16div16...
num serve não.
em 4mhz, pegar 16000 / 3 = 268uS...

Fabim
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor msamsoniuk » 07 Out 2008 12:51

fabim escreveu:aff. mesmo ?
divide por 100 e multiplica por 33,33333333 ?? Daria certo também né ?


mas nao eh muito eficiente neh. vc pode multiplicar por 85 e dividir por 256, otimizando tudo para usar apenas shifts e somas:

resultado = ((valor<<6)+(valor<<4)+(valor<<2)+valor)>>8;

mas esse metodo requer 8 bits extras, entao se vc tem valores de 16 bits, os shifts vao jogar eles para 24 bits. alem disso, eh uma aproximacao meio fajuta...

outro metodo eh decompor 1/3 em fracoes menores tipo 1/2^n. para isso eu usei um pequeno programa em awk:

Código: Selecionar todos
BEGIN
{
  SOMA=0;
  for(j=0;j!=16;j++)
  {
    i=2**j;
    if((SOMA+1/i)<=(1/3))
    {
        SOMA+=(1/i);
        print SOMA,"1/2^"j
    }
  }
}


e ele me deu os seguintes resultados:

0.25 1/2^2
0.3125 1/2^4
0.328125 1/2^6
0.332031 1/2^8
0.333008 1/2^10
0.333252 1/2^12
0.333313 1/2^14

assim, o valor 1/3 pode ser visto como a somatoria destas fracoes:

resultado = ( ( valor>>2 ) + ( valor>>4 ) + ( valor>>6 ) + ( valor>>8 ) + ( valor>>10 ) + ( valor>>12 ) + ( valor>>14 ) ) ;

o resultado eh mais exato que o primeiro metodo e nao requer bits extras a esquerda, mas requer mais somas e shifts.
Editado pela última vez por msamsoniuk em 07 Out 2008 13:07, em um total de 2 vezes.
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor fabim » 07 Out 2008 13:00

entãozis tchelo..
A uns %#$%#%$# anos atráz,,,
Eu tinha feito uma rotininha muy simples, para dividir por.
1....10.

Que era o que o soft precisava..

Mais como fazem muitos anos eu não consigo me lembrar como eu tinha feito isto!!

no meu caso, não importa se ele perder tipo até D20... tanto faz.
O que eu preciso é dividir uma word por 3, no menor tempo possivel!!
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor msamsoniuk » 07 Out 2008 13:23

pois eh, o segundo metodo requer 7 shifts e 6 somas de 16 bits, enquanto o segundo requer 4 shifts e 3 somas de 32 bits... apesar do primeiro metodo ser mais simples, eu chuto que o segundo eh mais veloz, em funcao da diferenca de 16 e 32 bits.
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor fabim » 07 Out 2008 15:50

marromenu isso aqui ó..
Eu estava acabando um projeto que esta em outro post em pascal.
Mais o povão ia me chingar.
Módique na epoca eu tinha feito em ASM e estava portando para pascal.
Como sou "c"zeiro também!! agora...

Código: Selecionar todos
  void interrupt(void){
 if (INTCON.INTF){   // foi int GP0 em borda de descida ? se sim !!
 // tempo de demora para acionar mosfet = 10 ciclos em CK 5mhz

 _asm BSF GPIO, 0; // liga mosfet do bico

 _asm BSF T1CON,0; //T1CON.TMR1ON = 1; liga timer 1
 
 while (!GPIO.GP2){   // enquanto 0 coça o saco..
 _asm NOP; }

 _asm BCF T1CON,0; //T1CON.INTF = 0;  desliga timer 1
 _asm MOVF TMR1H, W;
 _asm MOVWF _Temp+1;  // temp_MSB = TMR1H
 _asm MOVF TMR1L, W;
 _asm MOVWF _temp+0; //TEMP_LSB = TMR1L

 (* agora é a parte fodastica.
   Suponha que o tempo do pulso na contagem em LOW é de 17000
  não enteressa a quantidade de pulsos o que interessa é 30% ou 1/3 deles acrescidos.

  houve que. Quando aconteceu o acionamento da centralina, eu acionei o mosfet no bico, contei quantos pulsos duraram. 18000 EX.
  Eu pego 1/3 de 18K = 6K.
  menos ciclos que eu demorei para os calculos. 500 ciclos por exemplo.

  6K - 500 = 5500. Mantenho o mosfet acionado por mais 5500 ciclos.
  Desligo mosfet.!!

  Tempo total que o mosfet deixou o bico aberto é de.
  18000 + 500 ciclos de calculo + 5500 = 24000 ciclos.
 
  Passando para tempo vem que.
 
  CK=5mhz  = 20MHZ/4 .........
  1 / 5000 000 =  0,000 000 200. = 200nS
  24000 ciclos * 200nS = 4,8mS

  Tempo horiginal da centralina é de.
  18000 * 200nS = 3,6mS

   ou seja eu adicionei 30% a mais de combustivel...

  *)
 
 }
 INTCON.INTF = 0;
}
 Ai eu tive uma ideóta da seguinte forma.
 Quando eu acabar de pegar o valor de TIMER1 e jogar no TEMP, que foi o tempo de pulso LOW que a centralina enviou
 Zera timer 1H
 Zera timer 1L
 Liga timer
 pega 30% da contagem anterior
 desliga timer.
 18000 - tempo do calculo que esta no timer + 30% de 18000.

 Só que este segundo calculo ja vai ferrar a logica.

 por isso que queria uma forma de pegar 1/3 de 16 bits em pucos ciclos.

 Fabim
 
 
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor ze » 07 Out 2008 16:36

intendi paul newman.

skece. nestas horas que perdeu tentando fazer em asm, seu concorrente já fez tudo em C num pic de 40+MHz ou dspic e já te comeu.

Fiz pra brincar no mplab uma div16 por 3 e levou ~340uS - 4MHz - pic18F252 - hitech C. Prat o mesmo tempo dos shifts. Pode ser muito msm.
cogite uC + veloz.

Código: Selecionar todos
main()
{
unsigned int valor=16000,resultado;
for (;;){
   resultado=valor/3;
   asm("nop"); //pus break point aqui, 340 ciclos
   }
}


abs
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Mensagempor Djalma Toledo Rodrigues » 07 Out 2008 17:14

Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22

Mensagempor msamsoniuk » 07 Out 2008 19:11

nossa, o PIC eh tao lento assim ateh mesmo fazendo os shifts ?!

mas tipo, se nao precisa muita precisao, pode tentar um chutao: a media entre o valor dividido por 2 e por 4 hahaha, algo como:

resultado = ((valor>>1)+(valor>>2))>>1

meio aproximado dae, mas usa soh 1 soma e 3 shifts! hehehe
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor fabim » 09 Out 2008 09:50

lellis escreveu:intendi paul newman.

skece. nestas horas que perdeu tentando fazer em asm, seu concorrente já fez tudo em C num pic de 40+MHz ou dspic e já te comeu.

Fiz pra brincar no mplab uma div16 por 3 e levou ~340uS - 4MHz - pic18F252 - hitech C. Prat o mesmo tempo dos shifts. Pode ser muito msm.
cogite uC + veloz.

Código: Selecionar todos
main()
{
unsigned int valor=16000,resultado;
for (;;){
   resultado=valor/3;
   asm("nop"); //pus break point aqui, 340 ciclos
   }
}


abs


MANITO.
Seguinte.
a tatica desses conversores de gasosa pra alcool é injetar 30% a mais de combustivel.
A quantidade de combustive é em função de tempo de abertura dos bicos injetores do carro, se você aumentar em 30% no tempo, entao é 30% a mais de combustivel.

Como deve saber, quem tem isto no carro em sua maioria diz que funciona muito bem.

A tatica é simplesmente esta...

Se chave ligada, então aumenta 30% o pulso de saida referente a entrada.
Se chave desligada, tempo do pulso de saida igual ao de entrada.

Facim né ? Mais vou fazer uns testes.
ao invés de 30% vou injetar 25%.

Alguém aí tem conectores bull-dog ? macho e fêma ?pra testar ?

Nem tumove eu tenho mais,, perto de arroz de terceira eu sou farinha.rs

fabim
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor Djalma Toledo Rodrigues » 09 Out 2008 10:07

2 sugest:
1) Div por 6 mult por 2 : Mas tem que preservar o deslocamento em um 3º Byte antes de mult por 2
2) Usar um uC 16 bits com Mult/Divisão
Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22

Mensagempor MOR_AL » 09 Out 2008 13:59

Olá Fabim.
Tenta o Link abaixo.

http://www.restena.lu/convict/Jeunes/Ma ... tions2.htm

MOR_AL
"Para o triunfo do mal só é preciso que os bons homens não façam nada." Edmund Burke.
"Nunca discutas com pessoas estúpidas. Elas irão te arrastar ao nível delas e vencê-lo por possuir mais experiência em ser ignorante". Mark Twain
Avatar do usuário
MOR_AL
Dword
 
Mensagens: 2934
Registrado em: 19 Out 2006 09:38
Localização: Mangaratiba - RJ

Próximo

Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

cron

x