K-Series USART2 Shenanigans.

Discuss PIC and electronic related things

Moderators: David Barker, Jerry Messina

Post Reply
User avatar
Senacharim
Posts: 139
Joined: Tue Aug 10, 2010 5:19 pm
Location: Ventura, CA

K-Series USART2 Shenanigans.

Post by Senacharim » Tue Nov 22, 2011 8:03 pm

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.
Surviving Member
Bermuda Triangle Battalion
from 2026 to 1992

Voted "Most likely to time travel"--Class of 2024.

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Wed Nov 23, 2011 12:01 am

Well now, that's a strange one.

If you're not using interrupts, then I'd make sure I had all the latest device files.

Which usart modules are you using? Just USART.bas?

Also, check the errata for the 26K22. You might need BRGH=1 and BRG16 = 1 (probably unrelated, but worth a check).

User avatar
Senacharim
Posts: 139
Joined: Tue Aug 10, 2010 5:19 pm
Location: Ventura, CA

Post by Senacharim » Wed Nov 23, 2011 3:25 pm

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.
Surviving Member
Bermuda Triangle Battalion
from 2026 to 1992

Voted "Most likely to time travel"--Class of 2024.

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Wed Nov 23, 2011 3:59 pm

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.

User avatar
Senacharim
Posts: 139
Joined: Tue Aug 10, 2010 5:19 pm
Location: Ventura, CA

Post by Senacharim » Wed Nov 23, 2011 4:33 pm

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.
Surviving Member
Bermuda Triangle Battalion
from 2026 to 1992

Voted "Most likely to time travel"--Class of 2024.

User avatar
ohararp
Posts: 194
Joined: Tue Oct 03, 2006 11:29 pm
Location: Dayton, OH USA
Contact:

Post by ohararp » Wed Sep 05, 2012 1:57 pm

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 
Thanks Ryan
$25 SMT Stencils!!!
www.ohararp.com/Stencils.html

User avatar
David Barker
Swordfish Developer
Posts: 1214
Joined: Tue Oct 03, 2006 7:01 pm
Location: Saltburn by the Sea, UK
Contact:

Post by David Barker » Wed Sep 05, 2012 3:32 pm

I think USART2 is on PORTB for this device - check out the datasheet. Something like

Code: Select all

   #if _device in (18F26K22)
   RCInput As TRISB.Booleans(7),   
   TXInput As TRISB.Booleans(6)   
   #else
   ...
should work...

User avatar
ohararp
Posts: 194
Joined: Tue Oct 03, 2006 11:29 pm
Location: Dayton, OH USA
Contact:

Post by ohararp » Wed Sep 05, 2012 9:13 pm

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.
Thanks Ryan
$25 SMT Stencils!!!
www.ohararp.com/Stencils.html

User avatar
ohararp
Posts: 194
Joined: Tue Oct 03, 2006 11:29 pm
Location: Dayton, OH USA
Contact:

Post by ohararp » Wed Feb 06, 2013 5:53 am

I got to revisit this code and was able to get things up and running by using this:

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 
And modifying the section of the USART2:

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
Thanks Ryan
$25 SMT Stencils!!!
www.ohararp.com/Stencils.html

User avatar
ohararp
Posts: 194
Joined: Tue Oct 03, 2006 11:29 pm
Location: Dayton, OH USA
Contact:

Assign Char to String (FAIL)

Post by ohararp » Mon Aug 26, 2013 3:24 am

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.

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
Thanks Ryan
$25 SMT Stencils!!!
www.ohararp.com/Stencils.html

User avatar
David Barker
Swordfish Developer
Posts: 1214
Joined: Tue Oct 03, 2006 7:01 pm
Location: Saltburn by the Sea, UK
Contact:

Post by David Barker » Mon Aug 26, 2013 7:40 am

Possibly a buffer overrun. You have the result string as 128 bytes (127 chars + null) and IMU_RXBUFFER_LENGTH = 128. So

Code: Select all

ElseIf IMU_CHARPOS > IMU_RXBUFFER_LENGTH Then   ' Terminate reading
   RESULT(IMU_CHARPOS)= NULL' Null Terminate Line 
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.

User avatar
David Barker
Swordfish Developer
Posts: 1214
Joined: Tue Oct 03, 2006 7:01 pm
Location: Saltburn by the Sea, UK
Contact:

Post by David Barker » Mon Aug 26, 2013 4:56 pm

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.

User avatar
ohararp
Posts: 194
Joined: Tue Oct 03, 2006 11:29 pm
Location: Dayton, OH USA
Contact:

Post by ohararp » Tue Aug 27, 2013 2:51 am

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 -

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

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()
Thanks Ryan
$25 SMT Stencils!!!
www.ohararp.com/Stencils.html

Post Reply