Define CONFIG1H = 0x06 '8MHz XTL x4 HSPLL =32MHz
Hi T,Are you sure the original was using an 8MHz clock and not 32MHz?
The various constants and comments in the original imply it's counting at a 500ns rate (2MHz), and you get that with a 32MHz clock and a TMR1 prescaler of 1:4
The CONFIG setting shown:
will get you HS oscillator, PLL enabled as the primary oscillatorCode:Define CONFIG1H = 0x06 '8MHz XTL x4 HSPLL =32MHz
Any OSCCON setting in the code may not matter if the lower two SCS1:SCS0 bits are '00', which specifies "use the primary oscillator setting", which comes from the CONFIG1H setting. You would have to have the CONFIG1H set for one of the INTOSC settings or SCS1:SCS0 = 1x to select the internal osc block for the IRCF[2:0] Internal Oscillator Frequency Select bits to matter
ServoPos(i) = i * 250 + 2000 '1ms(2000) to 1.875(1 7/8ths - 3750)ms in 1/8th mS steps
Hi T,What I'm saying is that if OSCCON ends in '00' then it doesn't change the osc setting set by the CONFIG1H word, so just because there's an 'OSCCON= xxxx' statement in the code doesn't mean anything.
The comments like this:lead me to believe that's it's already set for 32MHz... 2000 counts of 500ns = 1ms, and you get 500ns counts with 32MHz and a 1:4 prescaler.Code:ServoPos(i) = i * 250 + 2000 '1ms(2000) to 1.875(1 7/8ths - 3750)ms in 1/8th mS steps
Is there a copy of the "original code" here somewhere?
'18F4431 32MHz XTL PCB9 REMOTE_SLAVE GPS_SERVO 070224 1600
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
Define SIMULATION_WAITMS_VALUE = 1 'Comment in for SIM out for PIC
Dim wordTemp As Word
Dim ServoCount As Byte
Dim i As Word
Dim ServoPos(8) As Word
Dim servoDir(8) As Byte
Dim frame As Word
Dim gpsbuf(80) As Byte
Dim strCount As Byte
Dim rec As Byte
Dim isDone As Bit
Dim pos As Word
Dim dir As Byte
Symbol rled = PORTD.7
OSCCON = %01110000 '& h70
TRISA = %11000000 '7=OSC, 6=OSC,
TRISB = %00000000 '0=SEROUT
TRISC = %11110010 '6=1-slave4431_cs, 3=74HC164 MR, 2=74HC164 CLK, 0=74HC164 DATA'<<<<<<<<<<<<
TRISD = %00000000
LATC.0 = 0 'ensure data is low
LATC.2 = 0 'and clock
LATC.3 = 1 'Master reset HIGH for run.'<<<<<<<<<<<<<<
For i = 0 To 7
LATC.2 = 1 'send positive clock edge
ServoPos(i) = i * 250 + 2000 '1ms(2000) to 1.875(1 7/8ths - 3750)ms in 1/8th mS steps
LATC.2 = 0 'send negative edge
servoDir(i) = i And 1 '<<<<<<<added
Next i
'Start up led
rled = 1
WaitMs 1000
rled = 0
WaitMs 1000
rled = 1
WaitMs 1000
rled = 0
WaitMs 1000
'TRISC = %11111010 'CCP0 (RC2) & RC0 output'<<<<<<<<<<<<<<<<<<<<
ServoCount = 8 'cause it to reset
T1CON = %00100000 'prescaler = 4
T1CON.0 = 1 'start timer
CCP1CON = %1000 'will go high on interrupt - will start a 0.5mS pulse
frame = 1000 'start everything in 4000 cycles
strCount = 0
isDone = 0
'setup USART for 9600 baud receive
RCSTA = %10010000
TXSTA.BRGH = 1
BAUDCON.BRG16 = 1
SPBRG = 207
PIR1.RCIF = 0
PIE1.RCIE = 1
PIE1.CCP1IE = 1
INTCON.PEIE = 1
INTCON.GIE = 1
While 1 '\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
While ServoCount = 0 'wait for 20mS to pass (=1/50th of a second)
Wend
While ServoCount <> 0
Wend
For i = 0 To 7
dir = servoDir(i) 'doesn't matter if ISR happens as servoPos isn't changed by ISR
pos = ServoPos(i)
If dir = 1 Then
pos = pos + 40 'add 1/50th to the servo position
Else
pos = pos - 40 'subtract it
Endif
If pos < 2000 Then 'have we gone past the end?
pos = 2000 'yes so make it the end stop
dir = 1 'and turn it around
Endif
If pos > 4000 Then 'same for other end
pos = 4000
dir = 0
Endif
INTCON.GIE = 0
ServoPos(i) = pos
INTCON.GIE = 1
servoDir(i) = dir 'servoDir not used by ISR
Next i
'Serout PORTB.0, 9600, "$ R W ", gpsbuf(0), gpsbuf(3), gpsbuf(44), CrLf
Wend
End
On High Interrupt 'go via location 0x0008
Save System
If PIR1.CCP1IF Then 'has CCP1 triggered?
wordTemp.HB = CCPR1H 'get value of CCPR1 into wordTemp
wordTemp.LB = CCPR1L
If CCP1CON = 0x08 Then 'have we started the 1000 cycle pulse
CCP1CON = 0x09 'yes so end the pulse after 0.5mS
wordTemp = wordTemp + 1000 'adding 1000 will make pulse 0.5mS long
Else
LATC.0 = 0 'clear the data pin
CCP1CON = 0x08 'No so output the timed gap
If ServoCount < 8 Then
'still doing the servos so add remainder of time
wordTemp = wordTemp + ServoPos(ServoCount)
wordTemp = wordTemp - 1000 'knock of the 1000 (0.5mS) already elapsed
frame = frame - ServoPos(ServoCount)
ServoCount = ServoCount + 1
Else
'done all the servos so just the frame gap to do
wordTemp = wordTemp + frame
frame = 39000 '40,000(20mS) minus time of positive pulse(0.5mS)
ServoCount = 0 'start all over again
LATC.0 = 1 'will become first pulse (is data pin of shift register)
Endif
Endif
CCPR1H = wordTemp.HB 'put value back into CCPR1
CCPR1L = wordTemp.LB
PIR1.CCP1IF = 0 'clear interrupt flag
Endif
If PIR1.RCIF Then
rec = RCREG 'get the received character
If RCSTA.OERR Or RCSTA.FERR Then 'neither of these should ever occur.
RCSTA.CREN = 0 'this is kinda wishful thinking
If PIR1.RCIF Then
rec = RCREG
Endif
RCSTA.CREN = 1 'as any data received is corrupt
strCount = 0 'however, reset everything
isDone = 0 'and hope for the best
Else 'no errors so use the data
If strCount = 0 And isDone = 0 Then 'are we already receiving
'waiting for $ 'no so wait
If rec = "$" Then 'for $ to appear'<<<<<<<<<<<<<<<<<<<<<<<<
gpsbuf(strCount) = rec 'start receiving
strCount = strCount + 1
Endif
Else
If isDone = 0 And strCount < 79 Then 'have we collected a full string?
gpsbuf(strCount) = rec 'no so carry on storing
strCount = strCount + 1
If rec = "W" Then 'have we got the "endOfString" character'<<<<<<<<<<<<
isDone = 1 'yes, so set done true
'put break here
Endif
Else
If isDone = 0 Then '?????????<<<<<<<<<<<<<<<<<<<<<<<
'still waiting to start or buffer overflow
strCount = 0
Endif
Endif
Endif '<<<<<<<<<<<<<<<
Endif
Endif 'end RS232 if
Resume
'setup USART for 9600 baud receive
RCSTA = %10010000
TXSTA.BRGH = 1
BAUDCON.BRG16 = 1
SPBRG = 207
Hi T,The OSCCON register allows you to select between different clock sources, depending on the lower two bits SCS1:SCS0...
00 = primary osc (the one set by CONFIG1H)
01 = secondary osc (TIMER1)
1x = internal osc
The code in #304 sets OSCCON = %01110000 (0x70), so the lower two bits tell it to use the primary CONFIG1H osc setting, which in this case is Define CONFIG1H = 0x06 '8mHz XTL x4 =32MHz. The comment is correct for that...
0110= HS oscillator, PLL enabled (clock frequency = 4 x FOSC1)
As long as you have an 8MHz xtal you should already be running at 32MHz with those settings.
All of the existing TMR/CCP settings in that code seem to match with that.
The only thing that doesn't is the UART setting, which is shown as:
Code:'setup USART for 9600 baud receive RCSTA = %10010000 TXSTA.BRGH = 1 BAUDCON.BRG16 = 1 SPBRG = 207
At 32MHz those register settings will get you a baud rate of 38400, not 9600 as the comment claims.
If you want 9600 baud then change the line to TXSTA.BRGH = 0
If you comment out the 'OSCCON = %01110000' in the above code nothing should change.
You shouldn't need to change anything.
Is there any difference between this CODE:
-------------------------------------------------
'setup USART for 9600 baud receive
RCSTA = %10010000
TXSTA.BRGH = 1
BAUDCON.BRG16 = 1
SPBRG = 207
-----------------------------------------------
and the Oshonsoft [ Hseropen 9600 ]?
If you set TXSTA = 0 then that will reset the TXSTA.BRGH bit (which will change the baud rate to 9600), and also clear TXEN which will disable UART output.but If I understand correctly, TXSTA should be set to '0'.
Hi T,I don't use Oshonsoft, so take this fwiw...
Probably. For one thing, as I mentioned, at 32MHz those code settings will get you 38400 baud, so it's probably more like "Hseropen 38400". Hseropen will likely enable the TX output as well.
If you set TXSTA = 0 then that will reset the TXSTA.BRGH bit (which will change the baud rate to 9600), and also clear TXEN which will disable UART output.
If you don't need the UART TX, then set TXSTA = 0 right after setting RCSTA so that any other changes to TXSTA aren't effected. An Hseropen statement would likely override all those settings provided it was after the register setup and not before it.
Hi T,TXSTA = 0 must be above TXSTA.BRGH = 1
Setting TXSTA afterwards will reset any BRGH bit setting, so it might change the baud rate depending on the BRG16 setting as shown above.I tried Hseropen 38400 with TXSTA = 0 below. This didn't stall
Hseropen 38400
TXSTA.TXEN = 0 ' disable TX
'setup USART for 38400 baud receive only (disable TXEN)
RCSTA = %10010000
TXSTA = 0 ' TXEN=0, SYNC=0, BRGH=0
TXSTA.BRGH = 1
BAUDCON.BRG16 = 1
SPBRG = 207
INTCON.PEIE = 1
INTCON.GIE = 1
INTCON.GIEL = 1
INTCON.GIEH = 1
Hi T,From what I see in the documentation they mention ENABLE HIGH and ENABLE LOW interrupt priorities,
so I would assume that means behind the scenes they use RCON IPEN=1 to enable interrupt priority.
In your code, right before the 'WHILE 1' loop you have:
Code:INTCON.PEIE = 1 INTCON.GIE = 1
When you have IPEN=1 those two bits change function and are better thought of as:
Code:INTCON.GIEL = 1 INTCON.GIEH = 1
So, you're enabling the low-priority intr but not specifying a vector. Not a good idea.
Also, just so you're aware, disabling the high-priority interrupt (INTCON.GIEH = 0) disables all interrupts.
In order to get a peripheral to use the low-priority vector you have to clear the proper IP bit in the IRPx register since they are all high-priority be default.
It may be better to stop messing with the INTCON bits and use ENABLE HIGH/DISABLE HIGH/ENABLE LOW/DISABLE LOW scheme.
If you're talking about this portion:Note: Farther down the program, in part of the SERVO CODE there is INTCON.GIEH = 0/INTCON.GIEH = 1
INTCON.GIE = 0
ServoPos(i) = pos
INTCON.GIE = 1
If there's other code than what you've shown it's really hard to make any suggestions...This PIC reads the GPS and transfers it to the MASTER PIC via SPI, which has WHILE/WAITs in it's CODE,
Hi T,If you're talking about this portion:
That's there to disable interrupts around updating the ServoPos data array which is shared between the main program and the ISR. You could use DISABLE HIGH/ENABLE HIGH there, but it's ok the way it is.Code:INTCON.GIE = 0 ServoPos(i) = pos INTCON.GIE = 1
If there's other code than what you've shown it's really hard to make any suggestions...
I can appreciate that, but when you're talking about a program stalling/failing to work properly then you need to see ALL the code. Seemingly the problem occurs when you add in the portion you've not included here....and I've been told many times not to post FULL programs as they're too long,
Probably so. It's easy to imagine the SPI transfer code changing all the timing.I'm investigating my findings in #315, as I think I'm on the right track.
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?