K-Series USART2 Shenanigans.
Moderators: David Barker, Jerry Messina
- Senacharim
- Posts: 139
- Joined: Tue Aug 10, 2010 5:19 pm
- Location: Ventura, CA
K-Series USART2 Shenanigans.
Well, I'm working with a PIC18F26K22. This PIC was chosen specifically because it's nearly identical to the PIC18F2620 except it features two USARTs.
I'm getting an amazingly stupid intermittent error--sometimes when I compile the code I get it where input on USART1 raised the USART1.RCIF flag like and should and input on USART2 raises the USART2.RCIF flag like it should.
When this is the situation; sending data via USART2 is pointless, it will be generally mangled (for some stupid reason) before it ever reaches its destination.
Other times, input on USART1 raises the USART2.RCIF flag AND the USART1.RCIF flag (apparently) and input on USART2 doesn't do a damn thing. When this is the case, data sent via USART2 arrives pristine & clear to wherever it's being sent.
At present, this behaviour appears almost randomly. It'll be one way for awhile, and later when I've changed enough code, (breathed enough times, thought about fairies, I dunno what) it will switch behaviours.
Has anybody else encountered anything like this with a 2 USART PIC?
Was it ever resolved?
So, to sum up: HELP!
Regards,
Senacharim.
I'm getting an amazingly stupid intermittent error--sometimes when I compile the code I get it where input on USART1 raised the USART1.RCIF flag like and should and input on USART2 raises the USART2.RCIF flag like it should.
When this is the situation; sending data via USART2 is pointless, it will be generally mangled (for some stupid reason) before it ever reaches its destination.
Other times, input on USART1 raises the USART2.RCIF flag AND the USART1.RCIF flag (apparently) and input on USART2 doesn't do a damn thing. When this is the case, data sent via USART2 arrives pristine & clear to wherever it's being sent.
At present, this behaviour appears almost randomly. It'll be one way for awhile, and later when I've changed enough code, (breathed enough times, thought about fairies, I dunno what) it will switch behaviours.
Has anybody else encountered anything like this with a 2 USART PIC?
Was it ever resolved?
So, to sum up: HELP!
Regards,
Senacharim.
Surviving Member
Bermuda Triangle Battalion
from 2026 to 1992
Voted "Most likely to time travel"--Class of 2024.
Bermuda Triangle Battalion
from 2026 to 1992
Voted "Most likely to time travel"--Class of 2024.
-
- Swordfish Developer
- Posts: 1473
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
- Senacharim
- Posts: 139
- Joined: Tue Aug 10, 2010 5:19 pm
- Location: Ventura, CA
Oh, and to add to the weirdness, the behaviour is consistent regardless of baud rate (1200 to 57600) and oscillator speed (internal 1MHz to 16Mhz, PLL to 64MHz)--doesn't matter.
Results are the same and consistent in their inconsistency.
Results are the same and consistent in their inconsistency.
Surviving Member
Bermuda Triangle Battalion
from 2026 to 1992
Voted "Most likely to time travel"--Class of 2024.
Bermuda Triangle Battalion
from 2026 to 1992
Voted "Most likely to time travel"--Class of 2024.
-
- Swordfish Developer
- Posts: 1473
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
AFAIK, there's nothing wrong with the 26K22.
The usart libs might need a little tweaking for that chip. For example, USART2.bas would have the wrong pins defined. Also, make sure you've got the analog functions for those pins turned off.
Without some code to look at, it's sort of hard to say what you're seeing.
The usart libs might need a little tweaking for that chip. For example, USART2.bas would have the wrong pins defined. Also, make sure you've got the analog functions for those pins turned off.
Without some code to look at, it's sort of hard to say what you're seeing.
- Senacharim
- Posts: 139
- Joined: Tue Aug 10, 2010 5:19 pm
- Location: Ventura, CA
Using slightly modified USART.bas & USART2.bas, primarily in that I added necessary #defines to account for the PIC18F26K22 pins, TRIS, and ANSEL.
Have been using these chips in various (single USART) applications previously with nary a whiff of difficulty, it's only now I'm getting this when attempting to get 2 USARTs working in harmony.
I've been poring over the docs & errata from Microchip--I do have the BRGH=1 and BRG16 = 1 on both USARTs which is stated as necessary in the errata. Setting the TRIS & ANSEL for the pins negates the possibility of it accidentally being configured to analog...
Time permitting, I'll cull appropriate bits of code and post them.
Thanks for the replies--if I do discover the cause, I'll be certain to post it so others may learn from this.
Edit: I'm debating attempting to use interrupts for one/both USARTs. Primarily in desperation, as I'm solidly running out of ideas and things to troubleshoot.
Have been using these chips in various (single USART) applications previously with nary a whiff of difficulty, it's only now I'm getting this when attempting to get 2 USARTs working in harmony.
I've been poring over the docs & errata from Microchip--I do have the BRGH=1 and BRG16 = 1 on both USARTs which is stated as necessary in the errata. Setting the TRIS & ANSEL for the pins negates the possibility of it accidentally being configured to analog...
Time permitting, I'll cull appropriate bits of code and post them.
Thanks for the replies--if I do discover the cause, I'll be certain to post it so others may learn from this.
Edit: I'm debating attempting to use interrupts for one/both USARTs. Primarily in desperation, as I'm solidly running out of ideas and things to troubleshoot.
Surviving Member
Bermuda Triangle Battalion
from 2026 to 1992
Voted "Most likely to time travel"--Class of 2024.
Bermuda Triangle Battalion
from 2026 to 1992
Voted "Most likely to time travel"--Class of 2024.
Gentlemen, I am using the 18F26K22 and trying to get the USART2 up and running now that the SD card stuff is working. Any chance you know the settings to get the UART.bas code up and running? A simple hello world is presented below. I am getting "invalid variable types associated with the USART2.bas lines:
Code: Select all
RCInput As TRISG.Booleans(2), // as TRISG (2)
TXInput As TRISG.Booleans(1) // as TRISG (1)
Code: Select all
{
*****************************************************************************
* Name : UNTITLED.BAS *
* Author : [select VIEW...EDITOR OPTIONS] *
* Notice : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
* : All Rights Reserved *
* Date : 6/20/2011 *
* Version : 1.0 *
* Notes : *
* : *
*****************************************************************************
}
// DEVICE AND CLOCK
Device = 18F26K22
Clock = 64
Config
FOSC = HSHP , 'EC oscillator (medium power, 4-16 MHz)
PLLCFG = ON , 'Oscillator used directly
PRICLKEN = OFF , 'Primary Clock enabled
FCMEN = OFF , 'Fail-Safe Clock Monitor disabled
IESO = OFF , 'Oscillator Switchover mode disabled
PWRTEN = OFF , 'Power up timer disabled
BOREN = SBORDIS , 'Brown-out Reset enabled in hardware only (SBOREN is disabled)
BORV = 190 , 'VBOR set To 1.90 V nominal
WDTEN = OFF , 'Watch dog timer is always disabled. SWDTEN has no effect.
WDTPS = 256 , '1:256
CCP2MX = PORTC1 , 'CCP2 Input/Output is multiplexed With RC1
PBADEN = OFF , 'PORTB<5:0> pins are configured As digital I/O on Reset
CCP3MX = PORTB5 , 'P3A/CCP3 Input/Output is multiplexed With RB5
HFOFST = On , 'HFINTOSC Output And ready status are Not delayed by the oscillator stable status
T3CMX = PORTC0 , 'T3CKI is on RC0
P2BMX = PORTB5 , 'P2B is on RB5
MCLRE = EXTMCLR , 'MCLR pin enabled, RE3 Input pin disabled
STVREN = On , 'Stack full/underflow will cause Reset
LVP = On , 'Single-Supply ICSP enabled If MCLRE is also 1
XINST = OFF , 'Instruction set extension And Indexed Addressing mode disabled (Legacy mode)
Debug = OFF , 'Disabled
CP0 = OFF , 'Block 0 (000800-003FFFh) Not code-protected
CP1 = OFF , 'Block 1 (004000-007FFFh) Not code-protected
CP2 = OFF , 'Block 2 (008000-00BFFFh) Not code-protected
CP3 = OFF , 'Block 3 (00C000-00FFFFh) Not code-protected
CPB = OFF , 'Boot block (000000-0007FFh) Not code-protected
CPD = OFF , 'Data EEPROM Not code-protected
WRT0 = OFF , 'Block 0 (000800-003FFFh) Not write-protected
WRT1 = OFF , 'Block 1 (004000-007FFFh) Not write-protected
WRT2 = OFF , 'Block 2 (008000-00BFFFh) Not write-protected
WRT3 = OFF , 'Block 3 (00C000-00FFFFh) Not write-protected
WRTC = OFF , 'Configuration registers (300000-3000FFh) Not write-protected
WRTB = OFF , 'Boot Block (000000-0007FFh) Not write-protected
WRTD = OFF , 'Data EEPROM Not write-protected
EBTR0 = OFF , 'Block 0 (000800-003FFFh) Not protected from table reads executed in other blocks
EBTR1 = OFF , 'Block 1 (004000-007FFFh) Not protected from table reads executed in other blocks
EBTR2 = OFF , 'Block 2 (008000-00BFFFh) Not protected from table reads executed in other blocks
EBTR3 = OFF , 'Block 3 (00C000-00FFFFh) Not protected from table reads executed in other blocks
EBTRB = OFF 'Boot Block (000000-0007FFh) Not protected from table reads executed in other blocks
// INCLUDES
Include "Convert.bas"
Include "options.bas"
Include "USART.bas"
Include "USART2.bas"
Include "SUART.bas"
Include "String.bas"
//OPTIONS
#option USART_BAUDRATE = 38400
#option USART2_BAUDRATE = 38400
#option WDT = True
//******************************************************************************
While TRUE
USART.Write("HELLO WORLD",13,10)
USART2.Write("HELLO WORLD",13,10)
DelayMS(200)
Wend
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
I think USART2 is on PORTB for this device - check out the datasheet. Something like
should work...
Code: Select all
#if _device in (18F26K22)
RCInput As TRISB.Booleans(7),
TXInput As TRISB.Booleans(6)
#else
...
David, this was a super easy fix. I work with mostly 28-40 pin parts and hadn't seen the TRISG stuff. I feel kinda silly now that you pointed this out. So far it works a treat.
Edit: So this will allow the compiler to compile but when I try and program the code I get a no-go. Seems to just stall or not run on the micro. Real weird. I'll have to dig deeper on this one.
Edit: So this will allow the compiler to compile but when I try and program the code I get a no-go. Seems to just stall or not run on the micro. Real weird. I'll have to dig deeper on this one.
I got to revisit this code and was able to get things up and running by using this:
And modifying the section of the USART2:
Code: Select all
{
*****************************************************************************
* Name : UNTITLED.BAS *
* Author : [select VIEW...EDITOR OPTIONS] *
* Notice : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
* : All Rights Reserved *
* Date : 6/20/2011 *
* Version : 1.0 *
* Notes : *
* : *
*****************************************************************************
}
// DEVICE AND CLOCK
Device = 18F26K22
Clock = 64
Config
FOSC = HSMP , 'EC oscillator (medium power, 4-16 MHz)
PLLCFG = ON , 'Oscillator used directly
PRICLKEN = OFF , 'Primary Clock enabled
FCMEN = OFF , 'Fail-Safe Clock Monitor disabled
IESO = OFF , 'Oscillator Switchover mode disabled
PWRTEN = OFF , 'Power up timer disabled
BOREN = SBORDIS , 'Brown-out Reset enabled in hardware only (SBOREN is disabled)
BORV = 190 , 'VBOR set To 1.90 V nominal
WDTEN = OFF , 'Watch dog timer is always disabled. SWDTEN has no effect.
WDTPS = 256 , '1:256
CCP2MX = PORTC1 , 'CCP2 Input/Output is multiplexed With RC1
PBADEN = OFF , 'PORTB<5:0> pins are configured As digital I/O on Reset
CCP3MX = PORTB5 , 'P3A/CCP3 Input/Output is multiplexed With RB5
HFOFST = On , 'HFINTOSC Output And ready status are Not delayed by the oscillator stable status
T3CMX = PORTC0 , 'T3CKI is on RC0
P2BMX = PORTB5 , 'P2B is on RB5
MCLRE = EXTMCLR , 'MCLR pin enabled, RE3 Input pin disabled
STVREN = On , 'Stack full/underflow will cause Reset
LVP = On , 'Single-Supply ICSP enabled If MCLRE is also 1
XINST = OFF , 'Instruction set extension And Indexed Addressing mode disabled (Legacy mode)
Debug = OFF , 'Disabled
CP0 = OFF , 'Block 0 (000800-003FFFh) Not code-protected
CP1 = OFF , 'Block 1 (004000-007FFFh) Not code-protected
CP2 = OFF , 'Block 2 (008000-00BFFFh) Not code-protected
CP3 = OFF , 'Block 3 (00C000-00FFFFh) Not code-protected
CPB = OFF , 'Boot block (000000-0007FFh) Not code-protected
CPD = OFF , 'Data EEPROM Not code-protected
WRT0 = OFF , 'Block 0 (000800-003FFFh) Not write-protected
WRT1 = OFF , 'Block 1 (004000-007FFFh) Not write-protected
WRT2 = OFF , 'Block 2 (008000-00BFFFh) Not write-protected
WRT3 = OFF , 'Block 3 (00C000-00FFFFh) Not write-protected
WRTC = OFF , 'Configuration registers (300000-3000FFh) Not write-protected
WRTB = OFF , 'Boot Block (000000-0007FFh) Not write-protected
WRTD = OFF , 'Data EEPROM Not write-protected
EBTR0 = OFF , 'Block 0 (000800-003FFFh) Not protected from table reads executed in other blocks
EBTR1 = OFF , 'Block 1 (004000-007FFFh) Not protected from table reads executed in other blocks
EBTR2 = OFF , 'Block 2 (008000-00BFFFh) Not protected from table reads executed in other blocks
EBTR3 = OFF , 'Block 3 (00C000-00FFFFh) Not protected from table reads executed in other blocks
EBTRB = OFF 'Boot Block (000000-0007FFh) Not protected from table reads executed in other blocks
// INCLUDES
Include "Convert.bas"
Include "options.bas"
Include "USART.bas"
Include "USART2.bas"
Include "String.bas"
'Include "SetDigitalIO.bas"
//OPTIONS
#option USART_BAUDRATE = 38400
#option USART_BRGH = true
#option USART_BRGH16 = true
#option USART2_BAUDRATE = 38400
#option USART2_BRGH = true
#option USART2_BRGH16 = true
Dim LED_BLUE As PORTB.2
Dim LED_GRN As PORTB.3
Dim LED_RED As PORTB.4
'SetAllDigital()
'Configure Software UART for Debugging
Sub Init()
'HSERIAL = 38400 BAUD
USART.SetBaudrate(br38400)
USART2.SetBaudrate(br38400)
End Sub
//******************************************************************************
Init()
While TRUE
USART.Write("HARDWARE UART",13,10)
USART2.Write("HARDWARE2 UART",13,10)
Toggle(LED_BLUE)
DelayMS(200)
Wend
Code: Select all
// MCU has more than one USART...
#else
Public Dim // -> USART2
#if USART2_BRG16
SPBRGRegister As SPBRG2.AsWord,
BRG16 As BAUDCON2.3,
#else
SPBRGRegister As SPBRG2,
#endif
RCRegister As RCREG2, // as RCREG2
TXRegister As TXREG2, // as TXREG2
RCStatus As RCSTA2, // as TXSTA2
TXStatus As TXSTA2, // as TXSTA2
#if _device in (18F26K22)
RCInput As TRISB.Booleans(7),
TXInput As TRISB.Booleans(6)
#else
RCInput As TRISG.Booleans(2), // as TRISG (2)
TXInput As TRISG.Booleans(1) // as TRISG (1)
#endif
#endif
Assign Char to String (FAIL)
Gentlemen, I am using the code below to read USART2 data. I had this code working very well and then deployed some units to a customer and everything went to pot.
Basically I am reading an ascii string of floating point data. It's very similar to NMEA data and the code below is derived from a NMEA processing code that I have used with good success.
The trouble I am getting is that I can read a character using ReadByte, but am having trouble assigning the Char to a string array (RESULT).
I know the code is reading the data and not timing out. I also have a "character index" that is being incremented. But when I print out the character index and resulting character array the index prints, but not the actual data. It's like it's magically lost!
Any help is appreciated. I have been upside and inside out swapping chips, changing code, refining etc. I know the IMU I am using is pumping out 3.3V TTL data no problem (tested with MCP2200 and Scope). The really weird thing is that up until a few days ago the code was working fine. No MPLAB or compiler changes since.
Basically I am reading an ascii string of floating point data. It's very similar to NMEA data and the code below is derived from a NMEA processing code that I have used with good success.
The trouble I am getting is that I can read a character using ReadByte, but am having trouble assigning the Char to a string array (RESULT).
I know the code is reading the data and not timing out. I also have a "character index" that is being incremented. But when I print out the character index and resulting character array the index prints, but not the actual data. It's like it's magically lost!
Any help is appreciated. I have been upside and inside out swapping chips, changing code, refining etc. I know the IMU I am using is pumping out 3.3V TTL data no problem (tested with MCP2200 and Scope). The really weird thing is that up until a few days ago the code was working fine. No MPLAB or compiler changes since.
Code: Select all
Function IMU_SENTENCE(IMU_CMD As Byte) As String * 128
Dim IMU_CHAR As Char
Dim IMU_CHARPOS As Byte
Dim IMU_RXBUFFER_LENGTH As Byte
IMU_RXBUFFER_LENGTH = 128
USART2.Write(58,DecToStr(IMU_CMD),10) 'Send Spec'd Command Byte to IMU
If USART2.DataAvailableTimeout(1000) = True Then 'Timeout Call
IMU_CHARPOS = 0
While True ' Create a loop to receive the serial string
IMU_CHAR = USART2.ReadByte() ' Receive a character serially
'USART.Write(IMU_CHAR)
RESULT(IMU_CHARPOS) = IMU_CHAR ' Store Character
If IMU_CHAR = #10 Then 'End with Line Feed
RESULT(IMU_CHARPOS)= NULL 'Null Terminate Line
Break ' Exit the loop if the string reaches the end
ElseIf IMU_CHARPOS > IMU_RXBUFFER_LENGTH Then ' Terminate reading
RESULT(IMU_CHARPOS)= NULL' Null Terminate Line
Break ' Repeat the loop until the buffer runs out
EndIf
Inc(IMU_CHARPOS) ' Increment the index
Wend
USART.Write(42,DecToStr(IMU_CHARPOS),RESULT())
Else
RESULT = "No Data"
USART.Write("IMU TIMEOUT",RESULT,13,10)
BLINK3(LED_RED,LED_GRN,LED_BLU,3)
EndIf
End Function
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
Possibly a buffer overrun. You have the result string as 128 bytes (127 chars + null) and IMU_RXBUFFER_LENGTH = 128. So
looks like you are putting a null at 129 - this means the last character and null terminator may get overwritten. Such an error is likely to give erratic and unpredictable results.
Code: Select all
ElseIf IMU_CHARPOS > IMU_RXBUFFER_LENGTH Then ' Terminate reading
RESULT(IMU_CHARPOS)= NULL' Null Terminate Line
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
Ryan
You need to correct the problems outlined above, but I would also recommend running an update to correct a problem outlined here:
http://www.sfcompiler.co.uk/forum/viewtopic.php?t=1769
just in case.
You need to correct the problems outlined above, but I would also recommend running an update to correct a problem outlined here:
http://www.sfcompiler.co.uk/forum/viewtopic.php?t=1769
just in case.
David, thanks for catching the 128 byte error. I fixed that (code didn't reflow, but it could have).
Turns out it was something alot simpler. Basically USART2 for this chip sets the TRISB.6 and 7 bits to 1. I had an interrupt declaration that was resetting the bits.
Bad Code -
Good Code - I moved the UART2 declare after the interrupt and set only the bit I was concerned about in the interrupt rather than all the bits. I knew the problem was something obvious, but was baffled why it didn't rear its ugly head until after a pcb revision.
Turns out it was something alot simpler. Basically USART2 for this chip sets the TRISB.6 and 7 bits to 1. I had an interrupt declaration that was resetting the bits.
Bad Code -
Code: Select all
'SET DECLARE VARIABLES
TRISB = %0000001 'Set RB0 to inputs
INTEDG0 = 1 'Set External Interrupt Edge to rising edge
INT0IP = 1 'Set INT0 - RB0 as a High priority interrupt
INT0IF = 0 'Clear RB0 INT Flag
If VIBED > 0 Then
INT0IE = 1 'Enable External RB0 Interrupt
Else
INT0IE = 0 'Disable External RB0 Interrupt
EndIf
Code: Select all
'SET DECLARE VARIABLES
TRISB.0 = 1 'Set RB0 to inputs
INTEDG0 = 1 'Set External Interrupt Edge to rising edge
INT0IP = 1 'Set INT0 - RB0 as a High priority interrupt
INT0IF = 0 'Clear RB0 INT Flag
If VIBED > 0 Then
INT0IE = 1 'Enable External RB0 Interrupt
Else
INT0IE = 0 'Disable External RB0 Interrupt
EndIf
'HSERIAL = 57600 BAUD
USART2.SetBaudrate(br57600)
RCSTA2 = $90 ' Enable serial port & continuous receive
TXSTA2 = $24 ' Enable transmit, BRGH = 1
SPBRG2 = 21 ' 57600 Baud @ -0.08%
SPBRGH2 = 1
BAUDCON2.3 = 1 ' Enable 16 bit baudrate generator
DelayMS(1000)
IMU_RESET()