seemanta
Member level 4
8051 idle
Hi,
Based on the advice in my earlier post to create a battery powered AT89S52 based device, I have added some code for IDLE mode into my digital clock.
Unfortunately, after the micro goes to idle and it receives an interrupt from the RTC, it does not 'wake up'.
So I created a test program which handles the INT1 interrupt and displays a single character in the LCD, to see if my basic premise of dealing with sleep mode was correct.
Without the idle mode change, i.e the "MOV PCON,#01" change, it works well. However, with the idle mode changes, my ISR does not get hit when I press the switch for the INT1 line.
Here goes the code:
For simplicity, I have not added the LCD routines, LCD_POS_CURSOR, LCD_SEND_DATA and LCD_BUSY_WAIT. They are already tried and tested in my main clock program.
Can anyone please check what I am missing here? In principle, in the main routine, before I start going to an indefinite loop in the line 'SJMP HERE', I move 01h into the PCON register. This essentially takes the micro to idle mode.
Only an interrupt is supposed to get it out of idle mode. However, my ISR does not get hit and as a result, the code in the ISR never gets executed and I do not get any display in the LCD.
Please advice. I have a gut feeling I am missing something very trivial and simple here.
Thanks in advance,
Seemanta
Hi,
Based on the advice in my earlier post to create a battery powered AT89S52 based device, I have added some code for IDLE mode into my digital clock.
Unfortunately, after the micro goes to idle and it receives an interrupt from the RTC, it does not 'wake up'.
So I created a test program which handles the INT1 interrupt and displays a single character in the LCD, to see if my basic premise of dealing with sleep mode was correct.
Without the idle mode change, i.e the "MOV PCON,#01" change, it works well. However, with the idle mode changes, my ISR does not get hit when I press the switch for the INT1 line.
Here goes the code:
Code:
LETTER EQU 30H
ORG 0000H
LJMP MAIN ; BYPASSING THE INTERRUPT VECTORS
ORG 0013H ;/INT1 ISR
LCALL INT1_ISR
MOV PCON,#01 ;GO BACK TO IDLE MODE AFTER THE INTERRUPT
RETI
ORG 0030H
MAIN:
ACALL LCD_INIT ;INITIALIZING THE LCD
MOV IE,#10000100B ;ENABLING THE INT1 INTERRUPT
SETB TCON.3
MOV LETTER,#65 ;INITIALIZING WITH 'A'
MOV PCON,#01 ;GO TO IDLE MODE
HERE: SJMP HERE
INT1_ISR:
LCALL DELAY_20MS ;CALL THE DELAY ROUTINE - DEBOUNCING THE KEY
;CHECK PIN STATUS.IF UNSET,THIS WAS A FALSE ALARM.IF SET,THEN IT IS A TRUE INTERRUPT
JNB P3.3,RETN
MOV A,#00H
LCALL LCD_POS_CURSOR
MOV A,LETTER
LCALL LCD_SEND_DATA
ACALL LCD_BUSY_WAIT
INC LETTER
RETN: RET
DELAY_20MS:
MOV R1,#46
H1: MOV R2,#200
H2: DJNZ R2,H2
DJNZ R1,H1
RET
For simplicity, I have not added the LCD routines, LCD_POS_CURSOR, LCD_SEND_DATA and LCD_BUSY_WAIT. They are already tried and tested in my main clock program.
Can anyone please check what I am missing here? In principle, in the main routine, before I start going to an indefinite loop in the line 'SJMP HERE', I move 01h into the PCON register. This essentially takes the micro to idle mode.
Only an interrupt is supposed to get it out of idle mode. However, my ISR does not get hit and as a result, the code in the ISR never gets executed and I do not get any display in the LCD.
Please advice. I have a gut feeling I am missing something very trivial and simple here.
Thanks in advance,
Seemanta