Basically, I am creating a remote control interface for my robot. I am trying to get the serial interrupt to work. In the code below, Keypad uC system (now simulated by PC) sends 0 in binary when the turn right key is pressed on the remote control, 9 is sent for turn left key.
The robot program should be haulted when a serial byte comes in, and checks to see what value it receives, and jumps to turn right, left etc. appropriately depending on what the received byte is.
Though my code compiles, it does not work when I download it onto the 8051 on my robot. When I run it for the first time on the 8051, upon the first byte input, the uC simply goes back to the top of the program and starts again (like I have reset it). Any subsequent presses on any key makes no affect on the robot, it just functions normally ignoring all serial data input.
Here is the code:
**broken link removed**
Note: comment reads 'interrupt service routine' next to ORG 23H at the beginning of the code. Thats obviously not the ISR, it's at the bottom (just not to confuse beginners reading). Also, 'now clear it' in comment next to CLR RI
Anyone else ever worked with serial interrupt on the 8051?
The problem I am having is that when I send a byte, the program goes back to the top and starts again. Any subsequent byte sent is ignored by the progrem, unless I reset the uC, then the same thing happens....
I didn't use the interrupt but polled the RI and TI bits.
I transmit packages of 5 bytes between PC and µC.
You can see the variable "Scherm" as a state of a state machine:
During state 80, 5 bytes are received from the PC
During state 81, 5 bytes are send to the PC
Below code for:
1) Init serial comm
2) Receive 5 bytes from PC
3) Send 5 bytes to PC
4) Stop serial comm
1) Initialising serial comm
Code:
; Setup the serial port for 4800 baud at 12MHz.
; TH1 = 256 - (crystal / (2 * 12 * 16 * baudrate)) with SMOD.7 = 0
; TH1 = 256 - (crystal / (12 * 16 * baudrate)) with SMOD.7 = 1
; with crystal= crystalfrequentie (Hz)
; baudrate= desired baudrate (bits/sec)
;
InitializeSerialComm:
mov SCON,#050h ;SCON: mode 1, 8-bit UART, enable rcvr
orl PCON,#080h ;Set bit SMOD.7 to doubles the baud rate
orl TMOD,#020h ;TMOD: timer 1, mode 2, 8-bit reload
mov TH1,#0F3h ;TH1: reload value for 4800 baud @ 12MHz
setb TR1 ;TR1: timer 1 run
setb TI ;TI: set TI to send first char of UART
ret
2) Poll RI bit and if set, store received byte in array and when 5 bytes are received, handle them.
Code:
L6080A: jnb RI,L6080End ;Wait until character received
mov a,#SerialData ;Calculate address for received byte
add a,GP_Array+6
mov R0,a
mov @R0,SBUF ;Store received byte
clr RI ;Clear reception flag
inc GP_Array+6
mov a,GP_Array+6 ;5 bytes received?
xrl a,#5
jnz L6080End
jmp HandleReceivedBytes
L6080End:ret
3) Send 5 bytes to PC
Code:
L6081Start: cjne a,#81,L6082Start ;Scherm 81
jnb TI,L6081End ;Wait until transmission complete
clr TI ;Clear 'Ready for transmission' flag
mov a,#SerialData ;Calculate address for byte to send
add a,GP_Array+6
mov R0,a
mov SBUF,@R0 ;Send byte
inc GP_Array+6
mov a,GP_Array+6 ;5 bytes send?
xrl a,#5
jnz L6081End
mov Scherm,#82 ;Naar scherm 82: Ontvangen data schakeltijden
L6081End: ret
The polling interrupt wasnt working I think because of 'silly' mistakes and not because of errors in the way I was polling. I had JUMPS to routines where I had placed RET thinking they were CALLS, of that sort basically.
I take it that polling is more reliable/easy to work with (particularly serial interrupt)? I was reading www.8052.com which said something like interrupt codes are easy to mess up, the program may run for a while and then crash - maybe even after a month etc. if you dont get things thought out properly/spot on etc.
I take it that polling is more reliable/easy to work with (particularly serial interrupt)? I was reading www.8052.com which said something like interrupt codes are easy to mess up, the program may run for a while and then crash - maybe even after a month etc. if you dont get things thought out properly/spot on etc.