Página 1 de 2
calculo em asm (Resolvido)

Enviado:
19 Jul 2010 12:56
por diogo_18sp
ola boa tarde a todos do forum estou com uma duvida e queria uma ajuda pois estou fazendo um voltimetro com pic 16f877a e etou com dificuldade de elaborar esta multiplicaçao em assembly;
232 valor em decimal que obtenho do registrador adresh do conversor ad
19,5 o valor da minha constante para multiplicaçao
a duvida seria como vou mutiplicar este valor em asm 232x19,5 para depois mostrar o mesmo em um display de sete segmentos a duvida e como vou multiplicar o 0.5 pois ele naum e um numero inteiro .
obrigado a todos desculpem se minha pergunta for "idiota" obrigado..

Enviado:
19 Jul 2010 13:05
por KrafT
Na época que programava em asm, eu multiplicaria por 195 e depois converteria em dezenas de milhares, milhares, centenas, dezenas e unidades .
Aí já estaria pronto para mostrar no display. Exemplo:
232*195=45240
Como ignoramos a virgula, o 4 passa a ser a milhar, o 5 a centena, o 2 a dezena, o 4 a unidade.
Aí desenha o ponto e manda o 0 como décimo.

Enviado:
19 Jul 2010 13:20
por tcpipchip
1) opcao: somas sucessivas + 50% do valor que foi multiplicado por 19
2) rotacione para direita 1 posicao para pega 50% do valor...
ou
1) multiplicacao bit a bit...dos valores inteiros...
2) some 50% do valor sendo multiplicado por 19...no final da multiplicacao...

Enviado:
19 Jul 2010 17:30
por Djalma Toledo Rodrigues
ADC 10 bits ---> 1024
Se a Tensão de referência for adequadamente escolhida não haverá fração.
Exemplo :
1.040 Vdc ---> 1 mV por Bit
2.080 Vdc ---> 2 mV por Bit
e por essa razão existem CI com essas Tensões de Referência.
DJ

Enviado:
19 Jul 2010 19:10
por diogo_18sp
muito obrigado a todos ,foi elaborar essa parte do programa que multiplica dai volto a falar com vcs se surgir algum problema obrigado pelas respostas

Enviado:
20 Jul 2010 00:10
por ÁgioFelipe
Eu já fiz isso algumas vezes utilizando algo como uma tabela, sem precisar fazer esse monte de conta.

Enviado:
20 Jul 2010 12:49
por diogo_18sp
ÁgioFelipe escreveu:Eu já fiz isso algumas vezes utilizando algo como uma tabela, sem precisar fazer esse monte de conta.
esta tabela que vc sugere teria entaum 256 valores correspondente a cada bit do conversor seria isso entaum?

Enviado:
20 Jul 2010 20:19
por Guri
´e exatamente isso que eu iria sugerir "USAR UMA TABELA"
Eu acho que vc iria criar uma tabela relacionada com os valores de tensão reias do AD em contrapartida com os valores que vc quer que apareça no display...
Coisa do tipo:
Vc lê no AD o valor 10 que suponhamos corresponde-se a 500milivolts (só uma hipótese, ok para exemplo) então vc manda esse valor para o ponteiro da tabela que conterá o valor a ser mostrado no display ou seja 000,500 suponhando um display de 6 digitos.
Uma outra dica bem mais inteligente seria vc utilizar uma tabela externa localizada numa memoria i2c, assim todas as vezes que vc apontar para a tabela a mesma irá direcionar o numero contido nela para a leitura de um vetor na e2prom e nesse vetor vc teria o que desejar...
Eu utilizo essa técnica para mostrar mensagem num LCD, no meu caso eu faço a leitura do AD, e encominho esse valor diretamente para a leitura da memória externa onde por exemplo se eu enviar o numero 01 decimal a minha rotina de leitura da e2prom irá gerar a leitura de um buffer que no meu caso é de 16 bytes, para essa rotina eu utilizo um contador que conta de 0 a 15 os endereço da memória e depois disso sai dessa rotina e começa outra coisa...
No seu caso vc poderia até escrever coisas no seu LCD se é que esta utlizando um, ou alocar na memória externa já os valores bcd apropriados para serem enviados diretamente para um 7 segmentos..
Me desculpe se não consegui ser mais claro, mas se tiver dúvidas de como fazer alguma coisa me avise que postarei aquí o código da e2p

Enviado:
21 Jul 2010 01:33
por jorgeluiz
use aquela rotina basica, pra transforma binario em BCD. So' que divida por multiplos de 5 cada subrotina, pra te dar o resultado no valor real.

Enviado:
24 Jul 2010 04:06
por dan_braz
Resultado: 232 x 19,5 = 4524
Em asm dá pra fazer assim... multiplicar por 19,5 por ser feito:
=(valor x 16) + (valor x 4) - (valor / 2)
=( 3712 ) * ( 928 ) - ( 116 )
=4524
Concorda?
Eu separei a conta em multiplos de 2 para facilitar os cálculos. Em asm você teria que fazer o seguinte:
- copiar o valor AD para 2 bytes, vamos chamar de resh e resl
- rodar resh:resl duas vezes para a esquerda e assim multiplicar por 4
- pegue esse resh:resl e copie para 2 bytes temporários temph:templ
- rode resh:resl mais duas vezes para a esquerda continuando a multiplicação, no total você multiplicou por 16
- some a resh:resl o valor temporário que tem o valor multiplicado por 4 (temph:templ)
- resh:resl vai ter o valor multiplicado por 20 ( (x16)+(x4) ), falta subtrair o x0,5
- copie o resh:resl para o temph:templ
- rode temph:templ para a direita e assim dividir por 2 (que é igual a multiplicar por 0,5)
- subtraia temph:templ de resh:resl deixando resh:resl com o valor multiplicado por 19,5
Parece muita coisa, mas a rotina fica bem enxuta, essa forma de calcular é muito mais rápida do que usar uma rotinha de multiplicação de 16 bits.
O resultado vai ser inteiro arredondado para cima porque a parte decimal foi subtraida.

Enviado:
24 Jul 2010 09:05
por DEJANO
Ola Pessoal!!!
A microchip disponibiliza no site deles, rotinas de calculos, ja prontos em asm. Sao calculos de divisao multiplicacao em 8, 16 e até mais bits.Acho que tem até calculos complexos como raiz, etc..
Esses de multiplicacao nao sao muito grandes nao e faceis de adequar para qualquer programa. De uma olhada la.
Quando eu precisei aplicar um fator de correcao em uma conversao eu utilizei o deles.
Dejano

Enviado:
24 Jul 2010 12:31
por diogo_18sp
OBRIGADO A TODOS TO TERMINANDO MINHA ROTINA DE CALCULO EU PEGUEI A PARTE BAIXA DO BYTE DO REGISTRADOR AD ROTACIONEI 4 VEZES SENDO UMA MULTIPLICAÇAO POR 16 DEPOIS SOMEIMAIS 3 VESES DAI SOMEI O 0,50 QUE FIZ DIVIDINDO O VALOR INICIAL DO AD E SOMANDO ELE NO FINAL ESTOU TRMINANDO A ROTINA DAI POSTO HA SE FUNCIONAR OBRIGADO A TODOS POR SUAS AJUDAS

Enviado:
26 Jul 2010 19:35
por Andre_Cruz
Os arquivos citados pelo DEJANO, é o application node 544 da microchip, que pode ser vista no site da microchip, por esse endereço:
http://www.microchip.com/stellent/idcpl ... ects=an544
André_Cruz

Enviado:
26 Jul 2010 19:46
por Andre_Cruz
Os arquivos citados pelo DEJANO, é o application node 544 da microchip, que pode ser vista no site da microchip, por esse endereço:
http://www.microchip.com/stellent/idcpl ... ects=an544
André_Cruz

Enviado:
26 Jul 2010 23:48
por diogo_18sp
valeu andre e dejano pela ajuda alias toda a galeraestou quase concluindo a rotina de calculo que fiz e agora com esse arquivo posso ter a ideia de onde estao alguns erros na minha rotina vou postala uma parte aki que estou testando ela..
multi
clrf flag
clrf multi_l
clrf multi_h
movlw 0x05 ;carrega com 4 2x2x2x2 = 16
movwf auxi_multi ;contem 4
movf aux_ad,f ;move o conteudo para ele mesmo
btfss status,z ;verrifica se o valor e zero
goto nao_zero ;nao e zero faz o calculo
return ;sim e zero
nao_zero
movf aux_ad,w ;coloca valor em w
movwf multi_l ;carrega com o valor do conversor ad byte parte baixa
movwf auxi_metade ;coloca valor na variavel
rrf auxi_metade,f ;rotaciona divide por 2 e guarda nele mesmo o valor valor de 50%
btfss status,c ;verifica se e negativo a divisao
goto volta_mul
clrf auxi_metade
volta_mul
decfsz auxi_multi,f ;decementa multi 4 vezez a multiplicaçao sera 16
goto mult
movlw 0x04
movwf auxi_multi ;soma 3 vezes
;return;9999999999999999999
goto soma ;soma os valores para atingir 19 vezes
mult
bcf status,c ;limpa a flag c para a multiplicaçao
rlf multi_l,f ;multiplica por 2
rlf multi_h,f
btfss status,c ;testa carry pra ver se e 1
goto volta_mul ;carry e zero
bsf flag,0 ;bit que indica que houve estouro
goto volta_mul ;volta a multiplicar
;***************************************************************************************************
soma
decfsz auxi_multi,f ;decrementa
goto cont
;return;((((((((((((((((((((((((((((((((((((((((((((
goto soma_50 ;soma os 0,5 da conta
cont
bcf status,c ;limpa carry
movf aux_ad,w ;move auxi ad em w
addwf multi_l,f ;soma w + multi_l
btfss status,c ;houve estouro do carry
goto soma ;nao houve estouro do carry
movlw 0x01
addwf multi_h,f
; bsf flag,0
goto soma
soma_50
bcf status,c
movf auxi_metade,w ;coloca o valor de metade em w
addwf multi_l,f ;soma w na parte baixa
btfss status,c ;houve estouro
goto n_houve1 ;naum houve
movlw 0x01
addwf multi_h,f ;sim houve estouro rotaciona bit
return
n_houve1
; btfss flag,0 ;e para incrementar parte alta?
return ;nao incrementa
; incf multi_h,f ;incrementa
; return