Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Timer Interrupt not interrupted

Status
Not open for further replies.

RyanHan

Junior Member level 3
Joined
Apr 24, 2012
Messages
26
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,514
Dear Expert,

I had write a keil C code for my DS89C450 microcontroller. I had 2 interrupt. One of which is the external interrupt 3 tie to a hardware switch. And Timer interrupt 0. I am using Keil C to program this 2 interrupt. My problem is that once the hardware interrupt triggered by the switch, the timer interrupt stop functioning. I had did some troubeshooting and found that.

The purpose of my code is to wait for the switch to be pressed and interrupt the uC. After which, at regular interval, by timer interrupt, I will read the value of Port 0 and put into a buffer. Once a certain amount of byte was written, I will stop the timer interrupt and exist the external interrupt loop. Below is my program. Is it a good way to put a while loop in to external interrupt? Cause my problem now is that inside the external interrupt loop, my timer interrupt cannot work any more. I had check and both are of the same interrupt priority. Can any expert enlighten me as to what had went wrong with this code that the timer interrupt doesnt work once the external interrupt 3 trigger. Thanks a lot



Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <DS89C4xx.h>
 
unsigned int bytecounter, Read_data;
 
void Int3(void) interrupt 9
    {
        EIE = 0x00;
                            TH0 = 0xE6;
        TL0 = 0xFF;
        TR0 = 1;
        while(!Read_data);
        TR0 = 0;
        EIE = 0x02;
    }
 
void Timer0Interrupt(void) interrupt 1
    {
        unsigned char buffer;
                  .
                            .
                            .
                            .
                            .
        if (bytecounter > 10) Read_data = 1;
    }
    }
 
void main (void)
{
        IE = 0x82;
        EIE = 0x02;
        TMOD = 0x21;
        TH1 = 0xFD;
        SCON0 = 0x50;                 //for serial port communication
        TR1 = 1;
        
        while(1)
        {
            if (Read_data)
                {
                    .
                    .
                                                                      .
                                                                      .
                                                            Read_Data = 0;  
                }
        }
}

 
Last edited by a moderator:

Basically you can not wait Inside the interrupt... your code will wait for ever when the button is pressed
 

Hi mgate,

Therefore, what should be a better way of doing this? Thanks a lot
 

I can help you... But I am not familiar with the registers.. can you comment the code?

---------- Post added at 03:10 ---------- Previous post was at 02:54 ----------

check page 91 -- interrupt section
https://www.keil.com/dd/docs/datashts/dallas/ds89c420_ug.pdf

---------- Post added at 03:27 ---------- Previous post was at 03:10 ----------

Basically you can not wait Inside the interrupt... your code will wait for ever when the button is pressed

I was wrong... in this uC you can as long as you correctly manage interrupts
 

It says that Timer 0 interrupt had higher prioty then the External interrupt 3 unless we set the Priority control however, I leave all at default which means timer 0 should interrupt external interrupt 3. But dont know why it cant work
 

RyanHan,

I think the problem might be on you have forgot to clear Interrupt 3 flag, jamming the code to continuously run interrupt 3 ISR

check your code, I've added the clear IE3 flag code on the ISR (line 17).. ... check page 23 of the above manual..

I hope it solves..


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <DS89C4xx.h>
 
unsigned int bytecounter, Read_data;
 
void Int3(void) interrupt 9
{
    EIE = 0x00; // External Interrupts disable - Disable interrupt requests generated by the INT3 pin.
    TH0 = 0xE6; // Set timer0 high byte
    TL0 = 0xFF; // Set timer0 low byte
    TR0 = 1;    // start timer0 increment count
    
    while(!Read_data); // wait for read_data flag high
    
    TR0 = 0;    // stop timer0 increment count
    
    // you forgot to clear external interrupt3 flag 
    EXIF &= ~0x20;
    
    EIE = 0x02; // External Interrupt 3 Enable - Enable interrupt requests generated by the INT3 pin.
}
 
void Timer0Interrupt(void) interrupt 1
{
    unsigned char buffer;
    /*.
    .
    .
    .
    .*/
    if (bytecounter > 10) Read_data = 1;  // set read_data flag
}
 
void main (void)
{
    IE = 0x82;  // Timer 0 interrupts - Enable all interrupt requests generated by the TF0 flag (TCON.5)
                // Global Interrupt Enable
    
    EIE = 0x02; // External Interrupt 3 Enable - Enable interrupt requests generated by the INT3 pin.
    
    TMOD = 0x21; // Timer 1 -> Mode 2: 8 bits with autoreload; Timer 0 -> Mode 1: 16 bits
    
    TH1 = 0xFD;  // Set most significant byte of  timer 1
    
    SCON0 = 0x50; //for serial port communication
    
    TR1 = 1; // Start timer1 increment count
 
while(1)
{
    if (Read_data)
    {
        /*.
        .
        .
        .*/
        Read_Data = 0; // clear read_data flag
        }
    }
}



---------- Post added at 04:34 ---------- Previous post was at 04:14 ----------

I would also suggest you to clear ext interrupt flags before you enable Global Interrupts...

I suggest you remove these lines from External interrupt 3 ISR

Code:
    while(!Read_data); // wait for read_data flag high
    
    TR0 = 0;    // stop timer0 increment count
    
    // you forgot to clear external interrupt3 flag 
    EXIF &= ~0x20;
    
    EIE = 0x02; // External Interrupt 3 Enable - Enable interrupt requests generated by the INT3 pin.

and put this coded in the timer0 interrupt ISR

Code:
void Timer0Interrupt(void) interrupt 1
{
    unsigned char buffer;
    /*.
    .
    .
    .
    .*/
    if (bytecounter > 10)
    { 
        Read_data = 1;  // set read_data flag
       
[B]        TR0 = 0;    // stop timer0 increment count
    
        EXIF &= ~0x20;
    
        EIE = 0x02; // External Interrupt 3 Enable - Enable interrupt requests generated by the INT3 pin.[/B]

    }
}

this way you don't need any loop inside the ISR...
 
Last edited:

Hi mgate, thanks for your feedback. I remove the while loop inside the ISR and everything work now. I check on the Timer 0 and it did set the bytecounter and I am sure it did run the Read_data = 1; line. However, after the Timer 0 interrupt stop, my main program didnt run and it stop before the while(1) loop and didnt continue. Therefore I cannot check my data inside buffer in the main rountine. What could have went wrong here? After the Timer 0 interrupt stop, it should be running the main program right? But the main program didnt loop after the Timer 0 interrupt finish. Before the interrupt, the while(1) loop inside the main is working. Very strange.

Code:
void Timer0Interrupt(void) interrupt 1
{
    unsigned char buffer;
    .
    .
    .
    .
    .
    if (bytecounter > 10)
    { 
        Read_data = 1;  // set read_data flag      
        TR0 = 0;    // stop timer0 increment count 
        EXIF &= ~0x20;
        EIE = 0x02; // External Interrupt 3 Enable - Enable interrupt requests generated by the INT3 pin.
    }
}

void main (void)
{
		IE = 0x82;
		EIE = 0x02;
		TMOD = 0x21;
		TH1 = 0xFD;
		TH0 = 0x01;
		TL0 = 0xFB;
		SCON0 = 0x50;
		TR1 = 1;

		while(1) 
		{
			if (Read_data)
			{
				SerTx('Y');               //just to check that it went inside the loop or not
				Read_data = 0;
			}
		}
		
}
 

Try cleaning interrupt flags before activate interrupts, because it is possible that external interrupt be lunch before you click the button, at the begging of main(), when you enable the interrupts
Code:
void main (void)
{
[B]            EXIF = 0;[/B]
		IE = 0x82;
		EIE = 0x02;
		TMOD = 0x21;

, anyway this doesn't seem to have to do with the current problem..

try declaring read_data as volatile to avoid caching... might be it
Code:
volatile unsigned int Read_data;
 
Last edited:

Hi mgate,

Thanks a lot for your Spontaneous respond. I had tried your method but it doesnt work also. I put a watchpoint and found that the uC stop just before the while loop. I believe the Read_data do really become 1 but the code in the main after the while loop didnt execute. Pls help. Thanks a lot
 

I was with hope that the Read_data was being cached , and that the volatile declaration would solve it...

It's probably better if you post a recent and updated version of your code so that others can have a look at it... I also think it would be easier if you post the full code, so that we can see other possible interactions ...

---------- Post added at 11:42 ---------- Previous post was at 11:35 ----------

Also, try running the code without use timer1

Code:
void main (void)
{
		IE = 0x82;
		EIE = 0x02;
		TMOD = 0x21;
		TH1 = 0xFD;
		TH0 = 0x01;
		TL0 = 0xFB;
		SCON0 = 0x50;
[B]		TR1 = 0;[/B]
 
Last edited by a moderator:

Hi mgate, i cant disable the timer 1 as it is my serial port buad rate counter. Without it, I cant send string out. Therefore I also dont know my program is working or not
 

You can use led blinking patterns to check if the codes zones are being reached...
Hi mgate, i cant disable the timer 1 as it is my serial port buad rate counter. Without it, I cant send string out. Therefore I also dont know my program is working or not
 
Hi mgate,

I tried to remove the timer for serial port and the programs works fine now. However, still dont know the reason behind it. BTW, I face another problem with my programming but I think I will open another post for that problem and closed this post. Thanks a lot
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top