How to make the code run only on interrupt

8051interrupts

I have the following code which is supposed to count the number of interrupts on pin P3.2 (external interrupt) and display it on UART. But this code is doing exactly opposite of it i.e. it's running when the interrupt doesn't occur (count gets incremented when there is no interrupt and count stops when there is an interrupt). Any advice on it on where I'm going wrong ? I'm using P89LV52RD2 micro controller. Thanks in advance!

#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);
}

Here is the link for the data sheet of microcontroller I'm using.

Best Answer

Right. The interrupt pins are active low. So whenever the P3.2 pin (~INT0) is low, there will be an interrupt. You have assumed the opposite and are trying to measure an active high input signal. Your options are:

  • invert the signal
  • convert to falling edge triggered (which will give you the correct count although on the wrong edge, which for wind speed measurement is OK)

If you set "TCON" register bit 0 ("IT0") it should trigger on the falling edge. See page 29. That also says:

(Bit 1) Interrupt 0 Edge flag. Set by hardware when external interrupt 0 edge/low level is detected. Cleared by hardware when the interrupt is processed, or by software.

which sounds like you don't need to actively clear interrupts, so Dave Tweed's answer may not apply.