Hi M,The servos only use CCP1 to do the pulses and the gap.
Mike.
Edit, timer 1 is also used but is never altered so it is free running and can be used for other timing.
'18F4431 32MHz XTL REMOTE_SLAVE 164 160223 2330
Define CONFIG1L = 0x00
Define CONFIG1H = 0x06 '8mHz XTL x4 =32mHz
Define CONFIG2L = 0x0c
Define CONFIG2H = 0x20
Define CONFIG3L = 0x04
Define CONFIG3H = 0x80
Define CONFIG4L = 0x80 'Set for HVP
Define CONFIG4H = 0x00
Define CONFIG5L = 0x0f
Define CONFIG5H = 0xc0
Define CONFIG6L = 0x0f
Define CONFIG6H = 0xe0
Define CONFIG7L = 0x0f
Define CONFIG7H = 0x40
Define CLOCK_FREQUENCY = 32
Define SINGLE_DECIMAL_PLACES = 2
Define STRING_MAX_LENGTH = 20
Dim wordTemp As Word
Dim i As Word
Dim cnt As Byte
dim fifo(32) as byte
dim fifoStart as byte
dim fifoEnd as byte
Dim ccpDone As Bit
Dim previous as Bit
Dim TXbyte as byte
Dim bitCount as byte
Dim str as string
dim serialCount as word
OSCCON = %01110000 '& h70
TRISA = %11000000 '7=OSC, 6=OSC,
TRISC = %11111010 '6=1-slave4431_cs, 2=74HC164 CLK, 0=74HC164 DATA
LATC.0 = 0 'ensure data is low
LATC.2 = 0 'and clock
For i = 0 To 7
LATC.2 = 1 'send positive clock edge
LATC.2 = 0 'send negative edge
Next i
TRISC = %11111010 'CCP2 (RC1) output
T1CON = %00100000 'prescaler = 4
T1CON.0 = 1 'start timer
PIE2.CCP2IE = 1 'CCP2 interrupts enable
INTCON.PEIE = 1
INTCON.GIE = 1
While 1
if serialCount>=9600 then 'every second do this
serialCount=0
str="Mike Was Ere!!" + CrLf
for i=0 to len(str))
putFifo(str(i))
next i
Endif
Wend
End
proc putFifo(dat as byte)
dim temp as byte
temp=fifoStart
if ((fifoEnd-temp) AND 0x1f)=0x1f then 'is fifo full
while fifoStart=temp 'yes so wait for interrupt
wend 'to make room
Endif
fifo(fifoEnd)=dat 'add data to queue
fifoEnd=(fifoEnd+1) AND 0x1f 'and increment pointer
End Proc
function getFifo() as byte 'note, doesn't test if fifo is empty
getFifo=fifo(fifoStart) 'so always call getFifoLen first
fifoStart=(fifoStart+1) AND 0x1f
End Function
function getFifoLen())
getFifoLen=(fifoEnd-fifoStar) AND 0x1f
End Function
On High Interrupt 'go via location 0x0008
Save System
if PIR2.CCP2IF Then
serialCount=serialCount+1
wordTemp.LB=CCPR2L 'ensure next interrupt is
wordTemp.HB=CCPR2H 'in 208*2=832 instruction cycles
wordTemp=wordTemp+208 '208 is 2,000,000/9600
CCPR2L=wordTemp.LB 'write it back
CCPR2H=wordTemp.HB
LATC.1=PORTC.1 'ensure latch is same as current CCP output
if ccpDone then
bitCount=0
if getFifoLen() then
TXbyte=getFifo()
CCP@CON=%1001
ccpDone=false
previous=0
Endif
else
'we're sending a byte
if bitCount<9 then
if TXbyte.1=previous then
'just need the interrupt
CCP2CON=%1010
else
'we need to flip the bit
if previous Then
'we need a zero next
previous=0
CCP2CON=%1001
else
'we need a one next
previous=1
CCP2CON=%1000
endif
endif
TXbyte=shiftRight(TXbyte,1)
else
'doing the stop bits
if bitCount<10 then
if previous then
CCP2CON=%1010 'just need interrupt
else
previous=1
CCP2CON=%1000 'go high next interrupt
endif
else
ccpDone=true
Endif
Endif
Endif
bitCount=bitCount+1
PIR2.CCP2IF=0
Endif
Resume
Hi M,This was missing from getFifoLen,
function getFifoLen() as byte
getFifoLen=(fifoEnd-fifoStart) AND 0x1f
End Function
It had fifoStar instead of fifoStart.
How do you access characters in a string as, putFifo(str(i)) doesn't compile?
I assume that str(2) will give me the third character of str. - zero based.
Does it need splitting? I.E.
Dim temp as Byte
temp=str(i)
putFifo(temp)
Mike.
'18F4431 32MHz XTL REMOTE_SLAVE 164 160223 2330
Define CONFIG1L = 0x00
Define CONFIG1H = 0x06 '8mHz XTL x4 =32mHz
Define CONFIG2L = 0x0c
Define CONFIG2H = 0x20
Define CONFIG3L = 0x04
Define CONFIG3H = 0x80
Define CONFIG4L = 0x80 'Set for HVP
Define CONFIG4H = 0x00
Define CONFIG5L = 0x0f
Define CONFIG5H = 0xc0
Define CONFIG6L = 0x0f
Define CONFIG6H = 0xe0
Define CONFIG7L = 0x0f
Define CONFIG7H = 0x40
Define CLOCK_FREQUENCY = 32
Define SINGLE_DECIMAL_PLACES = 2
Define STRING_MAX_LENGTH = 20
Dim wordTemp As Word
Dim i As Word
dim fifo(16) as byte
dim fifoStart as byte
dim fifoEnd as byte
Dim ccpDone As Bit
Dim previous as Bit
Dim TXbyte as byte
Dim bitCount as byte
dim serialCount as word
OSCCON = %01110000 '& h70
TRISA = %11000000 '7=OSC, 6=OSC,
TRISC = %11111000 '6=1-slave4431_cs, 2=74HC164 CLK, 0=74HC164 DATA 1=serial out
LATC.0 = 0 'ensure data is low
LATC.2 = 0 'and clock
LATC.1=1 'serial idle
For i = 0 To 7
LATC.2 = 1 'send positive clock edge
LATC.2 = 0 'send negative edge
Next i
T1CON = %00100000 'prescaler = 4
T1CON.0 = 1 'start timer
PIE2.CCP2IE = 1 'CCP2 interrupts enable
fifoStart=0
fifoEnd=0
INTCON.PEIE = 1
INTCON.GIE = 1
While 1
if serialCount>=9600 then 'every second do this
serialCount=0 'clear the count
putFifo("M") 'send the string as seperate bytes
putFifo("i")
putFifo("k")
putFifo("e")
putFifo(" ")
putFifo("W")
putFifo("a")
putFifo("s")
putFifo(" ")
putFifo("E")
putFifo("r")
putFifo("e")
putFifo("!")
putFifo("!")
putFifo(0x0d)
putFifo(0x0a)
Endif
Wend
End
proc putFifo(dat as byte)
while ((fifoEnd-fifoStart) AND 0x0f)=0x0f
wend
fifo(fifoEnd)=dat 'add data to queue
fifoEnd=(fifoEnd+1) AND 0x0f 'and increment pointer
End Proc
function getFifo() as byte 'note, doesn't test if fifo is empty
getFifo=fifo(fifoStart) 'so always call getFifoLen first
fifoStart=(fifoStart+1) AND 0x0f
End Function
function getFifoLen() as byte
getFifoLen=(fifoEnd-fifoStart) AND 0x0f
End Function
On High Interrupt 'go via location 0x0008
Save System
if PIR2.CCP2IF Then
serialCount=serialCount+1
wordTemp.LB=CCPR2L 'ensure next interrupt is
wordTemp.HB=CCPR2H 'in 208*2=832 instruction cycles
wordTemp=wordTemp+208 '208 is 2,000,000/9600 = 104uS or the time for 1 bit at 9600 baud
CCPR2H=wordTemp.HB 'it's really important that the high byte gets written first
CCPR2L=wordTemp.LB 'write it back
LATC.1=PORTC.1 'ensure latch is same as current CCP output
if ccpDone then
bitCount=0
if getFifoLen() then
TXbyte=getFifo()
CCP2CON=%1001 'pin high and low on next interrupt = start bit
ccpDone=false
previous=0
Endif
else
'we're sending a byte
if bitCount<9 then
if TXbyte.1=previous then
'just need the interrupt
CCP2CON=%1010
else
'we need to flip the bit
if previous Then
'we need a zero next
previous=0
CCP2CON=%1001
else
'we need a one next
previous=1
CCP2CON=%1000
endif
endif
TXbyte=shiftRight(TXbyte,1)
else
'doing the stop bits
if bitCount<10 then
if previous then
CCP2CON=%1010 'just need interrupt
else
previous=1
CCP2CON=%1000 'go high next interrupt
endif
else
ccpDone=true
Endif
Endif
Endif
bitCount=bitCount+1
PIR2.CCP2IF=0
Endif
Resume
'18F4431 32MHz XTL REMOTE_SLAVE 164 160223 2330
Define CONFIG1L = 0x00
Define CONFIG1H = 0x06 '8mHz XTL x4 =32mHz
Define CONFIG2L = 0x0c
Define CONFIG2H = 0x20
Define CONFIG3L = 0x04
Define CONFIG3H = 0x80
Define CONFIG4L = 0x80 'Set for HVP
Define CONFIG4H = 0x00
Define CONFIG5L = 0x0f
Define CONFIG5H = 0xc0
Define CONFIG6L = 0x0f
Define CONFIG6H = 0xe0
Define CONFIG7L = 0x0f
Define CONFIG7H = 0x40
Define CLOCK_FREQUENCY = 32
Define SINGLE_DECIMAL_PLACES = 2
Define STRING_MAX_LENGTH = 20
Dim wordTemp As Word
Dim i As Word
dim fifo(16) as byte
dim fifoStart as byte
dim fifoEnd as byte
Dim ccpDone As Bit
Dim previous as Bit
Dim TXbyte as byte
Dim bitCount as byte
dim serialCount as word
Dim length as Byte
OSCCON = %01110000 '& h70
TRISA = %11000000 '7=OSC, 6=OSC,
TRISC = %11111000 '6=1-slave4431_cs, 2=74HC164 CLK, 0=74HC164 DATA 1=serial out
LATC.1=1 'serial idle
T1CON = %00100000 'prescaler = 4
T1CON.0 = 1 'start timer
CCP2CON=%1010 'interrupt only
PIE2.CCP2IE = 1 'CCP2 interrupts enable
fifoStart=0
fifoEnd=0
INTCON.PEIE = 1
INTCON.GIE = 1
serialCount=0
putFifo(0xff) 'send a dummy byte to get in sync
While 1
if serialCount>=9600 then 'do this every second
serialCount=0 'clear the count
putFifo(77) 'send the string as seperate bytes
putFifo(73)
putFifo(107)
putFifo(101)
putFifo(32)
putFifo(87)
putFifo(97)
putFifo(115)
putFifo(32)
putFifo(69)
putFifo(114)
putFifo(101)
putFifo(33)
putFifo(33)
putFifo(13)
putFifo(10)
Endif
Wend
End
proc putFifo(dat as byte)
while ((fifoEnd-fifoStart) AND 0x0f)=0x0f
wend
fifo(fifoEnd)=dat 'add data to queue
fifoEnd=(fifoEnd+1) AND 0x0f 'and increment pointer
End Proc
function getFifo() as byte 'note, doesn't test if fifo is empty
getFifo=fifo(fifoStart) 'so always call getFifoLen first
fifoStart=(fifoStart+1) AND 0x0f
End Function
function getFifoLen() as byte
getFifoLen=(fifoEnd-fifoStart) AND 0x0f
End Function
On High Interrupt 'go via location 0x0008
Save System
if PIR2.CCP2IF Then
serialCount=serialCount+1
wordTemp.LB=CCPR2L 'ensure next interrupt is
wordTemp.HB=CCPR2H 'in 208*2=832 instruction cycles
wordTemp=wordTemp+208 '208 is 2,000,000/9600 = 104uS or the time for 1 bit at 9600 baud
CCPR2H=wordTemp.HB 'it's really important that the high byte gets written first
CCPR2L=wordTemp.LB 'write it back
LATC.1=PORTC.1 'ensure latch is same as current CCP output
if ccpDone then
bitCount=0
length=getFifoLen())
if length>0 then
TXbyte=getFifo()
CCP2CON=%1001 'pin high and low on next interrupt = start bit
ccpDone=false
previous=0
Endif
else
'we're sending a byte
if bitCount<9 then
if TXbyte.1=previous then
'just need the interrupt
CCP2CON=%1010
else
'we need to flip the bit
if previous Then
'we need a zero next
previous=0
CCP2CON=%1001
else
'we need a one next
previous=1
CCP2CON=%1000
endif
endif
TXbyte=shiftRight(TXbyte,1)
else
'doing the stop bits
if bitCount<10 then
if previous then
CCP2CON=%1010 'just need interrupt
else
previous=1
CCP2CON=%1000 'go high next interrupt
endif
else
ccpDone=true 'stop bits will still be generated - this happens at bitCount=10
Endif 'and output will stay high until next byte
Endif
Endif
bitCount=bitCount+1
PIR2.CCP2IF=0
Endif
Resume
Hi M,OK, try this. I've changed all the "M" etc to ascii values and placed fifo length into a variable.
Code:'18F4431 32MHz XTL REMOTE_SLAVE 164 160223 2330 Define CONFIG1L = 0x00 Define CONFIG1H = 0x06 '8mHz XTL x4 =32mHz Define CONFIG2L = 0x0c Define CONFIG2H = 0x20 Define CONFIG3L = 0x04 Define CONFIG3H = 0x80 Define CONFIG4L = 0x80 'Set for HVP Define CONFIG4H = 0x00 Define CONFIG5L = 0x0f Define CONFIG5H = 0xc0 Define CONFIG6L = 0x0f Define CONFIG6H = 0xe0 Define CONFIG7L = 0x0f Define CONFIG7H = 0x40 Define CLOCK_FREQUENCY = 32 Define SINGLE_DECIMAL_PLACES = 2 Define STRING_MAX_LENGTH = 20 Dim wordTemp As Word Dim i As Word dim fifo(16) as byte dim fifoStart as byte dim fifoEnd as byte Dim ccpDone As Bit Dim previous as Bit Dim TXbyte as byte Dim bitCount as byte dim serialCount as word Dim length as Byte OSCCON = %01110000 '& h70 TRISA = %11000000 '7=OSC, 6=OSC, TRISC = %11111000 '6=1-slave4431_cs, 2=74HC164 CLK, 0=74HC164 DATA 1=serial out LATC.1=1 'serial idle T1CON = %00100000 'prescaler = 4 T1CON.0 = 1 'start timer CCP2CON=%1010 'interrupt only PIE2.CCP2IE = 1 'CCP2 interrupts enable fifoStart=0 fifoEnd=0 INTCON.PEIE = 1 INTCON.GIE = 1 serialCount=0 putFifo(0xff) 'send a dummy byte to get in sync While 1 if serialCount>=9600 then 'do this every second serialCount=0 'clear the count putFifo(77) 'send the string as seperate bytes putFifo(73) putFifo(107) putFifo(101) putFifo(32) putFifo(87) putFifo(97) putFifo(115) putFifo(32) putFifo(69) putFifo(114) putFifo(101) putFifo(33) putFifo(33) putFifo(13) putFifo(10) Endif Wend End proc putFifo(dat as byte) while ((fifoEnd-fifoStart) AND 0x0f)=0x0f wend fifo(fifoEnd)=dat 'add data to queue fifoEnd=(fifoEnd+1) AND 0x0f 'and increment pointer End Proc function getFifo() as byte 'note, doesn't test if fifo is empty getFifo=fifo(fifoStart) 'so always call getFifoLen first fifoStart=(fifoStart+1) AND 0x0f End Function function getFifoLen() as byte getFifoLen=(fifoEnd-fifoStart) AND 0x0f End Function On High Interrupt 'go via location 0x0008 Save System if PIR2.CCP2IF Then serialCount=serialCount+1 wordTemp.LB=CCPR2L 'ensure next interrupt is wordTemp.HB=CCPR2H 'in 208*2=832 instruction cycles wordTemp=wordTemp+208 '208 is 2,000,000/9600 = 104uS or the time for 1 bit at 9600 baud CCPR2H=wordTemp.HB 'it's really important that the high byte gets written first CCPR2L=wordTemp.LB 'write it back LATC.1=PORTC.1 'ensure latch is same as current CCP output if ccpDone then bitCount=0 length=getFifoLen()) if length>0 then TXbyte=getFifo() CCP2CON=%1001 'pin high and low on next interrupt = start bit ccpDone=false previous=0 Endif else 'we're sending a byte if bitCount<9 then if TXbyte.1=previous then 'just need the interrupt CCP2CON=%1010 else 'we need to flip the bit if previous Then 'we need a zero next previous=0 CCP2CON=%1001 else 'we need a one next previous=1 CCP2CON=%1000 endif endif TXbyte=shiftRight(TXbyte,1) else 'doing the stop bits if bitCount<10 then if previous then CCP2CON=%1010 'just need interrupt else previous=1 CCP2CON=%1000 'go high next interrupt endif else ccpDone=true 'stop bits will still be generated - this happens at bitCount=10 Endif 'and output will stay high until next byte Endif Endif bitCount=bitCount+1 PIR2.CCP2IF=0 Endif Resume
Mike.
Hi M,How on earth are you supposed to use a procedure? putFifo is a procedure that expects a byte as a parameter. How is putFifo(xx) not that? What does it need to be?
Mike.
Edit, what is the error on those lines?
Hi M,Does it compile if you put the value in a byte variable?
I.E.
Dim temp as Byte
temp=255
putFifo(temp)
instead of
putFifo(0xff)
Mike.
From the manual,Hi M,
I'm no programmer, but could the problem be:
proc putFifo(dat as byte)
I've never seen and extra word such as 'dat' before.
C
This code is to output comments so you can debug, or so I thought. The hardware UART is reading the sentence from the GPS.Hi M,
Would you prefer that if I can get the GPS module to communicate via SPI, instead of UART, we leave this CODE, till I find out?
C
Hi M,From the manual,
View attachment 140785
on page 10.
This code is to output comments so you can debug, or so I thought. The hardware UART is reading the sentence from the GPS.
Mike.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?