¿Cómo hacer que el código se ejecute solo en caso de interrupción?

0

Tengo el siguiente código, que se supone que cuenta el número de interrupciones en el pin P3.2 (interrupción externa) y lo muestra en UART. Pero este código está haciendo exactamente lo contrario, es decir, se está ejecutando cuando no se produce la interrupción (la cuenta se incrementa cuando no hay interrupción y la cuenta se detiene cuando hay una interrupción). ¿Algún consejo al respecto sobre dónde me voy mal? Estoy usando el microcontrolador P89LV52RD2. Gracias de antemano!

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

/* function prototypes */
void delay(unsigned int ms);
void putc1( chr);
void windspeed_read( void);
void initialize(void);
void record_wind(unsigned char c);
void puts1(char* p);
void send_data();


// global variables declared
unsigned char buf[1]={0},*ptr;
int c=0,i=0; 



/* delay function to create a delay of 1 sec */
void delay(const unsigned int ms)
{
 unsigned int x;
 unsigned int y;
 for (x = 0; x < ms; x++)
 {
 for (y = 0; y <= 113; y++)
 ;
 }
}



void puts1(char* p)
{
 char *temp = p;          /*temp pointer so that the actual pointer is not displaced */
 while(*temp != 0x00)
 {
  putc1(*temp);  
  temp++;
 } 
}



/* function to detect the wind speed */
void windspeed_read( void ) interrupt 0
{
EA=0;
c = c+1;
sprintf(buf,"%d",c);
EA=1;
}



/*init the TIMER and etc*/
void initialize()
{
 SCON  = 0x50;   /*SCON: mode 1, 8-bit UART, enable receive      */ 
 TMOD |= 0x20;   /*TMOD: timer 1, mode 2, 8-bit                  */
 TH1   = 0xFD;   /*TH1:  for 9600 baud                           */
 TR1   = 1;      /*TR1:  timer 1 run                             */ 
}



/* to print the character in UART and serial window*/
void putc1(chr)
{
    initialize();
  SBUF = chr;
  while(TI==0);            /*Wait until the character is completely sent */
  TI=0;                   /*Reset the flag */
}



/* main function */
void main()
{
initialize();
IE = 0x81;
EX0 = 1;
while(1)
{
send_data();
delay(100000);
}
}

void send_data()
{

sprintf(buf,"%d",c);
ptr = buf;
P2 = buf[0];
puts1(ptr);
}

Aquí está el enlace para la hoja de datos del microcontrolador Estoy utilizando.

    
pregunta d-coder

2 respuestas

1

Bien. Los pines de interrupción están activos bajo. Entonces, cuando el pin P3.2 (~ INT0) esté bajo, habrá una interrupción. Ha asumido lo contrario y está tratando de medir una señal de entrada alta activa. Sus opciones son:

  • invertir la señal
  • convertir a flanco descendente activado (lo que le dará el conteo correcto aunque en el borde incorrecto, lo que para la medición de la velocidad del viento es correcto)

Si establece el bit 0 de registro "TCON" ("IT0"), se activará en el flanco descendente. Vea la página 29. Eso también dice:

  

(Bit 1) Interrumpir 0 indicador de borde. Establecido por hardware cuando la interrupción externa 0   Se detecta borde / nivel bajo. Despejado por hardware cuando la interrupción   Se procesa, o por software.

que suena parece que no es necesario que elimines las interrupciones de forma activa, por lo que la respuesta de Dave Tweed puede no aplicarse.

    
respondido por el pjc50
0

En general, en el 8051, una fuente de interrupción establece un indicador de interrupción, y el manejador de esa interrupción debe borrar explícitamente ese indicador antes de regresar, de lo contrario la interrupción seguirá ocurriendo. Parece que no está borrando ninguna marca en su ISR ( windspeed_read() ).

Tampoco veo ningún lugar donde esté configurando el hardware que generará la interrupción en primer lugar.

    
respondido por el Dave Tweed

Lea otras preguntas en las etiquetas