0
\$\begingroup\$

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.

\$\endgroup\$
5
  • \$\begingroup\$ Have you got a level triggered interrupt on the wrong level? \$\endgroup\$ – pjc50 Dec 8 '14 at 10:08
  • \$\begingroup\$ I don't know. I'm new to this field so could you help ? \$\endgroup\$ – d-coder Dec 8 '14 at 10:26
  • \$\begingroup\$ OK: look up "level triggered" versus "edge triggered" and understand that. Then look up the microcontroller data sheet and your program and determine which you have set in the code. Please also post a link to the data sheet here. \$\endgroup\$ – pjc50 Dec 8 '14 at 10:49
  • \$\begingroup\$ Actually the interrupts are level triggered.See the link for the data sheets in my edits. \$\endgroup\$ – d-coder Dec 8 '14 at 12:02
  • \$\begingroup\$ Level triggered interrupts will continuously interrupt while the level is active on some MCUs. \$\endgroup\$ – geometrikal Dec 8 '14 at 12:40
1
\$\begingroup\$

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.

\$\endgroup\$
6
  • \$\begingroup\$ How do I convert to falling edge ? \$\endgroup\$ – d-coder Dec 8 '14 at 12:57
  • \$\begingroup\$ Set "TCON" register bit 0 ("IT0") as above. \$\endgroup\$ – pjc50 Dec 8 '14 at 13:43
  • \$\begingroup\$ It's not working! When I connect my sensor to measure the wind speed then it keeps counting when no interrupt occurs and when there is an interrupt then it stops counting. My sensor is nothing but a reed switch which makes a contact giving the voltage \$\endgroup\$ – d-coder Dec 9 '14 at 5:25
  • \$\begingroup\$ Is your sensor active low or active high? \$\endgroup\$ – pjc50 Dec 9 '14 at 7:36
  • \$\begingroup\$ it's active high \$\endgroup\$ – d-coder Dec 9 '14 at 8:35
0
\$\begingroup\$

In general on the 8051, an interrupt source sets an interrupt flag, and the handler for that interrupt must explicitly clear that flag before returning, or else the interrupt will keep happening. You do not seem to be clearing any flags in your ISR (windspeed_read()).

I also do not see any place where you are configuring the hardware that will generate the interrupt in the first place.

\$\endgroup\$
2
  • \$\begingroup\$ Sorry but I couldn't get most of the part you said. \$\endgroup\$ – d-coder Dec 9 '14 at 8:36
  • \$\begingroup\$ In that case, I don't think I can help you. You don't seem to have the background you need in order to be programming the 8051 at this level. Perhaps you would be better off working in the Arduino environment, which is expressly designed to hide all of the low-level implementation details and allow you to move forward with your application development. There is also an Arduino stack exchange site where you can get help using it. \$\endgroup\$ – Dave Tweed Dec 9 '14 at 12:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.