# 8051 Interrupt problem

Status
Not open for further replies.

#### umery2k75

Hi,
I am using AES-51 Computer Embedded Controller from ADVANCED EDUCATIONAL SYSTEMS for designing a project. It is based on 80C32 microcontroller.

Programs using interrupts are giving me unusual responses.
I made a test program which would generate a 10 KHz square wave on P1.4, now every time I run this program I get the different frequency on P1.4.

Test Program:
=========

org 400BH
TOISR:
cpl p1.4
reti

org 7000h
main:
mov tmod,#02h
mov th0,#-50
setb tr0
mov ie,#82h
sjmp $end I’m doing this as: =========== • I attach RS-232 cable with a computer and attach the DC adaptor of controller in a power socket. • I run the program and LED on P1.4 glows. • I remove the DC adaptor of controller from the power socket for 5 sec or to 10 sec to ensure nothing remains in the RAM content. • I plug again the DC adaptor right after 5 sec and download the program from my computer to this controller and run this program again. I see LED on P1.4 to glow. • I check the frequency on P1.4. I have checked the frequency through 2 different multimeters and 1 oscilloscope and all measurements were the same, which proved that there was nothing wrong with instruments. In computer: ======== I have this program for downloading my hex code into my controller.This program came along with this board on floppy disk,To do this I have to write RX and then press enter<CR> 1st step ===== 2nd step ===== Now I press ALT+S to type the hex file name and then press ENTER. 3rd step ===== After pressing Enter I get this 4th step ===== I now write "call 7000h" and press enter to execute the program on my controller. 5th step ===== Now the LED on port 1.4 is blinking at a very fast rate, I can detect it's blinking by my eyes. This is the observation chart and number of times I repeat the above procedure. No____Power Supply time (Turn off-Turn On)__Frequency Obtained on P1.4 1________N/A______56.2848 Hz 2________5s_______3.20 KHz 3________5s_______9.22 KHz 4________5s_______< 10 Hz 5________5s_______56.2848 Hz 6________5s_______9.22 KHz 7________5s_______56.2848 Hz 8________5s_______56.2848 Hz 9________5s_______9.22 KHz 10_______5s_______< 10 Hz 11_______10s______56.2848 Hz 12_______10s______56.2848 Hz 13_______10s______< 10 Hz 14_______10s______56.2848 Hz 15_______10s______9.22 kHz 16_______10s______< 10 Hz 17_______10s______56.2848 Hz 18_______10s______9.22 KHz I turned ON and OFF my controller by removing and inserting the DC power adaptor into the power socket in this way, so as to remove content on RAM, just in case if the RESET button on controller board doesn't wash the RAM content. TURN OFF ====== TURN ON ====== Added after 4 minutes: NOTE: ==== Whenever a timer 0 interrupt is generated, the controller will jump to 000BH to read the code, this 000BH code resides in ROM, from there it jumps to 400BH to read the code, which resides in RAM address, so that a programmer can easily modify the code without having the need to program the UVROM one after the another during development process. Program in this board are run on RAM. In this I have 256 KB of RAM, in which I’m starting my code at 7000h and will also run this program not from 0000h, but from 7000h. Added after 5 hours 50 minutes: The contact information given on this controller manual was: Copyright 1998, Advanced Educational Systems 575 Anton Blvd. Suite 300, Costa Mesa, California 92626 USA Tel: (714) 550-8094 Fax: (714) 550-9941 Today, I called on this telephone number, and a lady answered to me as no such company exists on this telephone number today(2007).This number was taken by some other business company. I think the company has shut down and there's no help a customer can get from them #### VVV ##### Advanced Member level 5 Well, it's been a long time since I've used the 8051, but it may be that when you return from the interrupt you actually return to the address following the SJMP$ instruction. That means the micro executes garbage when it returns from the first interrupt. I may be wrong, confusing this with another micro, but give it a try.

Do it this way:

Code:
WAIT:  SJMP $SJMP WAIT So the interrupt occurs during the SJMP$ and the program counter contains the address of the next instruction, which is what it saves on the stack, so when you return you execute the second jump, which takes you back to the waiting loop. Of course, this assumes the interrupts will not occur so fast as to get another interrupt during the second SJMP. That should not happen, because you want 10kHz, which is 100us and the SJMP takes 4us.

Besides, if memory serves me well, the interrupts are only enabled AFTER the instruction FOLLOWING the RETI. That means that the micro would not even acknowledge an interrupt during the second SJMP, even if it occured. It would only recognize it after it executes the jump back to WAIT, which is fine. (Again, I may be wrong here).

Give it a try, though. It's simple to try.

### umery2k75

Points: 2

#### mcs51mc

##### Member level 4
First of all you don't have 256KB of RAM; you have 256Kbit of RAM what is 32KB(yte) of RAM for program memory.

I can live with your explanation of timer 0 interupt, vectors to 000Bh, in EPROM there is code that jumps to 400Bh and that is the location where you wrote your TOISR. Looks good to me.

But at power up your controller start at 0000h, what jump is programmed in the EPROM at address 0000h?? 7000h?? I would expect 4000h. Why?
I think they moved all addresses 4000 locations.
Power up: 4000h
IE0: 40003h
TF0: 400Bh
IE1: 4013h and so on... ...

1) mov th0,#-50 : why -50???
2) mov ie,#82h : why writing unreadable code? better is
setb ET0 ;enable interrupt timer 0
setb EA ;enable all interrupts
setb TR0 ;start timer 0
3) org 7000h : are you sure about that address (see above)?

VVV said:
Do it this way:

Code:
WAIT:  SJMP $SJMP WAIT or even better Code: WAIT: nop nop nop jmp WAIT Pointless writing 2 jumps after another... ... ### umery2k75 Points: 2 Helpful Answer Positive Rating #### wek ##### Full Member level 4 Using the scope, what sort of waveform do you see? Is there a pullup on P1.4? JW ### umery2k75 Points: 2 Helpful Answer Positive Rating #### umery2k75 ##### Advanced Member level 1 I actually copied the original program from "THE 8051 MICROCONTROLLER", by I.SCOTT MACKENZIE and modify this program to meet my need. Original program in Book I.SCOTT MACKENZIE Example 6-1: A Square Wave Using Timer Interrupts Page # 107 Code: ;**************************************************** ;8051 INTERRUPT EXAMPLE(10-khz SQUARE WAVE) ; ORG 0 ;RESET ENTRY POINT LJMP MAIN ;JUMP ABOVE INTERRUPT VECTORS ORG 000BH ;Timer 0 INTERRUPT VECTOR TOISR: CPL P1.0 ;TOGGLE PORT BIT RETI ORG 0030H MAIN: MOV TMOD,#02H ;Timer 0,MODE 2 MOV THO,#-50 ;50us DELAY SETB TR0 ;START TIMER MOV IE,#82H ;ENABLE TIMER 0 INTERRUPT SJMP$	          ;DO NOTHING

I changed the program as mention above in my post.

CODE MEMORY:
==========

By attaching and removing the jumper(J5), I can switch it’s memory configuration.

Jumper 5 Connected-default setup:
First half of code space (address 0 to 3fffh) resides in ROM(U3)
Second half of code space (address 4000h to 7fffh) resides in RAM(U4)

Jumper 5 open:
Entire code space (address 0 to 7fffh) resides in ROM(U3)
Entire data space (address 0 to 7ffffh) resides in RAM(U4)

I’m using default method J5(connected):
For my program in which user code space is from 4000h to 7fffh and resides in RAM, that's why I started my program from location 7000h( by writing ORG 7000h)

The entire AES system code is in the ROM chip from address 0 to 41ffh. System code includes the Basic-52 system, some custom BASIC-52 commands such as those used in uploading and downloading files, the AES monitor, all self test and utility routines. In the default setup only the codes from 0 to 3FFFh in ROM are accessible.

This is how the PROM of controller looks like.

I downloaded the ROM code of my controller and I dissembled it and I studied as how the interrupts vectors are written, below is the program I found on my controller PROM.
Code:
AES51                                                                                                         PAGE 1

1    ;
2    ;  D51 V2.6 8051 Disassembly of aes51.hex
3    ;  10/23/2007 1:59
4    ;
00E0                 5            acc     equ     0E0h
0080                 6            p0      equ     80h
0090                 7            p1      equ     90h
00A0                 8            p2      equ     0A0h
00B0                 9            p3      equ     0B0h
10
11
0000                  12            org     0
13    ;
0000 6187             14    X0000:  ajmp    X0387
15    ;
0003                  16            org     3
17    ;
0003 20312D           18            jb      26h.1,X0033
0006 C000             19            push    psw
0008 024003           20            ljmp    X4003
21    ;
000B C000             22            push    psw
000D 202E10           23            jb      25h.6,X0020
0010 02400B           24            ljmp    X400b
25    ;
0013 20122B           26            jb      22h.2,X0041
0016 C000             27            push    psw
0018 024013           28            ljmp    X4013
29    ;
001B C000             30            push    psw
001D 021F78           31            ljmp    X1f78
32    ;
0020 0218FA           33    X0020:  ljmp    X18fa
34    ;
0023 C000             35            push    psw
0025 201F1C           36    X0025:  jb      23h.7,X0044
0028 024023           37            ljmp    X4023
38    ;
002B C000             39            push    psw
002D 02402B           40            ljmp    X402b
41    ;
0030 021934           42    X0030:  ljmp    X1934
43    ;
0033 202608           44    X0033:  jb      24h.6,X003e
0036 C296             45            clr     p1.6
0038 3000FD           46    X0038:  jnb     int0,X0038
003B D296             47            setb    p1.6
003D 32               48            reti
49    ;
003E 022040           50    X003e:  ljmp    X2040
51    ;
0041 D216             52    X0041:  setb    22h.6
0043 32               53            reti
54    ;
0044 022050           55    X0044:  ljmp    X2050
56    ;
0047 17               57    X0047:  dec     @r1
0048 7C12             58            mov     r4,#12h

I saw over here, that on 000BH location, the controller is jumping to 400BH.
So I put my timer 0 interrupt service routines over there.

This code is very long, I have only showed the starting memory of the PROM.

I remodify this code as below, still I'm not getting correct wave form.

Code:
org	400BH
TOISR:
cpl	p1.5
reti

org	7000h
main:
mov	tmod,#02h
mov	th0,#-50
setb	tr0
mov	ie,#82h
WAIT:  SJMP $SJMP WAIT end Added after 5 minutes: By using Oscilloscope I see the square wave on P1.4. I changed the programming parameter to P1.5, still I'm getting the same results. Code: TOISR: cpl p1.5 reti Well I'm not sure whether there's a pull up resistor on P1.4 or not.I'll check the schematic diagram. Added after 5 minutes: NO, there is no pull up resistor on P1.4 #### XNOX_Rambo ##### Advanced Member level 1 I saw over here, that on 000BH location, the controller is jumping to 400BH. Well, that depends on the state of bit 25h.6: 000D 202E10 23 jb 25h.6,X0020 If the bit is set the program goes away someplace: 0020 0218FA 33 X0020: ljmp X18fa ...and who knows what goes on there - some BASIC-52 stuff I presume... Then it returns to process your interrupt. And, as mcs51mc points out, on reset the program starts from 0000h - and there we find: 0000 6187 14 X0000: ajmp X0387 I'd guess your program is not the only thing running in the chip... ### umery2k75 Points: 2 Helpful Answer Positive Rating #### VVV ##### Advanced Member level 5 I stand by what I said before. But I was expecting to see just an LJMP 400BH at location 000BH. I wonder what that bit means and what sets it. Can you try to clear it in your code, in the waiting loop, such that you always execute a jump to 400BH? ### umery2k75 Points: 2 Helpful Answer Positive Rating #### umery2k75 ##### Advanced Member level 1 I now had remodify my code as follows, but still I’m having different frequency responses.This still has not solve the problem. Code: org 400BH TOISR: cpl p1.4 reti org 7000h main: ; I am clearing the bit 25h.6 in the start of program to ensure it has not been set up previously by its firmware which ran before my program. ; 02eh = bit 25h.6 clr 02eh mov tmod,#02h mov th0,#-50 setb tr0 mov ie,#82h WAIT: clr 02eh SJMP WAIT end #### mcs51mc ##### Member level 4 XNOX_Rambo guess is correct, you have two program running in your µC, BASIC-52 in EPROM and you code in RAM. Since you don’t know exactly what BASIC-52 is doing, you have a small problem. All the X1234 stuff in the EPROM code are LABELS not addresses!!! So “ajmp X0387” is not jump to address 0387h but jump to label X0387: At µC reset BASIC-52 jumps to label X0387 (still in EPROM), what is located there? You can’t program anything there, so there has to be a jump somewhere in RAM, maybe to address 7000h (what you’re using as main code) but I still expect 4000h . Please let us know! At timer0 interrupt your µC vectors to address 000Bh and what do we found there: Code: push psw ;save PSW on stack jb 25h.6,X0020 ;jump if bit 25.6 set to LABEL X0020 ljmp X400b ;unconditional jump to LABEL X400b Bit 25h.6 is bit 6 of address 25h in internal RAM. That is the bit-addressable range of internal RAM. Bytes 20h to 2Fh are bit-addressable bytes, that way you have 128 bits that can be set, cleared and tested directly. Since you’re code doesn’t control that bit it’s is maybe done by BASIC-51. You can check that by searching for “setb 25h.6” or “clr 25h.6” instructions in the EPROM code. Change you’re code to Code: Wait: clr 25h.6 Jmp Wait And see what happens. About the Code: mov th0,#-50 With that number you can expect a frequency of 11.186kHz Timer0 divide the oscillator frequency by 12 to get timing pulses. Since you have a 11.0592 Xtal you have 1 pulse every 0.9216µs. For a 10kHz signal you need a timer interrupt every 50µs or 50µs / 0.9216µs = 54 pulses. You need a timer value of 255 – 54 = 201 not -50! -50 is correct for a 12MHz Xtal, but even then I prefer a reload value of 255 – 50 = 205! Everyone has it’s own way of doing things ### umery2k75 Points: 2 Helpful Answer Positive Rating #### umery2k75 ##### Advanced Member level 1 The sequence of code when timer 0 interrupt is executed, the controller jumps on location 000BH from there these are the codes I have copy extracted put them over here I have replaced the above program with this one, but still it doesn't work Code: org 400BH TOISR: cpl p1.4 reti org 7000h main: mov tmod,#02h mov th0,#-50 setb tr0 mov ie,#82h WAIT: clr 02eh ; 25h.6=02eh SJMP WAIT end When I execute the program.I get 9.22 Khz on P1.4 or P1.5(which ever I choose in program) or sometimes 56.2848Hz or <10Hz and very few times 3.20Khz. Added after 23 minutes: •I assume if the controller could give me 9.22 KHz on the same program or what ever frequency. It should always give me the same output, whenever I execute the program. The output frequency should not vary regardless the number of times I execute the SAME PROGRAM without any modification. #### mcs51mc ##### Member level 4 Why do you handle the X1234 stuff in code Code: jb 25h.6,X0020 X0020: ljmp X18fa as labels and in code Code: ljmp X400b as an address!!! All the X1234 stuff in EPROM are labels, you should look for a X400b label. And while you're searching, search also for the X0387 label (power up vector). Sligthly off topic: 1) Where did you get that board from? 2) Do yourself a favor: Dump that board and start with Atmel ISP processors and Flip software also from Atmel. Added after 43 minutes: Hi umery2k75, Just wrote this program into a controller Code: ;---------------------------------------------------------------------------------------- ;Fixed program locations ; CSEG AT RESET jmp MainProg CSEG AT TIMER0 jmp T0ISR ;---------------------------------------------------------------------------------------- ;Timer 0 ISR ; T0ISR: cpl P1.4 reti ;---------------------------------------------------------------------------------------- ;Mainprogram with endless loop ; MainProg: mov TMOD,#02h ;Setup Timer0 mov TH0,#205 setb TR0 mov ie,#82h WAIT: clr 02Eh ;Clear whatever bit sjmp WAIT END I assembled it resulting in the attached "MainProg.doc" file (originally "MainProg.lst") and downloaded into a controller. Result: nice pulstrain of 10kHz on both P1.4 & P1.5 pins. Even with -50 instead of 205, I have a 10kHz signal, but I'm using 12MHz oscillator and my old analogue scoop isn't that accurate Bottom line: Your code is 100% ok. The BASIC-52 code in the EPROM is fooling you in some way Like I already suggested, consider other, newer development tools. ### umery2k75 Points: 2 Helpful Answer Positive Rating #### umery2k75 ##### Advanced Member level 1 I have bought this developement board from U.S.A, couple of years back through mail for approximately$600 USD including all the charges.I had directly ordered this board from Advanced Educational System.This board is still brand new, I have never used this board before for developing applications.I have just used it for a very little time.

No I am going to assemble this code

This code has been perfectly assembled and assembler found no error in the code.Now I will download the code into my controller as.

I got "INVALID DATA RECIEVED", when I forget to write ORG XXXXh in my code, the starting address of my code.As I can see that the code I have downloaded into my controller does not have ORG statement.

#### mcs51mc

##### Member level 4
I didn't expect my code to work on your board because of the "BASIC-52" code in EPROM.

My code "CSEG AT RESET" is equal to ORG 0000h
My code "CSEG AT TIMER0" is equal to ORG 000Bh
you can check those addresses in the word document.
Problem is you can't access those since they are in EPROM

You have to focus on the BASIC-52 not on your code!
Are you sure of your "org 400BH" and "org 7000h " code?
Who controls the "clr 02eh ; 25h.6=02eh" bit?
You need to focus on those questions, check the manual... ...

Make a flow chart like you already make one for Timer0 for power up but please in another color than flashy blue.

Double check LABELS vs ADDRESS !!

### umery2k75

Points: 2

#### wek

##### Full Member level 4
This should have nothing to do with BASIC. It's no mystery - it's a program just as any other, only a bit more complicated. Anyway, if all the steps are the same, the behaviour should be consistent too - it might yield perhaps a different frequency than expected, but not varying each time.

Besides, after performing the CALL, the control goes completely to the user's program, especially after setting IE there is no way how the BASIC part could affect the software execution.

Bit 25.6 in BASIC52 is set after CLOCK1 is performed (i.e. BASIC's "real time" support is switched on) - which is not the case here I suppose. After all, it's easy to add a "clr 25.6" to the initialisation section of the "user" code just to be sure.

For BASIC52 manual etc. see for example www.nomad.ee ; although your incarnation is certainly modified to facilitate the "upload", the differences will be minor.

---

It's hard to say remotely but my guess is that this problem has hardware roots and the kit is not 100% OK from the hardware point of view (bad solder joints, loose connectors, loose and oxidised IC sockets and IC pins...). I'd also observe the waveforms on reset pin, VCC/GND(yes!) and clock (ALE) using the oscilloscope and/or their connection using a continuity tester.

JW

PS. You might want to post this question also on the 8052.com forum, where you might have received more specific '51-related help.

### umery2k75

Points: 2

#### umery2k75

It's the memory architecture

My code "CSEG AT RESET" is equal to ORG 0000h
My code "CSEG AT TIMER0" is equal to ORG 000Bh
you can check those addresses in the word document.
Problem is you can't access those since they are in EPROM

No,I can access these address 0000h and 000Bh, but they are useless to me, because they don't contain my code.This code is present in ROM and my Interrupt Service Routines of timer 0 is present at 400Bh.

============
In default mode(Jumper J5 connected), I can program only in these address of RAM 4000h to 7fffh.
I have run so many other programs except that of interrupt, which were starting on 7000h and they all run perfectly fine.

============
It's my assumption and I made this assumption when I see the ROM code of this controller as you can see above.Because with J5 connected, whenever an timer 0 interrupt occur, it goes to the code 000Bh, I thought of changing the ROM code of the controller at location with "ljmp 500BH", where my Interrupt Service Routine would be written for Timer 0 in RAM, so when I read the ROM code of controller, it was already written over there "ljmp 400BH, but with the condition of bit set for 25h.6!"

Okay now, I will focus on the ROM codes which are controlling the bit 25h.6 and I'll also make the flow chart of timer 0.

Added after 4 hours 7 minutes:

THIS PROBLEM IS RESOLVED A LITTLE BIT

This time I have used my Timer 1 instead of Timer 0 to generate the 10Khz frequency.Now, I'm getting perfect square wave of 10Khz on P1.4 , regardless the number of times I execute this program.

The new code for 10Khz sqr. wave on P1.4 is this:

Code:
org	401BH
TOISR:
cpl	p1.4
reti

org	7000h
main:
anl   TMOD, #0FH		  ;clear Timer 1 control
mov   TMOD, #020h  ;
mov   TL1,  #00h   ;value set by user
mov   TH1,  #0D2h   ;value set by user
setb IE.3
setb TR1        ;TCON.6  start timer 1

sjmp \$

end

The Basic-52 ROM code was also working perfectly fine.The problem was that some how the BASIC-52 was using timer 0 for it's own use( I think so) and may be that's the reason why, there was a jump bit condition as:

Code:
000B C000             22            push    psw
000D 202E10           23            jb      25h.6,X0020
0010 02400B           24            ljmp    X400b

I try to clear this 25h.6 bit in the program, but still the program was not giving me correct results.

When I saw the code for Timer 1 it was like this:

Code:
001B C000             30            push    psw
001D 021F78           31            ljmp    X1f78

I convert the above code as this:

Code:
001B 0000             30             nop
001D 02401B           31            ljmp    401Bh

By seeing no jump bit condition, I assume that the BASIC-52 is not using this timer 1 for it's own use or else there might be jump bit condition.

This time I decided not to use Timer 0 and to choose Timer 1 for the program.

Now, this interrupt worked fine, where there was no testing condition and there are some interrupts for Serial Port,External Interrupt 0/1,Timer 0, where there are testing condition.
l
I don't know, if I remove the jump bit condition and re-route them, whether they'll work or not.Because BASIC-52 does the initialization test of interrupts, I don't know what it does, but I have read about it in BASIC-52 manual, that it uses interrupts initially during the start up.So if I remove the jb condition and re-route them as I had done above.I think that MONITOR system(BASIC-52) may get hault.

I have to do something to gain access to my interrupts and I want to free them from the use of BASIC-52 for my programs.

YOU GUYS REALLY HELPED ME OUT IN PROVIDING DIFFERENT VIEWPOINTS TO LOOK AT IT, SO I'M CHECKING UP FOR "HELPED ME" TO ALL

I was thinking that there might be some hardware problem, but there ain't any!

#### wek

##### Full Member level 4

Now I see what's the problem - stack corruption.
In the BASIC part, psw is pushed onto the stack - you need to pop it from the stack in your code prior reti:
Code:
org 400BH
TOISR:
cpl  p1.4
pop  psw
reti

JW

#### mcs51mc

##### Member level 4
wek said:
Now I see what's the problem - stack corruption.
Absolutely not !!
Check the flow chart posted on 04 Nov 2007 12:20 by umery2k75.
You will se that BASIC-52 handles the "POP PSW" instruction very well when bit 25h.6 is set.

What happend at LABEL X400b when bit 25h.6 is cleared is still unknown since we never saw the code at that label.

The "ljmp X400b" in line 24 in BASIC-52 has nothing to with "ORG 400Bh" in umery2k75 program since the first one is a label and the last one an address!!!

To my opinion the problem is like umery2k75 already said.
Timer0 is used by BASIC-52 so the user can't use it, only Timer1 is available to him.

#### wek

##### Full Member level 4
mcs51mc said:
What happend at LABEL X400b when bit 25h.6 is cleared is still unknown since we never saw the code at that label.

Dear mcs51mc,

please note, that the presented snippet is a disassembly - and, from the binary (left to the disassembly) it's clear that ljmp X400b, which is 02 40 0B, IS in fact ljmp 400bh... Also, I wrote about meaning of the said flag in ...

I still hold my assertion on stack corruption true.

JW

#### umery2k75

Hi, I tried to put the pop statement before the Reti statement for Interrupt service routine.Still the system wasn't giving me correct frequency, when Timer 0 was used, I think that Timer 0 is in use by Basic-52 and Timer 1 wasn't in use by Basic-52, so I get away with Timer 1 easily.The logic following up the Stack corruption also seems very logical and sound.As there was no pop statement before the Reti statement.At this time I'm in my university lab, couple of hours later I'll be at my home, I'll then try every thing and will post the new reply with details

Yes, I think stack corruption was the only problem, I'll recheck everything couple of hours laters.

#### mosley401

##### Newbie level 3
umery2k75

I haven't run across anyone else in 13 years who has the AES51 system. I have this system and everything with it but have managed to lose the terminal emulator TE.EXE and can't find it anywhere. It seems the company doesn't exist anymore. If you have this program could you maybe email it to me? Much appreciated.

Status
Not open for further replies.