This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Using the External Interrupt 1

Hi there, I am trying to get a signal to the P89LPC932 Micro Controller by using the External interrupt 1 (P1.4). I never tried this before and I am also a beginner programming. Can anyone help me figuring out why this program does not work. The interrupt is supposed to be edge triggered and every time an interrupt occurs a counter (NPulses) is incremented til it gets to 1000 pulses. then it goes back to zero. I think my problem is configuring the timers registers, but I am not too sure.

Here is the code.
Thank you,

============================================
#include <Reg932.h>
#include <stdio.h>

void init(void);
void brkrst_init(void);
void Pulses_recieved (void);
unsigned long NPulses; //amount of pulses received
unsigned int Glass;
void ToggleC1Input (void);
sbit Pulse = P1^4;
int Glassid, count;

void Main(void)
{
P2 = 0x00;
NPulses = 0;
Glass = 10;
Glassid = 0;
count = 0;
init();
brkrst_init();
Pulses_recieved();
}

void init(void)
{
P1M1 = 0xFF; // Input only
P1M2 = 0x00;
P2M1 = 0x00; // push pull output
P2M2 = 0xFF;
ES = 1; EA = 1;
}

void brkrst_init(void) // This function allows ISP entry through the UART break detect
{
AUXR1 |= 0x40; // enable reset on break detect, pg. 102
SCON = 0x50; // select the BRG as UART baud rate source, pg. 60
SSTAT = 0x00;
//TCON = 0x04;
BRGR0 = 0x70; // 9600 BAUD at 11.0592 MHz. Hex 0470= 1136 decimal
BRGR1 = 0x04;
BRGCON = 0x03; // enable BRG, pg. 59
}

void UART(void) interrupt 4
{
RI = 0;
}

void Pulses_recieved(void)
{
while(1)
{
TCON = 0x40;
IEN0 = 0x04;
EA = EA | 1;
}
}

void ExtPulses (void) interrupt 2
{
NPulses++;
if (NPulses == 1000)
{
NPulses = 0;
Glassid++;
P2 = Glassid;
}
}
=============================================

Parents
  • Hmm, seems I miss something or ...?

    1. to configure INT1 interrupt to falling edge you should set IT1 bit of TCON then set EX1 and EA of IEN0.
    You do TCON = 0x40; <- it runs timer 1 as well as configured INT1 to low level triggered interrupt, that's wrong because your INT1 ISR does not support such mode of interrupt. You should:
    - either configure TCON for falling edge detector (by set bit IT1)
    - or expand your ISR with code for waiting till low level signal has been gone from pin P1.4 and then clear bit IE1 manualy -- you know, this bit is cleared with hardware only if IT1 set (for falling edge mode). Otherwise you will go to ISR again and again (dead interrupt loop).

    2. Same task may be done with timer 0 or 1 configured as counter of external events (on T0 or T1 pin). Read more about C/T bit of TMOD register. This way may be more useful - you will get only one interrupt at time when counter has been done.

    Good days!

Reply
  • Hmm, seems I miss something or ...?

    1. to configure INT1 interrupt to falling edge you should set IT1 bit of TCON then set EX1 and EA of IEN0.
    You do TCON = 0x40; <- it runs timer 1 as well as configured INT1 to low level triggered interrupt, that's wrong because your INT1 ISR does not support such mode of interrupt. You should:
    - either configure TCON for falling edge detector (by set bit IT1)
    - or expand your ISR with code for waiting till low level signal has been gone from pin P1.4 and then clear bit IE1 manualy -- you know, this bit is cleared with hardware only if IT1 set (for falling edge mode). Otherwise you will go to ISR again and again (dead interrupt loop).

    2. Same task may be done with timer 0 or 1 configured as counter of external events (on T0 or T1 pin). Read more about C/T bit of TMOD register. This way may be more useful - you will get only one interrupt at time when counter has been done.

    Good days!

Children
  • Hi there, Thank you very much for your help. I thought of using the counter as pulse detector through pin P0.7. I even wrote code for it. But there is something I am not too sure about. How can I keep track of the register increments I guess is (TL1). I think every time it increments is because a pulse was detected. I need that count. I set up the counter in mode 2, which means a value "0" in TH1 will be loaded into TL1 every time it overflows. Hence, every time TL1 gets to 250 counts, this value will be stored into a variable until it gets 1000. TL1 will be reset to zero after it gets to 250 counts. Does this sound right to you? There will be no interrupt service routine. Please help me. I have spent two weeks on this and I need help.
    Thank you!

  • Hi,
    I do not see a problem with using the timer/counter1 with T1 pin as pulse input.
    What you should do:
    1. Configure Timer/counter1 as counter of events on T1 pin:
    - clear TR1 (stop timer/counter);
    - set C/T bit of timer/counter1 (select as counter);
    - clear GATE bit of timer/counter1 (we do not need with INT1 pin control);
    2. Configure timer/counter1 mode:
    - select, for example, 16-bit mode by clear M1 and set M0 bits of timer/counter1;
    3. Prepare for counting 1000 pulses:
    - load TH1 with high byte of 65536-1000;
    - load TL1 with low byte of 65536-1000;
    4. Run it and wait till counting will be done:
    - clear TF1;
    - set TR1.
    Here you may configure and enable interrupt of timer/counter1 or disable it and just wait in main loop till TF1 will be set.

    In short, here is the ASM example (the code will not affect on other hardware):

    	ANL	TCON,#00111111b		; clear TR1 and TF1 bits
    	ANL	TMOD,#00001111b		; clear GATE and M1 bits
    	ORL	TMOD,#01010000b		; set C/T and M0 bits
    	MOV	TH1,#HIGH(65536-1000)
    	MOV	TL1,#LOW(65536-1000)
    	SETB	TR1
    wait:
    	JNB TF1,wait
    
    I hope you will be able to translate that code to C-language (=
    Good days!

  • Dear Oleg Sergeev:
    Thank you very much for your help. It really helps me. I wanted to let you know I tried your advice about using the counter in a 16 bit mode. But it does not work...I know I am missing something. could you take a look at the code? I also wanted to show on Port two every time 1000 pulses have been counted.
    I really appreciate your time and help. I need to get this done. Can you explain the value loaded onto TH1 and TL1.
    Thank you.

    =============================================
    #include <Reg932.h>
    #include <stdio.h>

    void init(void);
    void brkrst_init(void);
    void Pulses_recieved (void);
    unsigned long NPulses; //amount of pulses received
    unsigned int Glass;
    void ExtPulses (void);
    sbit Pulse = P1^4; //port to recieve pulses
    int Glassid, count;


    void Main(void)
    {
    P2 = 0x00;
    NPulses = 0;
    Glass = 10;
    Glassid= 0;
    count = 0;
    init();
    brkrst_init();
    Pulses_recieved();
    ExtPulses ();
    }

    void init(void)
    {
    P1M1 = 0xFF; // Input only
    P1M2 = 0x00;
    P2M1 = 0x00; // push pull output
    P2M2 = 0xFF;
    ES = 1; // enable UART interrupt
    EA = 1;
    }

    void brkrst_init(void) // This function allows ISP entry through the UART break detect
    {
    AUXR1 |= 0x40; // enable reset on break detect, pg. 102
    SCON = 0x50; // select the BRG as UART baud rate source, pg. 60
    SSTAT = 0x00;
    BRGR0 = 0x70; // 9600 BAUD at 11.0592 MHz. Hex 0470= 1136 decimal
    BRGR1 = 0x04;
    BRGCON = 0x03; // enable BRG, pg. 59
    }

    void UART(void) interrupt 4 //Interrupt number for serial port
    {
    RI = 0; // clear receive interrupt flag
    }

    void Pulses_recieved(void)
    {

    TMOD = 0x50;
    TAMOD = 0x00;
    TR1 = 0;
    TH1 = (65536-1000);
    TL1 = (65536-1000);
    }

    void ExtPulses (void)
    {
    TR1 = 1;
    while(1)
    if (TF1 == 1); {
    TF1 = 0;
    Glassid++;
    P2 = Glassid;
    }
    }
    =============================================

  • Hi,
    Can you explain the value loaded onto TH1 and TL1
    Well, timer/counter1 in mode 1 counts from 0x00 upto 0xFFFF then it sets bit TF1 and starts counting from 0x00 again.
    So, for example, if you wish to wait one step before TF1 will be set then you should load TH1 and TL1 with 0xFFFF, in general you load value #(0x10000 - wait_cycles).
    Now about your code.
    1) sbit Pulse = P1^4; //port to recieve pulses --- sorry? we discuss about receiving pulses via timer/counter1 so it should be P0.7. Do you connect input line correctly on assembly board? (=
    2) TH1 = (65536-1000); TL1 = (65536-1000);
    should be
    TH1 = (65536-1000)/256; high byte
    TL1 = (65536-1000)%256; low byte
    3) You should re-initialize TH1/TL1 values after TF1 has been set.
    Maybe:

    void Pulses_recieved(void)
    {
    TR1 = 0;
    TMOD = 0x50;
    TAMOD = 0x00;
    TH1 = (65536-1000)/256;
    TL1 = (65536-1000)%256;
    TF1 = 0;
    TR1 = 1;
    }
    
    void ExtPulses (void)
    {
    while(1)
    {
    // wait till 1000 pulses will be counted
    while (TF1 == 0) ;
    // then re-initialize counter1
    Pulses_recieved();
    Glassid++;
    P2 = Glassid;
    }
    }
    4) I hope for that input pulses come to pin T1 (P0.7) from IC (or from button via 74279, 7474 etc).
    5) I do not familar with LPC932; anyway I trust on you that your program does not use (and even does not try to use) timer 1 as Baud rate generator.

    Good days!

  • Dear Oleg Sergeev:
    You are great! I made the changes you told me, plus some others I thought would be helpful and it worked. The baud rate generation uses Timer1, so I changed the counter to counter0. It works fantastic. There is one more question. Have ever worked with smart cards...I mean interfacing them to a microcontroller like the LPC932?
    Thank you very much!!!

  • Hi,
    Sorry, cannot help you with it. IMHO, I preffer to use a special chip for such task, for example, Atmel AT89C5122: http://www.atmel.com/dyn/resources/prod_documents/doc4202.pdf

    Good days!

  • Oleg Sergeev, thank you very much for your help. Unfortunately, I have to use the same chip for the card reader interface. I will take a look at the web site you gave me in more detail though.

  • Oleg Sergeev, as I stated before, the micro controller is working fine by receiving the pulses. Every time it counts 1000 pulses it increases a variable and its value is displayed on port 2. I need to write this new value to memory and re-write it once it changes. I have that (read/write) function working as well by itself, but when I put it together with the "receiving pulses" function, it does not work. I think it's the interrupts that are not well configured. Do you have any ideas?

  • Oleg Sergeev, I need to keep track of the pulses being recieved. For example 500, 750. Is there anyway to do that. maybe store them in a variable?
    Thank you!

  • How are you Oleg Sergeev. I wanted to thank you for your help on this part of the project I'm implementing. However, I need to put the micro controller in Power Down Mode if it is not receiving any pulses at the T0 pin (P1^2). Do you have any ideas on how can this be done. I'm thinking of putting a waiting period and if no pulses are received then go to sleep...how much time should I wait...how do I calculate that.
    Thank you again

  • Hi,
    What is the problem to put MCU into Power Down mode? The main problem I see is that after PD mode will be activated your MCU stays at this mode till external reset generated (some MCUs allow to wake up from other inputs; unfortunately - not via T0/T1 pins). Are you sure that you need to stop all the program once really? Maybe it should be Idle mode?
    Anyway if so then I dunno about waiting time calculation because we need to know about frequence of input pulses at least.
    Btw, sorry about silence. You know, the main usage of the forum is the compiler/linker/debuger problems, but the program issues itself --- I recommend you to visit http://www.8052.com

    good days!

  • Dear:
    Oleg Sergeev
    The "external interrupt" program you helped on (receiving pulses through timer 0)is working fine. I have added more details (tasks) to it and now it looks like its counting more pulses than the expected. This is a multitasking problem (I think) could you give me an idea what could be wrong?
    Thank you