I am somewhat embarrassed to say that it has been a few months since I had the time to sit down and experiment on the Brat. I am trying to rearrange some of the servos and the like such that I could free up the pins for the hardware serial port and possibly the hardware I2C pins. This is the first time I reprogrammed the brat since converting from IDE 8.0.0.0 to 8.0.1.0. I thought I would do this in steps. First rearrange the servos and update the defines in the program that are associated with these servos. The first mistake I made was to try to use P9, which made it pretty noisy! I fixed that but then found that my LCD display on top was not working properly (mostly getting garbage). This LCD is a Sparkfun serial LCD that I have configured to run at 2400 baud as I had problems earlier at 9600 baud.
I found that if I commented out the ENABLEHSERVO command along with the other HSERVO commands, the LCD display worked fine. I extracted some of the BRAT code and included it below. Please note, there are two versions of the HANDLE_IRPD code as at first I thought it was the timer interrupt that might be causing the problems and so I tried to reconfigure this code to not require the interrupt. I have not fully debugged this code yet (probably timing issues), but it sometimes gets the right code from the TV remote…
Suggestions?
; Simple Test program to check the serial lcd with HSERVO enabled and possible timer running...
; define which LCD I am using...
;SEETRON con 1
LCDPIN con p0
#ifdef SEETRON
LCD_BAUD con n2400
#else
LCD_BAUD con i2400
#endif
;Interrupt init
USE_HSERVO con 1
#ifdef USE_HSERVO
HSERVO_GROUPS con 4
ENABLEHSERVO
#endif
ONINTERRUPT WKPINT_3,handle_irpd
USE_TIMER con 1
#ifdef USE_TIMER
ONINTERRUPT TIMERAINT,handle_timera
#endif
PMR5.bit3 = 1
TMA=4 ;increments on clock/256
ENABLE WKPINT_3
#ifdef USE_TIMER
ENABLE TIMERAINT
#endif
LoopCount var word
lasttime var long
overflowtime var long
currenttime var long
diff var long
tmaCycle var long
datacount var sbyte
irpd_data var word
command var byte
; variables for LCD... Not sure how to pass an array to a gosub so.
LCD_String var byte(17)
lasttime = -1 ;indicate next data should be a startpulse
;End of System setup. Add user variables below this line.
gosub LCD_Init
low 1
low 2
pause 1000
LCD_String = "Hello Brat|"
gosub LCD_Print[1, 0]
command=0xFF
LoopCount = 0
main
LoopCount = LoopCount + 1
if LoopCount = 32767 then
gosub LCDConvertNumToString[TCA]
gosub LCD_Print[1,1]
LoopCount = 0
endif
if(command<>0xFF)then
gosub LCDConvertNumToString[command]
gosub LCD_Print[2,1]
command = 0xff
endif
goto main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Handle IRPD - try to not use timer interrupt as the largest value we need appears to be 195...
handle_irpd
#ifdef USE_TIMER
currenttime=overflowtime+TCA
if(currenttime<0)then ;If we overflow to a negative number reset everything
overflowtime=0
currenttime=TCA
lasttime=-1
endif
if(lasttime<0)then ;If negtive lasttime, reset
datacount=0
lasttime=currenttime
else ;else process pulses
datacount=datacount+1
diff=currenttime-lasttime
irpd_data=irpd_data>>1
if(diff>175 AND diff<195)then ;If we get a start pulse reset datacount and irpd_data
irpd_data=0
datacount=0
elseif(diff>100 and diff<120) ;we got a "1" pulse
irpd_data.bit10=1
elseif(diff>65 and diff<85) ;we got a "0" pulse
irpd_data.bit10=0
else ;we got an invalid pulse so reset
lasttime=-1
resume
endif
if(datacount=11)then
lasttime=-1
command = irpd_data&0x7F
else
lasttime = currenttime
endif
endif
Resume
#else
tmaCycle=TCA
if (irr1.bit6) then
irr1.bit6 = 0
datacount = -1
resume
endif
TMA = 0xc ; reset tma
TMA = 4 ; divide by 256
if(datacount<0)then ;If negtive data count reset things...
datacount=0
else ;else process pulses
datacount=datacount+1
irpd_data=irpd_data>>1
if(tmaCycle>175 AND tmaCycle<195)then ;If we get a start pulse reset datacount and irpd_data
irpd_data=0
datacount=0
elseif(tmaCycle>100 and tmaCycle<120) ;we got a "1" pulse
irpd_data.bit10=1
elseif(tmaCycle>65 and tmaCycle<85) ;we got a "0" pulse
irpd_data.bit10=0
else ;we got an invalid pulse so reset
datacount = -1
resume
endif
if(datacount=11)then
datacount =-1
command = irpd_data&0x7F
endif
endif
Resume
#endif
handle_timera
overflowtime=overflowtime+256
resume
;
; Serial LCD functions added by Kurt
;
LCD_Init
; make sure SerLCD has a chance to finish initializing after power-up
; Reset to 9600 and powerup... - Uncomment if having problems with LCD.
; serout LCDPIN, I9600, [0x12]
Pause(1000)
; Now lets try setting it to 2400 baud. - uncomment if having problems
; Serout LCDPIN, I9600, [0x7c] ; 124, <control k>
; pause 2
; Serout LCDPIN, I9600, [11] ; 124, <control k>
#ifndef SEETRON
; Set the backlight to low
Serout LCDPIN, LCD_BAUD, [0x7C, 0x80] ; 124, 128 - Off
#endif
; Output the clear screen command
gosub LCD_WriteCommand[1] ; // Clear the screen
Pause(5)
return
;
; Main LCD output function
;
line var sbyte
fPad var byte
LCD_Print[line, fPad]
DISABLE WKPINT_3
#ifdef USE_TIMER
DISABLE TIMERAINT
#endif
if line = 1 then
gosub LCD_WriteCommand[0x80]
elseif line = 2
gosub LCD_WriteCommand[0xC0]
endif
Pause(1)
for line = 0 to 14 ; try now to write to last position as it appears to autoscroll...
if fPad <> 2 and LCD_String(line) > 0 and LCD_String(line) <> "|" then
serout LCDPIN, LCD_BAUD, [LCD_String(line)]
else
if fPad = 0 then
goto LCDP_Enable
endif
fPad = 2
serout LCDPIN, LCD_BAUD, " "]
endif
Pause(1)
next
LCDP_Enable
ENABLE WKPINT_3
#ifdef USE_TIMER
ENABLE TIMERAINT
#endif
return
;
;DISPLAY DATA RAM ADDRESSES
;CHARACTER 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
; + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
;LINE 1 | 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
;LINE 2 | C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
;
ich var byte
iline var byte
LCD_SetPos[ich, iline]
if iline = 1 then
gosub LCD_WriteCommand[0x80+ich]
else
gosub LCD_WriteCommand[0xC0+ich]
endif
pause 10
return
; clears the display and resets the current location to the upper left */
LCD_ClearAndReturn
gosub LCD_WriteCommand[1] ; // clear display
Pause(100)
return
fRight var byte
ichShift var byte
LCD_ShiftDisplay[fRight, ichShift]
if fRight <> 0 then
fRight = 0x1c
else
fRight = 0x18
endif
while (ichShift > 0)
gosub LCD_WriteCommand[fRight]
ichShift = ichShift -1
wend
return
; Send a command to the LCD, first send a command prefix character and then then command
cmd var byte
LCD_WriteCommand[cmd]
serout LCDPIN, LCD_BAUD, [0xfe]
pause 1
serout LCDPIN, LCD_BAUD, [cmd]
return
iCnT1 var byte
iCnt2 var byte
iOut var sword
LCDConvertNumToString[iOut]
if iOut < 0 then
LCD_String(0) = "-"
iOut = -iOut
iCnt1 = 1
iCnt2 = 1
else
iCnt1 = 0
iCnt2 = 0
endif
while (iOut > 0)
LCD_String(iCnt1) = "0" + iOut // 10
iOut = iOut / 10
iCnt1 = iCnt1 + 1
wend
if iCnt1 = 0 then
LCD_String = "0"
else
LCD_String(iCnt1) = 0
iCnt1 = iCnt1 - 1
while (iCnt1 > iCnt2)
swap LCD_String(iCnt1), LCD_String(iCnt2)
iCnt1 = iCnt1 - 1
iCnt2 = iCnt2 + 1
wend
endif
return