Ir ao conteúdo

Posts recomendados

Postado

Olá! Estou utilizando Timer0 e Interrupção Externa com borda de subida (RB0/INT) num PIC16F73, de modo que, se o pino RB0/INT permanecer em nível alto por mais de 1000ms, o pino RA1 tem que ter seu estado invertido por meio de rotina implementada no Timer0, conforme código abaixo. Ou seja, ao manter em nível alto o pino RB0/INT (da interrupção externa) por mais de 1 segundo, a saída RA1 inverte continuamente seu estado até que seja retirado o nível alto de RB0/INT.

 

PROBLEMA:
Se eu colocar RB0 em nível baixo enquanto RA1 está em nível alto, RA1 se mantém assim. Isso está OK.
PORÉM, se eu voltar a colocar RB0/INT em nível alto, mesmo que seja por menos de 1000mseg, RA1 volta para nível baixo sem passar pela rotina de inversão de estado do Timer0 (eu testei), o que é um problema, pois esta saída só deveria ter seu estado invertido se RB0/INT permanecesse por mais de 1000mseg em nível alto.


Alguém sabe o que pode estar gerando este comportamento estranho?

#INT_TIMER0
void TMR0_isr(void)
{
// ROTINA DO TIMER0 COM ESTOURO DE 1MS

    if (INTCON_TMR0IF) {
        // Zera a flag de Timer0
        INTCON_TMR0IF = 0;

        // Verifica nível lógico de RB0/INT.
        if (input(PIN_B0))
            TMR0_counter++;
        else
            TMR0_counter = 0;

        if (TMR0_counter > 1000){
            PORTAA_0 = !PORTAA_0;
            TMR0_counter = 0;
        }
    }
}

 

  • Membro VIP
Postado

oi de novo...

Haja bola de cristal viu. ...Programa completo por gentileza. Esquemático também cai bem.

 

Mas antes verifique se:

-outra interrupt ou no main() você zoa com RA0, RB0 ou TMR0_counter

-tipo de variável correto pata TMR0_counter pra caber 1000

-wdog, cristal e afins

-correto setup do timer

-cadê o valor de reload do TIMER0? Ou ajustou o setup pra 0x00 dar certo?

-etc

 

Eu gosto + de RA0^=1. Também prefiro if (x>999)... isto é , se 1mS for importante

abç

Postado

Olá Isadora. Não há muito o que mostrar no código todo, pois preparo pequenos trechos de teste a parte, antes de passar para o código definitivo em outro projeto. Mas segue abaixo o teste completo. Sobre o circuito, faço da mesma forma, ou seja, tudo de teste e que neste caso é um botão de pull down para o RB0 (com capacitor e resistor) e um LED em RA1, além do cristal. Circuito super enxuto só para teste mesmo....

 

Código:

#include <16f73.h>
#fuses HS, NOWDT
#use fast_io(A)

// Ciclo de máquina 500E-9
#use delay(clock=8MHz,crystal=8MHz)

// Registrador do Timer0
#byte INTCON 	   = 0x0B
// Flag estouro do TMR0
#bit INTCON_TMR0IF = INTCON.2
// Flag de interrupção Externa RB0/INT
#bit INTCON_INTF   = INTCON.1

// Registrador de configuração do Timer0
#byte OPTION_REG = 0x81
// Registrador de contagem do Timer0
#byte TMR0 		 = 0x01

// Registrador de Porta A
#byte PORTAA 	 = 0x05
#bit  PORTAA_0 	 = PORTAA.0

// Inicialização da base de tempo do Timer0
#define TMR0_INIT 0x06

// Contador do Time0
int16 TMR0_counter; 

#INT_EXT
void  EXT_isr(void) 
{
	if (INTCON_INTF) {
		INTCON_INTF = 0;
		// apenas teste
	}
}


#INT_TIMER0
void TMR0_isr(void)
{
	if (INTCON_TMR0IF) {
		INTCON_TMR0IF = 0;
		TMR0 = TMR0_INIT;  // Reinicialização de Timer0 (8bits) em 6

		if (input(PIN_B0))
			TMR0_counter++;
		else
			TMR0_counter = 0;

		if (TMR0_counter > 1000){
			PORTAA_0 = !PORTAA_0;
			TMR0_counter = 0;
		}

		// Evita o estouro da variável
		if (TMR0_counter > 65000)
			TMR0_counter = 1000;
	}
}


void main()
{
	// Inicializa o registrador de configurações do Timer0
	OPTION_REG = 0x82;	// Prescaler 8

	// Inicializa o registrador de contagem do Timer0
	TMR0	   = TMR0_INIT;

	// Inicializa o registrador de habilitação do Timer0
	INTCON	   = 0xE0;	// Habilita a interrupção por periféricos
						// Habilita o Timer0
	
	// Seta toda a "Porta A" como entrada, exceto o pino 1
	set_tris_a(0xFE);
	set_tris_b(0xFF);


	enable_interrupts(INT_EXT);
	ext_int_edge (L_TO_H);
	enable_interrupts(GLOBAL);

	output_low(PIN_A0);

	TMR0_counter = 0;
	PORTAA_0     = 0;
	
	while(true){

	}
}

 

Postado

@Isadora Ferraz , você que entende bastante dos macetes de uC, por favor confirme minha teoria sobre uma possível solução que encontrei para o problema.

 

Lendo o datasheet, verifiquei a seguinte nota de rodapé para este pino RB0 :

"This buffer is a Schmitt Trigger input when configured as the external interrupt."

 

Sendo assim, considerei que possíveis ruidos (bounce) gerados ao pressionar o botão de pull down ligado (com resistor e capacitor) neste pino, seriam ignorados pelo Schmitt Trigger. Porém o efeito gerado pela descarga do capacitor não seria ignorado pelo Schmitt Trigger, gerando o problema que descrevi. Ao retirar o capacitor, aparentemente o problema acabou.

 

Você concorda com essa teoria ou esse resultado é apenas uma "aparente solução"?

 

Obrigado.

  • Membro VIP
Postado
17 horas atrás, wBB disse:

Não há muito o que mostrar no código todo,

talvez não .. mas você colocou isso...

17 horas atrás, wBB disse:

TMR0 = TMR0_INIT; // Reinicialização de Timer0 (8bits)

no 2º post e era importante e era sim "muito o que mostrar no código" (lembra que preguntei sobre?) e sabe-se lá o que você tinha feito antes na EXT_isr(void)... Desabilite as interrupts que não usa pra ver se estão zoando o barraco

 

talvez não você mas o compilador pode ter zoado. A dica que que dou é: rode na simulação proteus p.ex. ou rode na real passo a passo ou coloque break points onde acha que o problema ocorre e etc.

 

Penso que você deve investigar melhor. Algo como bugs do compilador ou até mesmo, BIOS ou entre a cadeira e teclado (kk calma!)

Penso que esquema é importante sim pois dá uma visão mais macro da coisa. P.ex não sei se você colocou capacitor pro gnd ou vcc.  Se você decidir que vale a pena publicar, decido se vale a pena analisar melhor ok? Se estiver montando em protoboard aí então meu nêgo... o buraco é + em baixo, esquema não basta,  ruídos, correntes parasitas e etc. Até mesmo fotos seriam necessárias (antes de eu ir aí montar pra você kk) mas penso que o problema é muito simples. Como sempre digo, muito p pra pouca b... sem desmerecer seu projeto hein!!

 

Postado

Não tinha mais nada além do código que postei depois que você pediu. No início eu coloquei só aquilo para simplificar e não gerar um tópico com muito texto... só esse lance do "TMR0 = TMR0_INIT;" que eu não tinha reparado que retirei, mas foi sem perceber. Mas OK!

 

3 horas atrás, Isadora Ferraz disse:

sabe-se lá o que você tinha feito antes na EXT_isr(void)

Não tinha nada..

 

Sobre o capacitor, coloquei para o gnd;

A montagem é em protoboard (em geral faço assim);

No Proteus eu até gostaria de testar, mas ainda não encontrei a library de PIC que contenha o modelo 16F73 (conforme comentei em um outro tópico anterior), que tenho que usar nestes testes;

 

Imagino que o problema possa ser bem simples realmente, e mesmo sem muita experiência sou capaz de apostar que o problema está resolvido com essa modificação que citei anteriormente (da retirada do capacitor), porém não tenho como provar. Só posso acreditar no que os testes estão me mostrando...

Visitante
Este tópico está impedido de receber 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!