Ir ao conteúdo

Otimizar execução de programa assembly, ajuda.


Fervolt

Posts recomendados

Postado

Bom dia a todos,

Gostaria da ajuda dos "experts" em assembly no programa abaixo.

É uma rotina que faz parte de um programa maior, separei só ela pra facilitar a visualização, é responsável por enviar uma sequencia de 18 bits a outro CI

A label de nome "principal" está levando 288us@4MHz para ser executada, gostaria de saber se alguém sabe uma forma de otimizar essa rotina de modo a executar a mesma ação num tempo menor.(sei que se eu colocar um cristal de 20MHz o tempo será bem menor, mas a questão não é essa).


LIST P=PIC16F876A
radix dec
include <P16F876.INC>
__config _hs_osc & _cp_off & _wdt_off & _pwrte_on

;-------Tabela de definicoes de RAM e constantes.

#define enable portb, 0
#define _data portb, 1
#define clock portb, 2

dado equ 20h

aux2 equ 24h


;------- Memoria de Programa ---------

org 0
movlw 10

inicio:
bcf status, rp0
bcf status, rp1
clrf portb
bsf status, rp0
clrf trisb
bcf status, rp0

;-------- Programa principal ---------
principal:
movlw b'00000010'
movwf dado
movlw 5
movwf aux2
call quatro
movlw b'01011001'
movwf dado
movlw 9
movwf aux2
call nove
movlw b'00001000'
movwf dado
movlw 6
movwf aux2
call cinco
bcf enable
goto principal
envia:
bcf clock
bcf _data
decfsz aux2
goto verifica
return
verifica:
btfsc dado, 7
goto envia_1
goto envia_0
envia_0:
bcf _data
rlf dado
bsf clock
goto envia
envia_1:
bsf _data
rlf dado
bsf clock
goto envia
quatro:
bsf enable
swapf dado
call envia
return
nove:
bsf clock
nop
nop
bcf clock
call envia
return
cinco:
swapf dado
call envia
return

end

;............................................................

Coloquei também a tela do osciloscopio do protheus para mostrar o resultado.

Obrigado

Fernando Voltani

post-254226-13884955068441_thumb.jpg

Postado

O que você quer e reduzir o tempo de bit afinal para aumentar a taxa de transmissão? pois ao meu ver é isso que parece.

Transmissão serial de N bits eu faço assim:


cblock ramstart
BufferHi ;buffers
BufferMid
BufferLo

DadoHi ;dados
DadoMid
DadoLo

Bit_Cont ; contador de bits
Endc

.
.
.
.

TX_Service:
MOVLW .2
movwf Bit_Cont
swapf BufferHi,f
rlf BufferHi,f
rlf BufferHi,f 7uS incluindo o call até aqui.
MSBuffer:
bcf STATUS,C
btfsc BufferHi,7
bsf PORTB,0
btfss BufferHi,7
bcf PORTB,0
call delayTbit
rlf BufferHi,f
decfsz bit_cont,f 12uS + 2xTbit até terminar aqui.
goto MSBuffer


movlw 0x08
movwf Bit_Cont
MDBuffer:
bcf STATUS,C
btfsc BufferMid,7
bsf PORTB,0
btfss BufferMid,7
bcf PORTB,0
call delayTbit
rlf BufferMid,f
decfsz bit_cont,f ;48uS + 8*Tbit para terminar aqui.
goto MDBuffer


movlw 0x08
movwf Bit_Cont
LSBuffer:
bcf STATUS,C
btfsc BufferLo,7
bsf PORTB,0
btfss BufferLo,7
bcf PORTB,0
call delayTbit
rlf BufferLo,f
decfsz bit_cont,f ; E aqui tmb.
goto LSBuffer

bsf fim_flag
return

bastaria escolher uma rotina de delay rápida de modo que o tempo de cada bit fosse mínimo.

duvidas pergunte!

abs.

Postado

E ae Felipe, grato pela resposta

Na verdade cara, achei que tem muito call e goto nessa rotina, então gostaria de saber se estou dando bobeira e como não achei nenhum código parecido, resolvi postar.

Vou tentar adaptar seu exemplo para meu uso e ver se fica mais rápido.

Fora isso, o programa completo ainda tem que atualizar 2 displays de 7 seg. multiplexados, ler estado de 2 botões e ler estado de uma porta onde tem um receptor IR, ainda não terminei tudo, mas se o programa ficar "preso" nessa rotina não da tempo de fazer o resto.

Abrass

Fernando Voltani

Postado

Amigo Fervolt, uma transimssão serial de 288uS no porte que ela está de ser 18bits por frame, está com bom desempenho, o que acredito que faça a diferença na rotina, será o tempo de bit ou seja o tempo de quando ele fica em nivel alto ou baixo (lembrando que tem que ser o mesmo para ambos).

está tratando essa rotina dentro de uma interrupção?

abs.

EDIT.: A minha rotina tera de sofrer algumas modificações, primeiro a declaração do pino de clock, e o pino de enable, mas nada muito critico, qual é a velocidade maxima de recepção desse CI ao qual você envia os dados?

Postado

Então,

Funciona assim basicamente:

Existem 2 botões (+ e -) , um incrementa a variável count e o outro decrementa.

Quando pressiono o + por exemplo, vai para interrupção, aí eu tenho de acordo com o valor da variável count uma tabela usando o PCL, somo o valor de count ao PCL, na linha que cair tem um goto para as subrotinas que alimentarão as variáveis do display e as da sequencia que tenho que enviar, depois de todas as variáveis atribuidas, primeiro eu atualizo o display, depois caio nessa rotina e aí fico num loop:

-> atualiza display -> envia sequencia -> verifica botões->loop

Vou terminar e testar pra ver, acho que estou me preocupando antes do tempo.

Cara, agredeço a atenção

Obrigado

Fernando Voltani

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!