Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

8051 interrupt help needed!!!

Ok, I need to know if I have a bad board or I'm just mental.

I'm trying to program a PJRC 8051 board to activate an interrupt routine based on EXTERNAL interrupts. Below is one program that as far as I know should work. If you see something wrong or something I'm missing, please let me know. It should blink a light pattern specified by table then switch patterns when external interrupt 0 is low. It seems to every once and a while lock the program up, but it has never actually executed the interrupt.

Thanks

.equ locat, 0x3000 ;Location for this program
;82C55 memory locations, Rev 4
.equ port_d, 0xF900 ;access port D
.equ port_e, 0xF901 ;access port E
.equ port_f, 0xF902 ;access port F
.equ port_def_pgm, 0xF903 ;configure in/out of all three ports
.equ esc, 0x003E ;paulmon2's check for esc key

.org locat
.db 0xA5,0xE5,0xE0,0xA5 ;signiture bytes
.db 35,255,0,0 ;id (35=prog)
.db 0,0,0,0 ;prompt code vector
.db 0,0,0,0 ;reserved
.db 0,0,0,0 ;reserved
.db 0,0,0,0 ;reserved
.db 0,0,0,0 ;user defined
.db 255,255,255,255 ;length and checksum (255=unused)
.db "Hope",0 ;max 31 characters, plus the zero
.org locat+64 ;executable code begins here

.org 0x0000
ajmp startup

.org 0x0003
Intcall_0: ;ISR
mov dptr, #table2
reti

startup:
setb ex0 ;enable external interrupt 0
setb ex1 ;enable external interrupt 1
setb ea ;also turn on interrupts in general
mov dptr, #port_def_pgm
mov a, #128
movx @dptr, a ;make all D-E-F port pins outputs

begin:
mov dptr, #table
;DPTR will keep track of which entry in
;the table we will do next
loop:
clr a
movc a, @a+dptr ;get pattern to display
acall update
inc dptr
lcall esc ;abort if the user presses ESC
jc exit
clr a
movc a, @a+dptr ;get time to display this pattern
jz begin
acall delay
inc dptr
sjmp loop ;keep doing the animation....
exit: ljmp 0

update:
push dph
push dpl
mov dptr, #port_e
movx @dptr, a
pop dpl
pop dph
ret

delay:
mov r0, a
dly2: mov r1, #230
dly3: nop
nop
nop ;6 NOPs + DJNZ is 4.34 us
nop ;with the 22.1184 MHz crystal
nop
nop
djnz r1, dly3 ;repeat 230 times for 1 ms
djnz r0, dly2 ;repeat for specified # of ms
ret

table:
.db 01111111b, 90
.db 11111111b, 90
.db 255,0 ;zero marks end of table

table2:
.db 11111110b, 90
.db 11111111b, 90
.db 255,0

Comments

  • CytCyt Posts: 557Member
    As far as you know it works... If you have this exact code, I doubt it:

    [code]
    (...)
    .org locat+64 ;executable code begins here

    ; Here your code should be, but instead:
    .org 0x0000
    ajmp startup

    .org 0x0003
    Intcall_0: ;ISR
    mov dptr, #table2
    reti

    ; Startup is here at address 0x06 -
    ; in the middle of the interrupt vectors...

    startup:
    setb ex0 ;enable external interrupt 0
    [/code]

    Moreover, the implementation of your interrupt is hopefully just a tester. You shouldn't modify registers there. Rather, you should save the registers that you need, manipulate some variable in memory, and restore the registers.

    Excactly this code might cause the problems because of that:
    [code]
    update:
    push dph
    push dpl
    mov dptr, #port_e
    ; If an interrupt occurs here, you are in trouble....
    movx @dptr, a
    pop dpl
    pop dph
    ret
    [/code]

Sign In or Register to comment.