1 votos

Cómo controlar la interrupción utilizando el temporizador en el microcontrolador

Hola, estoy usando un microcontrolador 8051. Tengo un medidor de agua digital que da datos de tipo binario 0 1 0 1. Lo conecté con el 8051 INT1 para que pueda obtener la interrupción. Ahora, cuando el flujo de agua a través del medidor se iniciará el envío de interrupción (pulsos de 0101) a 8051 INT1. Ahora quiero contar el total de pulsos y enviarlo.

Para ello estoy usando este programa en Kiel en lenguaje C : [2da Actualización]

#include<reg51.h> // include at89x51 . h
#include<stdio.h>// include stdio . h
#include<stdlib.h>// include stdlib . h

unsigned long  value,x;
unsigned long check;
unsigned long time_overflow_count=0;
void initialize_GSM_modem(void);
void initialize_serialcommunication(void);
unsigned char Command_CMGF[]="AT+CMGF=1\r"; 
// AT+CMGF for selecting Text Mode
unsigned char CtrlZ=0x1A;                   
// CTRL+Z for sedning SMS after the message has been entered
unsigned char Command_CMGS[]="AT+CMGS=\"+9xxxxxxxxx\"\r"; 
// recepient mobile number
unsigned char Command_AT[]="AT\r";
unsigned char msg02[]="Hello!";

unsigned char buf[10]={0};

void send(void)interrupt 1
{
time_overflow_count=time_overflow_count+1;
if (time_overflow_count==5){
if(value==x){

sprintf((char*)buf, "R %lu", value);

time_overflow_count=0;

initialize_GSM_modem();
value=0;
}
}
TR0=1;
}

void input_counting(void) interrupt 2
{
TR0=0;
TL0=0x00;
TH0=0x00;

value=value+1;
TR0=1;

}

void main (void) {

TMOD = 0x21;
TH1 = 0xFD;
TL0=0x55;
TH0=0x55;
SCON = 0x50;
TR1=1;
EX1=1;///Enable external intrrupt 1
EA=1;
IE1=1;
IT1=1;
PX1=1;
ET0=1;

TI=1;
while(1)
{
x=value;
}
}

void delay(void){
unsigned int i;
for(i=0;i<50;i++);
}

 void delay2(void){
unsigned long i;
for(i=0;i<15000;i++);
}

 void initialize_GSM_modem(void)
 {
 delay2();
puts(Command_CMGS);
delay2();
puts((char *)buf);
delay2();

while(!TI); TI = 0;SBUF = 0x1A;
 }

* Actualizado : *Así que usando esto estoy tratando de conseguir una interrupción del temporizador que comprueba cuando no hay pulsos durante algún intervalo de tiempo entonces asume que el flujo del medidor está completo y envía el mensaje.

Pero hay un error: no sé por qué pero nuestro programa sigue enviando mensajes continuos durante un número de veces incluso si no arranco el contador de agua. Si pongo en marcha el contador de agua, envía el valor total en la parada y si no lo hago, sigue enviando 0 a intervalos regulares

Lo que quiero es que espere a que fluya el agua (o a que se inicie la interrupción) y luego compruebe el último valor y lo envíe una sola vez.

La próxima vez que inicie el medidor, debería esperar y enviar el valor de nuevo, pero no debería seguir enviando 0s a intervalos regulares.

ACTUALIZACIÓN : He actualizado el código y su trabajo bien, pero su no funciona como yo deseo

Por favor, sugiera

Gracias

2voto

RelaXNow Puntos 1164

Parece que tu fallo arquitectónico subyacente es que tienes la recepción de pulsos acoplada al envío de la información de caudal o agua acumulada. Además, asegúrate de que este contador de agua ya produce pulsos digitales limpios, o de que desbaratas la señal en caso de que sea sólo de un interruptor mecánico.

En el caso más general de tener que desbaratar los pulsos de agua, no interrumpir en absoluto los pulsos. Interrumpa regularmente desde un temporizador. Este debe ser un mínimo de 10 veces más rápido que los pulsos en el caudal máximo. La rutina de interrupción requerirá un número mínimo de estados altos o bajos consecutivos antes de considerar que la señal desbordada ha cambiado al nuevo estado. Una vez que esto ocurre, incrementa un contador. Los microcontroladores son mucho más rápidos que los contadores de agua, especialmente los mecánicos, por lo que interrumpir lo suficientemente rápido no debería ser un problema. Normalmente una interrupción de 1 ms es suficiente para esto, y luego puedes usarla para otros tiempos del sistema.

Ahora puede enviar periódicamente el valor del contador o cualquier delta acumulado de forma ansíncrona. Para evitar la contención sobre el contador con la rutina de interrupción, el contador que la rutina de interrupción incrementa puede ser un solo byte. El código en primer plano mantiene su propia copia del último valor conocido de ese byte. Periódicamente lee el contador de la rutina de interrupción, lo compara con el último valor conocido, procesa los nuevos ticks que representa la diferencia, y luego actualiza el último valor conocido. Mientras la rutina de primer plano haga esto con la suficiente frecuencia como para que el contador de un solo byte no pueda envolverse entre las muestras, no se perderán datos.

El código de primer plano puede entonces decidir cuándo enviar la información. Esto puede basarse en un tic del temporizador y/o cuando haya nueva información que enviar.

0voto

tenfour Puntos 118

Bien, aquí hay una buena:

Configura un temporizador para interrumpir cada, digamos, 10 segundos si puedes. Cuando inicies tu programa, pon en marcha el temporizador.

Cada vez que entre en la función input_counting, detenga el temporizador y borre su cuenta de nuevo a 0 (o al valor del periodo si interrumpe cuando llega a cero - si cuenta hacia atrás es decir). Luego, justo antes de salir de la interrupción, vuelve a activar el temporizador.

El tiempo siempre está contando, pero cada vez que recibe un pulso y su interrupción se ejecuta reinicia el temporizador. El temporizador sólo generará una interrupción cuando no haya pulsos durante 10s (o lo que sea que establezcas el período del temporizador).

Entonces, en el manejador de interrupciones para el temporizador, sólo transmite el valor de nuevo y luego desactiva el temporizador. Eso debería servir.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X