-
Posts
132 -
Cadastrado em
-
Última visita
Reputação
0-
Olá Paulo, finalmente consegui implementar um código que sai da interrupção e retorna à ela fazendo um novo ciclo. Dá uma conferida para nós. 'PIC 16F628A Define CONF_WORD = 0x3f50 Define CLOCK_FREQUENCY = 4 TRISA = 0xff 'seta todas portas A como entrada TRISB = 00000111b 'portas 0, 1 e 2 como entrada as demais saida Dim conta As Byte PORTB.5 = 0 AllDigital OPTION_REG.T0CS = 0 'USAR CLOCK INTERNO OPTION_REG.PSA = 0 'PS2, PS1, PS0 CONFIGURADOS PARA PRESCALER = 4 OPTION_REG.PS2 = 0 OPTION_REG.PS1 = 0 OPTION_REG.PS0 = 1 TMR0 = 0x06 'CONTAGEM INICIAL DO TIMER0 EM 6 INTCON.T0IE = 1 'habilita timer0 interrupção INTCON.GIE = 1 'habilitas todos interrupções un-masked OPTION_REG.T0CS = 0 'definir fonte de relógio timer0 de instrução interna do relógio de ciclo Enable alarme: If conta = 10 Then conta = 0 PORTB.7 = 1 WaitMs 10 PORTB.7 = 0 Goto continua Endif End ________________________________________________________ On Interrupt 'interrompe a rotina à cada 1 mS Save System conta = conta + 1 If conta = 10 Then Goto sai Endif Goto continua sai: Goto alarme continua: TMR0 = 0x06 Resume _____________________________________________________________
-
Ok, vou continuar pesquisando. Eu vi um vídeo muito bom de um camarada a respeito do TIMER0, ele tem várias videos-aulas porém ele se dedica ao MikroC. Ele mostra um exemplo e diz que a garantia de que houve um estouro é o T0IF ir a 1 então ele condiciona sua variável a sofrer incremento só quando essa condição é satisfeita e depois ele faz o T0IF = 0, eu acho que seria assim: aqui houve estouro então If INTCON.T0IF = 1 then conta = conta + 1 INTCON.T0IF = 0 endif vai para novo estouro........................................................... De tanto errar um dia eu acerto kkkkkkkkkkkkkkkkkkkkkkkkkkk, como na mega um dia eu acerto kkkkkkkkkkkkkkkkkkkkkkkkk.
-
Olá Paulo, após fazer varios ensaios para ver porque a minha gambiarra funcionava embora toda errada e a tua sugestão não fazia a recontagem e ficava trancada no end. A moral é o seguinte na minha gambiarra a execução da rotina de interrupção nunca chegava a executar o RESUME pois antes era desviada através de um goto ciclo, fazendo sempre esse laço sem encerrar com RESUME pois a partir do momento que fizer o RESUME a coisa não implementa mais a variravel CONTA conforme havia comentado. Pergunto então, estaria correto fazer assim? Veja como ficou a titulo de exemplo o codigo: 'PIC 16F628A Define CONF_WORD = 0x3f50 Define CLOCK_FREQUENCY = 4 AllDigital TRISA = 0xff 'seta todas portas A como entrada TRISB = 00000111b 'portas 0, 1 e 2 como entrada as demais saida Dim conta As Byte Dim flag_1 As Byte PORTB.5 = 0 'WaitMs 100 'Vamos esperar o sensor estabilizar e depois mandar o pulso OPTION_REG.T0CS = 0 'USAR CLOCK INTERNO OPTION_REG.PSA = 0 'PS2, PS1, PS0 CONFIGURADOS PARA PRESCALER = 4 OPTION_REG.PS2 = 0 OPTION_REG.PS1 = 0 OPTION_REG.PS0 = 1 TMR0 = 0x06 'CONTAGEM INICIAL DO TIMER0 EM 6 INTCON.T0IE = 1 'habilita timer0 interrupção INTCON.GIE = 1 'habilitas todos interrupções un-masked OPTION_REG.T0CS = 0 'definir fonte de relógio timer0 de instrução interna do relógio de ciclo Enable ciclo: PORTB.5 = 1 WaitUs 10 PORTB.5 = 0 Goto contagem verifica: If conta < 10 Then PORTB.7 = 1 WaitMs 10 PORTB.7 = 0 conta = 0 Goto ciclo 'Eco não retornou no tempo previsto, alarma e retorna novo ciclo Else conta = 0 Goto ciclo 'Tudo ok eco retornou em tempo portanto faz novo ciclo Endif End__________________________________________________________________ contagem: On Interrupt 'interrompe a rotina à cada 1 mS Save System conta = conta + 1 If PORTA.4 = 0 Then 'se recebeu o eco porta.4 vai de 1 para ZERO Goto verifica 'sair ' aqui ele tem que ir para esperando para verificar e já leva o valor de conta que se for igual a 10 alarma Endif sair: TMR0 = 0x06 Goto ciclo Resume________________________________________________________________________________________
-
Poderia simplificar e cortar um monte de instruções, deixando só o básico, entre a linha enable e o end só um laço para criar uma situação de sair da interrupção e retornar para ela novamente para ver se ela faz uma segunda entrada e um novo incremento da variável com isso acho com 50 linhas seria possível. Interessante que o meu projeto inicial onde a interrupção estava meio confusa inclusive tu pediu para eu colocar no final, fora daquele emaranhado todo a coisa em termos até funcionava isso é havia sucessivos incrementos e agora não, apenas um incremento inicial.
-
Oi Paulo, pelos experimentos que fiz, Alldigital não influenciou em nada e sem o Save System não funciona nada e se colocar o Intcon.t0if = 0 também. Troquei o pic pelo 16F648A que tem 256 bytes de ram também não resolveu. Resumindo só há incremento da variável na primeira passagem pela interrupção e ao sair dela e entrar em um novo ciclo congela no end.
-
Olá Paulo, retornando ao nosso estudo. Eu implementei a rotina seguindo tuas instruções e fiz ensaios no PSI. Forcei uma situação para Alarme onde PORTB.7 vai a 1 e uma situação em que o ECO chega no tempo previsto e a PORTA.4 vai a 0, até ai tudo OK. Mas estou tendo o seguinte problema: Quando rodo o programa na primeira vez ele vai ate a interrupção e encrementa a variável CONTA após isso vai para verificação para saber se a situação é de ALARME ou não e de lá vai para CICLO onde novamente envio o pulso de 10 uS para o TRIGGER e vou novamente para interrupção pra incrementar novamente a varíavel CONTA =====> śo que isso não ocorre, não há mais interrupções e a variável CONTA não sofre mais incrementos e o programa parece ficar parado no END. /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// ciclo: conta = 0 flag_1 = 0 PORTB.5 = 1 WaitUs 10 PORTB.5 = 0 Goto contagem verifica: If flag_1 = 1 Then If conta < 40 Then PORTB.7 = 1 WaitMs 10 PORTB.7 = 0 Goto ciclo 'Eco não retornou no tempo previsto, alarma e retorna novo ciclo Else Goto ciclo 'Tudo ok eco retornou em tempo portanto faz novo ciclo Endif Else '===========>>> Se o Flag_1 = 0 significa que o Eco ainda não chegou portanto volta a verificar Goto verifica Endif contagem: End_______________________________________________________________________________________________ On Interrupt 'interrompe a rotina à cada 1 mS Save System If flag_1 = 1 Then Goto sair Endif conta = conta + 1 If PORTA.4 = 0 Then 'se recebeu o eco porta.4 vai de 1 para ZERO flag_1 = 1 Goto verifica 'aqui ele tem que ir para esperando para verificar e já leva o valor de conta que se for igual a 10 alarma Endif If conta = 40 Then flag_1 = 1 Goto verifica 'aqui conta chegou a 10 e portb = 1 mas portb.4 = 1 ==> ECO não chegou então tem que alarmar Endif sair: TMR0 = 0x06 Resume___________________________________________________________________________________________
-
Paulo, agora eu é que fiquei confuso, pois se era para preservar a rotina de interrupção mantendo ela sem muita interferência para não atrapalhar, agora ela está cheia de tarefas agindo durante sua execução. A não ser que tenha entendido tudo errado. Conforme entendi ficou assim: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// flag_1 = 0 PORTB.5 = 1 'aqui geramos pulso de 10 uS para o trigger WaitUs 10 PORTB.5 = 0 If flag_1 = 1 Then If conta = 40 Then 'não houve retorno do eco PORTB.7 = 1 'saida de alarme WaitMs 10 PORTB.7 = 0 Endif Endif End _________________________________________________________________________________ On Interrupt 'interrompe a rotina à cada 1 mS If flag_1 = 0 Then 'se for zero faz a rotina, se for 1 vai direto ao fim Save System TMR0 = 0x06 'zera contagem Endif If flag_1 = 1 Then Goto sair 'pula direto para o fim Endif If PORTA.4 = 0 Then 'se recebeu o eco porta.4 vai de 1 para ZERO flag_1 = 1 Goto sair ' pula direto para o fim Endif conta = conta + 1 If conta = 40 Then flag_1 = 1 Endif sair: Resume _____________________________________________________________________________________
-
Paulo agora sim, tu deu nos dedos. Esse é meu problema, eu ainda não consegui entender como pegar o resultado da minha variável conta dentro da rotina de interrupção sem entrar nela. Sei que essa informação está gravada na memória do pic só não sei o caminho para chegar lá. Você fala em criar um Flag, seria esse o caminho? Vou dar uma pesquisada para entender como trabalhar com Flags.
-
OK Paulo, implementei as modificações mas na prática continua igual, parece que só trocou 6 por 1/2 dúzia pois o resultado é o mesmo. Ficou assim: 'SENSOR DE MOVIMENTO 'PIC 16F628A Define CONF_WORD = 0x3f50 Define CLOCK_FREQUENCY = 4 TRISA = 0xff 'seta todas portas A como entrada TRISB = 00000111b 'portas 0, 1 e 2 como entrada as demais saida Dim conta As Byte Dim tempo(4) As Byte Dim x As Byte Dim i As Byte Dim medida(2) As Byte Dim tolerancia1 As Byte Dim tolerancia2 As Byte PORTB.5 = 0 WaitMs 100 'Vamos esperar o sensor estabilizar e depois mandar o pulso OPTION_REG.T0CS = 0 'USAR CLOCK INTERNO OPTION_REG.PSA = 0 'PS2, PS1, PS0 CONFIGURADOS PARA PRESCALER = 4 OPTION_REG.PS2 = 0 OPTION_REG.PS1 = 0 OPTION_REG.PS0 = 1 TMR0 = 0x06 'CONTAGEM INICIAL DO TIMER0 EM 6 INTCON.T0IE = 1 'habilita timer0 interrupção INTCON.GIE = 1 'habilitas todos interrupções un-masked OPTION_REG.T0CS = 0 'definir fonte de relógio timer0 de instrução interna do relógio de ciclo Enable medida(0) = 0 medida(1) = 0 i = 0 ciclo: conta = 0 tempo(0) = 0 tempo(1) = 0 tempo(2) = 0 tempo(3) = 0 x = 0 For x = 0 To 4 'Vamos medir 4 vezes e fazer a media If x = 4 Then Goto registra Endif PORTB.5 = 1 'aqui geramos o pulso TRIGGER de 10 uS aprox para o SRF04 WaitUs 10 PORTB.5 = 0 verifica: If PORTA.4 = 1 Then 'aqui monitoramos a porta ECHO do SRF04 Goto mede Endif Goto verifica alarme: tolerancia1 = medida(1) + ((medida(1) * 10) / 100) 'tolerancia de 10% para erro tolerancia2 = medida(1) - ((medida(1) * 10) / 100) If tolerancia2 <= medida(0) And medida(0) <= tolerancia1 Then 'aqui aceito erro de 10% abaixo e acima PORTB.7 = 0 Else PORTB.7 = 1 WaitMs 10 PORTB.7 = 0 Endif tolerancia1 = 0 tolerancia2 = 0 medida(0) = 0 medida(1) = 0 Goto ciclo testa: If PORTA.4 = 0 Then tempo(x) = conta 'AQUI SALVAMOS A MEDIDA DO TEMPO conta = 0 Goto retorna 'faz voltar para proximo x Endif Goto mede retorna: Next x registra: medida(i) = tempo(0) + tempo(1) + tempo(2) + tempo(3) If i = 0 Then i = 1 Goto ciclo Endif If i = 1 Then i = 0 Goto alarme Endif End______________________________________________________________________ mede: On Interrupt 'interrompe a rotina à cada 1 mS Save System conta = conta + 1 'aqui faz incremento a cada 1 mS TMR0 = 0x06 'zera contagem INTCON.T0IF = 0 'habilita nova interrupção Goto testa Resume___________________________________________________________________
-
Paulo a situação é a seguinte: Montando o circuito eu tenho o led da portb.7 piscando e quando passo a mão na frente do SFR04 dá pra perceber alteração no led e quando chego a 15cm aprox. o led tende a apagar. Implementei uma tolerância de 10% depois de 20% até chegar em 30% mas não houve melhoras significativas. Retirando a conexão que envia pulso para o trigger o led apaga como deveria acontecer. Parece que o sistema em si está ok e o problema estaria no código. Nos testes estou com sensor a 1,80 mt da parede.
-
Beleza Mestre, o pouco que eu sei é em basic através da tua apostila, vamos lá: Eu configurei o TIMER0 para fazer interrupções à cada 1 mS e incrementar minha variavel para ter um parâmetro para comprarar o tempo do ECO à cada vez que eu mando um pulso no TRIGGER. 'SENSOR DE MOVIMENTO '07/07/2015 'PIC 16F628A Define CONF_WORD = 0x3f50 Define CLOCK_FREQUENCY = 4 TRISA = 0xff 'seta todas portas A como entrada TRISB = 00000111b 'portas 0, 1 e 2 como entrada as demais saida Dim conta As Byte Dim tempo(4) As Byte Dim x As Byte Dim i As Byte Dim medida(2) As Byte PORTB.5 = 0 WaitMs 100 'Vamos esperar o sensor estabilizar e depois mandar o pulso OPTION_REG.T0CS = 0 'USAR CLOCK INTERNO OPTION_REG.PSA = 0 'PS2, PS1, PS0 CONFIGURADOS PARA PRESCALER = 4 OPTION_REG.PS2 = 0 OPTION_REG.PS1 = 0 OPTION_REG.PS0 = 1 TMR0 = 0x06 'CONTAGEM INICIAL DO TIMER0 EM 6 INTCON.T0IE = 1 'habilita timer0 interrupção INTCON.GIE = 1 'habilitas todos interrupções un-masked OPTION_REG.T0CS = 0 'definir fonte de relógio timer0 de instrução interna do relógio de ciclo Enable medida(0) = 0 medida(1) = 0 i = 0 ciclo: conta = 0 tempo(0) = 0 tempo(1) = 0 tempo(2) = 0 tempo(3) = 0 x = 0 For x = 0 To 4 'Vamos medir 4 vezes e fazer a media If x = 4 Then Goto registra Endif PORTB.5 = 1 'aqui geramos o pulso TRIGGER de 10 uS aprox para o SRF04 WaitUs 10 PORTB.5 = 0 verifica: If PORTA.4 = 1 Then 'aqui monitoramos a porta ECHO do SRF04 Goto mede Endif Goto verifica alarme: If medida(0) = medida(1) Then 'se o tempos forem iguais PORTB.7 = 0 Else PORTB.7 = 1 WaitMs 10 PORTB.7 = 0 Endif medida(0) = 0 medida(1) = 0 Goto ciclo End mede: On Interrupt 'interrompe a rotina à cada 1 mS conta = conta + 1 'aqui faz incremento a cada 1 mS TMR0 = 0x06 'zera contagem INTCON.T0IF = 0 'habilita nova interrupção If PORTA.4 = 0 Then tempo(x) = conta 'AQUI SALVAMOS A MEDIDA DO TEMPO conta = 0 Goto retorna Endif Goto mede retorna: 'faz voltar para proximo x Next x registra: medida(i) = tempo(0) + tempo(1) + tempo(2) + tempo(3) Select Case i Case 0 i = 1 Goto ciclo Case 1 i = 0 Goto alarme EndSelect Resume
-
Olá meus amigos desse forum, um abraço a todos em especial ao meu queridissimo professor Paulo. Gostaria de aproveitar esse espaço e pedir uma orientação pois estou tendo dificuldades em um pequeno projeto usando o sensor SRF04. Trata-se de um sensor de movimento por ultrassom, o código que desenvolvi é em basic usando o PSI. Se houver alguém interessado em ajudar poderei postar meu codigo para analise.
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