LusoRobótica - Robótica em Português
Sistemas específicos => PIC => Tópico iniciado por: iyahdub em 13 de Julho de 2012, 23:04
-
Outra duvida :
Tenho dificuldade em perceber o delay por exemplo am algo basico como um blink; O meu problem relaciona-se com o facto de como e que eu vou poder saber como controlar um delay noutros projectos, de forma que possa ser medido de forma exacta( o quer que isso signifique).
#include <p16F887.inc>
__CONFIG _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
__CONFIG _CONFIG2, _WRT_OFF & _BOR21V
cblock 0x20
Delay1 ; Define two file registers for the
Delay2 ; delay loop
endc
org 0
Start:
bsf STATUS,RP0 ; select Register Bank 1
bcf TRISD,0 ; make IO Pin RD0 an output
bcf STATUS,RP0 ; back to Register Bank 0
MainLoop:
bsf PORTD,0 ; turn on LED RD0
OndelayLoop:
decfsz Delay1,f ; Waste time.
goto OndelayLoop ; The Inner loop takes 3 instructions per loop * 256 loopss = 768 instructions
decfsz Delay2,f ; The outer loop takes and additional 3 instructions per lap * 256 loops
goto OndelayLoop ; (768+3) * 256 = 197376 instructions / 1M instructions per second = 0.197 sec.
; call it two-tenths of a second.
bcf PORTD,0 ; Turn off LED RD0
OffDelayLoop:
decfsz Delay1,f ; same delay as above
goto OffDelayLoop
decfsz Delay2,f
goto OffDelayLoop
goto MainLoop ; Do it again...
end
Delay1 ; Define two file registers for the
Delay2 ; delay loop
e depois temos no codigo
OndelayLoop:
decfsz Delay1,f ; Queimar tempo.de preferencia em vez do Uc.
goto OndelayLoop ; O Inner loop demora 3 instrucoes por loop * 256 loopss = 768 instrucoes
decfsz Delay2,f ; O outer loop demora umas adicionais 3 instrucoes por volta * 256 loops
goto OndelayLoop ; (768+3) * 256 = 197376 instrucoes / 1M instrucoes por segundo = 0.197 sec.
; chamemos-lhe 2 decimos de segundo
E suposto demorar (768 + 3) * 256 = 197376 ?s = 0.197s... e piscar a 2.5 Hz
O meu problema e como e que posso criar uma maneira de criar um delay mais facil de usar, e que possa ser medido em segundos talvez ?!?...
Existe alguma maneira de criar macros ?!? Ou coisa parecida (ja que ja ouvi falar de macros e nao sei se seria neste caso aplicavel).
Obrigada em avanco
PS- quaisquer material de leitura que possa ajudar tb e bem vindo,claro...Nao tenho medo de ler e pesquisar, de preferencia com exemplos...
-
Alias ja agora uso o exemplo do Sena, que nos disponibilizou graciosamente estas perolas...
;#################################################################################
;
; Este programa inverte todos os pinos da porta B, a cada 100ms
;
; v1.0 01/02/2008 PIC16F886
;
; Autor: António Sérgio Sena, [url=http://www.senaeng.com]www.senaeng.com[/url]
;
;#################################################################################
processor 16F887 ;configura o tipo de CPU usado
radix hex ;pre-definicao do tipo de valores numericos usados
include "P16F887.inc" ;inclui pre-definicoes do processador
__config _CONFIG1, _DEBUG_OFF & _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
__config _CONFIG2, _WRT_OFF & _BOR40V
;---------------------------
temp equ 0x20 ;define endereco 0x20 com o nome de TEMP
temp2 equ 0x21 ;define endereco 0x21 com o nome de TEMP2
temp3 equ 0x22
;---------------------------
inicio
;configura toda a porta A para entrada/saida DIGITAL
banksel ANSEL ;muda para o banco onde está o registo ANSEL
clrf ANSEL ;limpa o registo ANSEL
clrf ANSELH ;limpa o registo ANSELH
;configura portas A e B como entradas/saidas
banksel TRISA ;muda para banco onde está o registo TRISA
movlw 0x00 ;carrega W com 0x00, todos pinos porta A como saida
movwf TRISA ;move de W para TRISA
movlw 0x00 ;carrega W com 0x00, todos pinos porta B como saida
movwf TRISB ;move de W para TRISB
movlw 0x00 ;carrega W com 0x00, todos pinos porta C como saida
movwf TRISC ;move de W para TRISC
movlw 0x00 ;carrega W com 0x00, todos pinos porta d como saida
movwf TRISD ;move de W para TRISD
movlw 0x00 ;carrega W com 0x00, todos pinos porta e como saida
movwf TRISE ;move de W para TRISE
banksel PORTA ;muda para banco onde está o registo PORTA
clrf PORTA ;desactiva todos os drivers de saída da porta A
clrf PORTB ;desactiva todos os drivers de saída da porta B
clrf PORTC ;desactiva todos os drivers de saída da porta C
clrf PORTD ;desactiva todos os drivers de saída da porta D
clrf PORTE ;desactiva todos os drivers de saída da porta E
repete
movlw b'00001111' ;0x01
xorwf PORTB, f ;inverte porta B (XOR, OU Exclusivo com o W)
call atraso_100m ;chama rotina de atraso
goto repete ;faz temporizacao de novo
;---------------------------
atraso_1s
movlw .10
movwf temp3
call atraso_100m
decfsz temp3, f
goto $-2
return
;---------------------------
atraso_100m
movlw 0xc7 ;carrega W com o valor 0xC7
movwf temp2 ;move valor em W para TEMP
call atraso_500u ;
decfsz temp2, f ;decrementa TEMP em uma unidade, coloca resultado em TEMP
;e salta a instrucao seguinte, se o resultado for zero
goto $-2 ; salta para as duas instrucoes anteriores
return ;sai fora da rotina de ATRASO
;---------------------------
atraso_500u
movlw 0xA5 ;carrega W com o valor 0xA5
movwf temp ;move valor em W para TEMP
decfsz temp, f ;decrementa TEMP em uma unidade, coloca resultado em TEMP
;e salta a instrucao seguinte, se o resultado for zero
goto $-1 ;salta para uma instrucao anterior
return ;sai fora da rotina de ATRASO
;---------------------------
end
;c328
Seriam estas rotinas de atraso por exemplo utilizaveis noutro caso?!? Parece-me que sim, mas existira um metodo melhor que outro ?!?
-
E suposto demorar (768 + 3) * 256 = 197376 ?s = 0.197s... e piscar a 2.5 Hz
Normalmente as contas são ::
( (A * N) * M) + picos ;D
A = nº de ciclos por loop
N = normalmente 256, pois são os 8bit do registo (pode ter outro valor, para afinar os contadores, mas vms supor que agora é assim)
M = este M multiplicador pode ser repetido várias vezes, quantos mais :: mais tempo de espera
picos = nº ciclos que demora a entrar e sair da função
ex:
OffDelayLoop:
decfsz Delay1,f ; same delay as above
goto OffDelayLoop
decfsz Delay2,f
goto OffDelayLoop
((3 * Delay1) * Delay2) + picos
Experimenta no MPLAB a simulação, passo-a-passo, com a janel da Watch e com o Stopwatch, para veres como funciona a coisa.
O meu problema e como e que posso criar uma maneira de criar um delay mais facil de usar, e que possa ser medido em segundos talvez ?!?...
Existe alguma maneira de criar macros ?!? Ou coisa parecida (ja que ja ouvi falar de macros e nao sei se seria neste caso aplicavel).
Sim, Macros é uma excelente opção, tornam a vida muito mais facilitada, especialmente se não houver preocupações de falta de memória.
O Help do MPLAB é bom nesse aspecto.
-
Alias ja agora uso o exemplo do Sena, que nos disponibilizou graciosamente estas perolas...
;#################################################################################
;
; Este programa inverte todos os pinos da porta B, a cada 100ms
;
; v1.0 01/02/2008 PIC16F886
;
; Autor: António Sérgio Sena, [url=http://www.senaeng.com]www.senaeng.com[/url]
;
;#################################################################################
processor 16F887 ;configura o tipo de CPU usado
radix hex ;pre-definicao do tipo de valores numericos usados
include "P16F887.inc" ;inclui pre-definicoes do processador
__config _CONFIG1, _DEBUG_OFF & _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
__config _CONFIG2, _WRT_OFF & _BOR40V
;---------------------------
temp equ 0x20 ;define endereco 0x20 com o nome de TEMP
temp2 equ 0x21 ;define endereco 0x21 com o nome de TEMP2
temp3 equ 0x22
;---------------------------
inicio
;configura toda a porta A para entrada/saida DIGITAL
banksel ANSEL ;muda para o banco onde está o registo ANSEL
clrf ANSEL ;limpa o registo ANSEL
clrf ANSELH ;limpa o registo ANSELH
;configura portas A e B como entradas/saidas
banksel TRISA ;muda para banco onde está o registo TRISA
movlw 0x00 ;carrega W com 0x00, todos pinos porta A como saida
movwf TRISA ;move de W para TRISA
movlw 0x00 ;carrega W com 0x00, todos pinos porta B como saida
movwf TRISB ;move de W para TRISB
movlw 0x00 ;carrega W com 0x00, todos pinos porta C como saida
movwf TRISC ;move de W para TRISC
movlw 0x00 ;carrega W com 0x00, todos pinos porta d como saida
movwf TRISD ;move de W para TRISD
movlw 0x00 ;carrega W com 0x00, todos pinos porta e como saida
movwf TRISE ;move de W para TRISE
banksel PORTA ;muda para banco onde está o registo PORTA
clrf PORTA ;desactiva todos os drivers de saída da porta A
clrf PORTB ;desactiva todos os drivers de saída da porta B
clrf PORTC ;desactiva todos os drivers de saída da porta C
clrf PORTD ;desactiva todos os drivers de saída da porta D
clrf PORTE ;desactiva todos os drivers de saída da porta E
repete
movlw b'00001111' ;0x01
xorwf PORTB, f ;inverte porta B (XOR, OU Exclusivo com o W)
call atraso_100m ;chama rotina de atraso
goto repete ;faz temporizacao de novo
;---------------------------
atraso_1s
movlw .10
movwf temp3
call atraso_100m
decfsz temp3, f
goto $-2
return
;---------------------------
atraso_100m
movlw 0xc7 ;carrega W com o valor 0xC7
movwf temp2 ;move valor em W para TEMP
call atraso_500u ;
decfsz temp2, f ;decrementa TEMP em uma unidade, coloca resultado em TEMP
;e salta a instrucao seguinte, se o resultado for zero
goto $-2 ; salta para as duas instrucoes anteriores
return ;sai fora da rotina de ATRASO
;---------------------------
atraso_500u
movlw 0xA5 ;carrega W com o valor 0xA5
movwf temp ;move valor em W para TEMP
decfsz temp, f ;decrementa TEMP em uma unidade, coloca resultado em TEMP
;e salta a instrucao seguinte, se o resultado for zero
goto $-1 ;salta para uma instrucao anterior
return ;sai fora da rotina de ATRASO
;---------------------------
end
Seriam estas rotinas de atraso por exemplo utilizaveis noutro caso?!? Parece-me que sim, mas existira um metodo melhor que outro ?!?
Esta é uma forma de o fazer. Há mais.
Esta foi a escolhida, como educacional para apresentar loops e chamadas de funções dentro de funções.
Para nós próprios, e depois de saber, podem criar-se funções sem chamadas, com os loops todos seguidos.
Ou então temporizadores por interrupção :) uma batalha mais para a frente.
-
Isso era outra pergunta que tenho andado a tentar responder...
Onde esta essa janela do watch e stop watch ?!? Eu acho que encontei a primeira mas qual e o registo q devo activar para que possa ver !?
-
Isso era outra pergunta que tenho andado a tentar responder...
Onde esta essa janela do watch e stop watch ?!? Eu acho que encontei a primeira mas qual e o registo q devo activar para que possa ver !?
No MPLAB
menús VIEW e DEBBUGER
-
AHHHHHHHHH assim , sim !!
No pick it2 nao disponibiliza, no entanto, era por isso que nao o via.
E no watch- existe algum SFRegister que conte os ciclos ?!? Agora estou perdido, nesse...
-
AHHHHHHHHH assim , sim !!
No pick it2 nao disponibiliza, no entanto, era por isso que nao o via.
E no watch- existe algum SFRegister que conte os ciclos ?!? Agora estou perdido, nesse...
o que são "ciclos", para ti ?
-
Nao sei... lol Lembra-te que nao estou em portugal a muito tempo, por isso explico-me o melhor que sei. Ciclos do Chip... Mas neste caso procurava algo que conte algo tangivel, para que me possa guiar durante o debugging ao menos( que o stop watch ja o faz, claro)...Mas como tb mencionaste o WATCH no Menu View, pensei qye houvesse alghum register que tb me desse info parecida/igual.
Ainda escapa no que toca a programar, mas hardware estou mesmo as cegas !! Lembra-te que isto e tudo muito novo para mim, no que toca a chips e sua arquitectura
-
O stopwatch também te dá a contagem de ciclos!
Falta-te alguma coisa?