Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Add GPS/PARSE to 8xSERVO-MOTOR CODE in Oshonsoft

The code will be useful for others too, a pseudo hardware uart can be very useful and most people never use CCP2.

I'd just like to know why the code doesn't compile when it's basically identical to the example in the manual.

Out of curiosity, does the example compile?
I.E.
Code:
Proc portb_display(arg1 As Byte)
PORTB = arg1
End Proc

Mike.
 
Ahhhhhhhhhhhh, it need call in front of it.
Try this,
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
call 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
        temp=77
        call putFifo(temp)                        'send the string as seperate bytes
        call putFifo(105)
        call putFifo(107)
        call putFifo(101)
        call putFifo(32)
        call putFifo(87)
        call putFifo(97)
        call putFifo(115)
        call putFifo(32)
        call putFifo(69)
        call putFifo(114)
        call putFifo(101)
        call putFifo(33)
        call putFifo(33)
        call putFifo(13)
        call 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*4=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.
 

Attachments

  • soft UART only.txt
    3.6 KB · Views: 226
The code will be useful for others too, a pseudo hardware uart can be very useful and most people never use CCP2.

I'd just like to know why the code doesn't compile when it's basically identical to the example in the manual.

Out of curiosity, does the example compile?
I.E.
Code:
Proc portb_display(arg1 As Byte)
PORTB = arg1
End Proc

Mike.
Hi M,
This compiles:
'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

Proc portb_display(arg1 As Byte)
PORTB = arg1
End Proc

C
 
Ahhhhhhhhhhhh, it need call in front of it.
Try this,
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
call 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
        temp=77
        call putFifo(temp)                        'send the string as seperate bytes
        call putFifo(105)
        call putFifo(107)
        call putFifo(101)
        call putFifo(32)
        call putFifo(87)
        call putFifo(97)
        call putFifo(115)
        call putFifo(32)
        call putFifo(69)
        call putFifo(114)
        call putFifo(101)
        call putFifo(33)
        call putFifo(33)
        call putFifo(13)
        call 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*4=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,
Added:
[ dim temp as byte ]
It compiles :0
C
 
Hi M,
Make sure I've done it correctly.
Removed dim temp as byte.
This compiles.
Code:
'18F4431 32MHz XTL REMOTE_SLAVE UART_GPS 110123 2301 test

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
Call 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

Call putFifo(77)

Call putFifo(105)
Call putFifo(107)
Call putFifo(101)
Call putFifo(32)
Call putFifo(87)
Call putFifo(97)
Call putFifo(115)
Call putFifo(32)
Call putFifo(69)
Call putFifo(114)
Call putFifo(101)
Call putFifo(33)
Call putFifo(33)
Call putFifo(13)
Call 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*4=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
C
 
Last edited:
Hi M,
Make sure I've done it correctly.
Removed dim temp as byte.
This compiles.
That all looks fine. If it works we can try using a loop again as in,
Code:
    if serialCount>=9600 then        'do this every second 
        serialCount=0                    'clear the count
        str="Mike Was Ere!!" + CrLf
        for i=0 to len(str)-1
            call putFifo(str(i))
        next i
    Endif
To see if that works.
Will have to add, of course,
Dim str As String
To the definitions at the top.

BTW, I'm assuming String positions start at zero.

Mike.
 
It should send "Mike Was Ere!!" out of C1 at 9600 baud every second.

Mike.
Hi M,
I'm on the wrong computer for HW, but this is what the Sim shows:
Got to stop now, g'night.
C
 

Attachments

  • Sim.jpg
    Sim.jpg
    70 KB · Views: 220
Last edited:
That all looks fine. If it works we can try using a loop again as in,
Code:
    if serialCount>=9600 then        'do this every second
        serialCount=0                    'clear the count
        str="Mike Was Ere!!" + CrLf
        for i=0 to len(str)-1
            call putFifo(str(i))
        next i
    Endif
To see if that works.
Will have to add, of course,
Dim str As String
To the definitions at the top.

BTW, I'm assuming String positions start at zero.

Mike.
Hi M,
Mañana
C
 
Hi,
I've updated #151 for clarity.

Note: I think you use a different system to mine?
I always try to update the title at the top of the CODE each iteration, showing what the CODE relates to and increment the date and time.
This help me find CODE in the future.
I notice you use the 164 CODE, so it relates to the 'shift register'

I added TRISC, and the line to speed up the sim.
If you don't use them, then I have to add them each time.

Anyway the CODE is compiling, so that's good, but there's nothing showig on the UART.
The 'watch variables, show nothing is being incremented, not sure whar this means.
EDIT: I haven't tried #152 yet.
C
 
Last edited:
None of these numbers make sense.
#151 says,

Please stop referring to previous posts and just write what you want to say.

Mike.
Hi M,
Strange! #151 on my screen shows an image which I changed?

So if I don't refer to earlier #'s
Did you notice that the CODE produces an incorrect stop BIT?
and,
I haven't tried the small section of CODE you sent earlier.
C
 
Hi M,
I've been on AAC, where they've been finding out where the CODE error occures.
Here's the explanation, from the Osh SIM.
C
Code:
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*4=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

Break '''''''''''''''''''''''''''''''''''' break point

PORTC.1 = 1 '''''' error msg
LATC.1 = PORTC.1 'ensure latch is same as current CCP output

If ccpDone Then
 

Latest threads

New Articles From Microcontroller Tips

Back
Top