Strange behavior on PORTB on a PIC18F26K20



THE BOOK of DT's INTERRUPTS is an organization of interrupt service routines and other works written by Darrel Taylor, RIP.

Interrupt routines are arranged per Darrel's original list. Darrel Taylor's Instant Interrupts are an extension of the work of Tim Box whom in October of 2002 wrote INT_CTRL.pbp

Many of the forum members felt this is a long overdue project.

THE BOOK of DT's INTERRUPTS
will be a valuable resource and a tribute to Darrel Taylor the "Fanatical Contributor".

THE BOOK of DT's INTERRUPTS is located at http://dt.picbasic.co.uk/

+ Reply to Thread
Results 1 to 8 of 8
  1. #1
    Join Date
    Sep 2016
    Posts
    3

    Default Strange behavior on PORTB on a PIC18F26K20

    Greetings everyone, this will be my first post on this forum (please be gentle).

    I'm hoping someone can give me some insight into what's causing a weird behavior in a test circuit I've been using on a PIC I've been introducing myself to recently.

    The PIC in question is a PIC18F26K20.
    Using PBP3, PBPX 3.0.7.4 on MicroCode Studio v5.0.0.5.

    As a test, I've hooked up a few LEDs directly to PortB.0, .1, .2, and .3 (pins 21-24), with nothing else but the normal stuff (2x ground, 1x +5VDC, 4700ohm resistor on pin 1, and the data and clock pins hooked up to my PICKit3. Genuine PICKit3.

    What the test program should do is simply flash each LED one at a time, with a 500ms delay during each LEDs lit phase. Only one LED is lit at any time. Simple enough.

    Just to clarify, I've already configured the GPIO as outputs (DDR) with the TRISB = 000000 statement, set those pins as digital with the ANSELH = 000000 statement just to be sure (I don't think this was actually necessary), and set up aliases for those pins, renaming them led1, led2, led3, and led4.

    Here's where the weirdness starts:

    Normally, I change pin states to high or low with a statement such as PORTB.0 = 1 and PORTB.0 = 0, and usually use an alias for the pin name. This has always worked well for me in the past.

    This time, and only for PortB, and only when operating at 20 MHz, it won't cycle through the LEDs properly unless I use the HIGH and LOW PBP commands.

    What it does instead is light up each of the first three LEDs (PortB.0, .1, and .2) at the appropriate times, but never turns any of them off. The fourth LED (PortB.3) works as it should.

    If I move everything to PortC, including the DDR preset, etc. just as I had set up for PortB, it works fine.
    If I change the defined OSC from 20 to 4 and replace the 20MHz resonator with a 4MHz resonator, it works fine (this one really surprised me).
    If I add a second PORTB.0 = 0 immediately after the intended PORTB.0 = 0 statement, it works fine (yes, this is two identical commands as if I'm telling the port to do it twice in a row).
    If I use LOW PORTB.0, it works fine.

    So it seems to be something going on with the first three pins on PortB that is requiring the strange workarounds in the code. Some pretty strange workarounds, it seems to me. I do notice that the pins affected are all INT pins. So I tried disabling Interrupts entirely with both the DISABLE and INTCON.7 = 0 commands, to no effect. I admit I don't currently know much about interrupts, as I've never needed to use them before, although I think this may have been a red herring. I could be wrong, but don't you have to intentionally enable interrupts to use them, so both of these commands are pointless without specifically turning the interrupts on?

    I can work around it by changing my coding convention, but I'd really like to know what's going on that's causing the difference in behavior.

    Can anyone shed some light on this for me?

    Thanks,
    Dos



    Note: Please excuse the crudity of this code, it's something I threw together one night as a quick test of the new PIC. The Serial LCD and buttons are not currently connected to the breadboard, but the code relevant to them has been left in the program.

    Code:
    '****************************************************************
    '*  Name    : 18F26K20test.PBP                                  *
    '*  Author  : *************                                     *
    '*  Notice  : Copyright (c) 2016 *************                  *
    '*          : All Rights Reserved                               *
    '*  Date    : 7/31/2016                                         *
    '*  Version : 1.0                                               *
    '*  Notes   : PIC18F26K20 - Test                                *
    '*          :                                                   *
    '****************************************************************
    
    #MSG "Compiling code for " + __PROCESSOR__
    
    ' Device fuses configuration - PIC18F26K20
    #CONFIG
        CONFIG  FOSC = HS             ; HS oscillator
        CONFIG  FCMEN = OFF           ; Fail-Safe Clock Monitor disabled
        CONFIG  IESO = OFF            ; Oscillator Switchover mode disabled
        CONFIG  PWRT = OFF            ; PWRT disabled
        CONFIG  BOREN = SBORDIS       ; Brown-out Reset enabled in hardware only (SBOREN is disabled)
        CONFIG  BORV = 18             ; VBOR set to 1.8 V nominal
        CONFIG  WDTEN = ON            ; WDT is always enabled. SWDTEN bit has no effect
        CONFIG  WDTPS = 512           ; 1:512
        CONFIG  CCP2MX = PORTC        ; CCP2 input/output is multiplexed with RC1
        CONFIG  PBADEN = OFF          ; PORTB<4:0> pins are configured as digital I/O on Reset
        CONFIG  LPT1OSC = OFF         ; Timer1 configured for higher power operation
        CONFIG  HFOFST = ON           ; HFINTOSC starts clocking the CPU without waiting for the oscillator to stablize.
        CONFIG  MCLRE = ON            ; MCLR pin enabled; RE3 input pin disabled
        CONFIG  STVREN = ON           ; Stack full/underflow will cause Reset
        CONFIG  LVP = OFF             ; Single-Supply ICSP disabled
        CONFIG  XINST = OFF           ; Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
        CONFIG  DEBUG = OFF           ; Background debugger disabled, RB6 and RB7 configured as general purpose I/O pins
        CONFIG  CP0 = OFF             ; Block 0 (000800-003FFFh) not code-protected
        CONFIG  CP1 = OFF             ; Block 1 (004000-007FFFh) not code-protected
        CONFIG  CP2 = OFF             ; Block 2 (008000-00BFFFh) not code-protected
        CONFIG  CP3 = OFF             ; Block 3 (00C000-00FFFFh) not code-protected
        CONFIG  CPB = OFF             ; Boot block (000000-0007FFh) not code-protected
        CONFIG  CPD = OFF             ; Data EEPROM not code-protected
        CONFIG  WRT0 = OFF            ; Block 0 (000800-003FFFh) not write-protected
        CONFIG  WRT1 = OFF            ; Block 1 (004000-007FFFh) not write-protected
        CONFIG  WRT2 = OFF            ; Block 2 (008000-00BFFFh) not write-protected
        CONFIG  WRT3 = OFF            ; Block 3 (00C000h-00FFFFh) not write-protected
        CONFIG  WRTC = OFF            ; Configuration registers (300000-3000FFh) not write-protected
        CONFIG  WRTB = OFF            ; Boot Block (000000-0007FFh) not write-protected
        CONFIG  WRTD = OFF            ; Data EEPROM not write-protected
        CONFIG  EBTR0 = OFF           ; Block 0 (000800-003FFFh) not protected from table reads executed in other blocks
        CONFIG  EBTR1 = OFF           ; Block 1 (004000-007FFFh) not protected from table reads executed in other blocks
        CONFIG  EBTR2 = OFF           ; Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks
        CONFIG  EBTR3 = OFF           ; Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks
        CONFIG  EBTRB = OFF           ; Boot Block (000000-0007FFh) not protected from table reads executed in other blocks
    
    #ENDCONFIG
    
    define OSC  20   ' Using 20Mhz oscillator - remember to change fuse to HS
    INCLUDE "bs2defs.bas"
    
    restart:
    
    TRISA     =    011111  ' Set 0-4 pins on PortA to inputs, 5-7 pins to outputs
    TRISB     =    000000  ' Set all pins on PortB to outputs
    TRISC   =   000000  ' Set all pins on PortC to outputs
    
    ANSEL  = 000000  ' Make AN0 - AN7 Digital (pins RA0, RA1, RA2, RA3, RA5 on PIC18F26K20)
    ANSELH = 000000  ' Make AN8 - AN15 Digital (pins RB2, RB3, RB1, RB4, RB0 on PIC18F26K20)
    
    ' Set all pins low to reset any pins that went high due to device connection
    PORTA = 0                   ' Set all pins on PORTA low
    PORTB = 0                   ' Set all pins on PORTB low
    PORTC = 0
    
    ' Port alias setup
    led1 var PORTB.0
    led2 VAR PORTB.1
    led3 VAR PORTB.2
    led4 VAR PORTB.3
    lcd  var PORTB.4      ' Serial output to LCD
    btnr var PORTA.0      ' Right arrow button
    btns vAR PORTA.1      ' Select button
    btnu var PORTA.2      ' Up arrow button
    btnl var PORTA.3      ' Left arrow button
    btnd var PORTA.4      ' Down arrow button
    
    ' Variable declaration
    
    start:
    
    SerOut lcd,N9600,[254,1] ' Clear LCD screen
    Pause 1
    
    goto ledanims
    
    mainloop:
    ' For now, as a test of the buttons, just send a test string to the LCD
    ' After this is proven, send different texts (bluetooth, PIC to PIC, wordlength, etc.)
    if btnr = 1 then btnrgt
    if btns = 1 then btnsel
    if btnu = 1 then btnup
    if btnl = 1 then btnlft
    if btnd = 1 then btndwn
    
    goto mainloop
    
    ' ----------------------------------------------------------------------------
    
    btnrgt:
    SerOut lcd,N9600,[254,1] ' Clear LCD screen
    Pause 1
    serout lcd,N9600,["Right button"]
    pause 500
    goto start
    
    btnsel:
    SerOut lcd,N9600,[254,1] ' Clear LCD screen
    Pause 1
    serout lcd,N9600,["Select button"]
    pause 500
    goto start
    
    btnup:
    SerOut lcd,N9600,[254,1] ' Clear LCD screen
    Pause 1
    serout lcd,N9600,["Up button"]
    pause 500
    goto start
    
    btnlft:
    SerOut lcd,N9600,[254,1] ' Clear LCD screen
    Pause 1
    serout lcd,N9600,["Left button"]
    pause 500
    goto start
    
    btndwn:
    SerOut lcd,N9600,[254,1] ' Clear LCD screen
    Pause 1
    serout lcd,N9600,["Down button"]
    pause 500
    goto start
    
    
    ' ============================================================================
    
    ledanims:
    
    'high PORTB.0
    'PORTB.0 = 1
    led1 = 1
    pause 500
    led1 = 0
    'led1 = 0                        ' <--- If I add this back in, this pin works correctly
    'PORTB.0 = 0
    'low PORTB.0                  ' <--- This statement does the job by itself
    
    'high PORTB.1
    'PORTB.1 = 1
    led2 = 1
    pause 500
    'led2 = 0
    'led2 = 0
    PORTB.1 = 0
    'PORTB.1 = 0
    'low PORTB.1
    
    'high PORTB.2
    'PORTB.2 = 1
    led3 = 1
    pause 500
    led3 = 0
    'PORTB.2 = 0
    'low PORTB.2
    
    'high PORTB.3
    'PORTB.3 = 1
    led4 = 1
    pause 500
    led4 = 0
    'PORTB.3 = 0
    'low PORTB.3
    
    goto ledanims
    Last edited by Dosbomber; - 28th September 2016 at 03:40. Reason: Added notes in code

  2. #2
    Join Date
    May 2013
    Location
    australia
    Posts
    2,118


    Did you find this post helpful? Yes | No

    Default Re: Strange behavior on PORTB on a PIC18F26K20

    looks like the classic read modify write issue
    check out this video for an explaination [View streaming media version: link]
    http://www.microchip.com/webinars.mi...cName=en556253
    Warning I'm not a teacher

  3. #3
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,421


    Did you find this post helpful? Yes | No

    Default Re: Strange behavior on PORTB on a PIC18F26K20

    It looks like you're missing the % in front of all numbers that are to be interpreted as binary by the compiler (or is that just the forum engine dropping that character (again)?)

    /Henrik.

  4. #4
    Join Date
    Apr 2011
    Location
    Kent, UK
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: Strange behavior on PORTB on a PIC18F26K20

    Try this. Use LAT instead of PORT for outputs. Inputs must use PORT!

    Tim.

    Code:
    '****************************************************************
    '*  Name    : 18F26K20test.PBP                                  *
    '*  Author  : *************                                     *
    '*  Notice  : Copyright (c) 2016 *************                  *
    '*          : All Rights Reserved                               *
    '*  Date    : 7/31/2016                                         *
    '*  Version : 1.0                                               *
    '*  Notes   : PIC18F26K20 - Test                                *
    '*          :                                                   *
    '****************************************************************
    
    #MSG "Compiling code for " + __PROCESSOR__
    
    ' Device fuses configuration - PIC18F26K20
    #CONFIG
        CONFIG  FOSC = HS             ; HS oscillator
        CONFIG  FCMEN = OFF           ; Fail-Safe Clock Monitor disabled
        CONFIG  IESO = OFF            ; Oscillator Switchover mode disabled
        CONFIG  PWRT = OFF            ; PWRT disabled
        CONFIG  BOREN = SBORDIS       ; Brown-out Reset enabled in hardware only (SBOREN is disabled)
        CONFIG  BORV = 18             ; VBOR set to 1.8 V nominal
        CONFIG  WDTEN = ON            ; WDT is always enabled. SWDTEN bit has no effect
        CONFIG  WDTPS = 512           ; 1:512
        CONFIG  CCP2MX = PORTC        ; CCP2 input/output is multiplexed with RC1
        CONFIG  PBADEN = OFF          ; PORTB<4:0> pins are configured as digital I/O on Reset
        CONFIG  LPT1OSC = OFF         ; Timer1 configured for higher power operation
        CONFIG  HFOFST = ON           ; HFINTOSC starts clocking the CPU without waiting for the oscillator to stablize.
        CONFIG  MCLRE = ON            ; MCLR pin enabled; RE3 input pin disabled
        CONFIG  STVREN = ON           ; Stack full/underflow will cause Reset
        CONFIG  LVP = OFF             ; Single-Supply ICSP disabled
        CONFIG  XINST = OFF           ; Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
        CONFIG  DEBUG = OFF           ; Background debugger disabled, RB6 and RB7 configured as general purpose I/O pins
        CONFIG  CP0 = OFF             ; Block 0 (000800-003FFFh) not code-protected
        CONFIG  CP1 = OFF             ; Block 1 (004000-007FFFh) not code-protected
        CONFIG  CP2 = OFF             ; Block 2 (008000-00BFFFh) not code-protected
        CONFIG  CP3 = OFF             ; Block 3 (00C000-00FFFFh) not code-protected
        CONFIG  CPB = OFF             ; Boot block (000000-0007FFh) not code-protected
        CONFIG  CPD = OFF             ; Data EEPROM not code-protected
        CONFIG  WRT0 = OFF            ; Block 0 (000800-003FFFh) not write-protected
        CONFIG  WRT1 = OFF            ; Block 1 (004000-007FFFh) not write-protected
        CONFIG  WRT2 = OFF            ; Block 2 (008000-00BFFFh) not write-protected
        CONFIG  WRT3 = OFF            ; Block 3 (00C000h-00FFFFh) not write-protected
        CONFIG  WRTC = OFF            ; Configuration registers (300000-3000FFh) not write-protected
        CONFIG  WRTB = OFF            ; Boot Block (000000-0007FFh) not write-protected
        CONFIG  WRTD = OFF            ; Data EEPROM not write-protected
        CONFIG  EBTR0 = OFF           ; Block 0 (000800-003FFFh) not protected from table reads executed in other blocks
        CONFIG  EBTR1 = OFF           ; Block 1 (004000-007FFFh) not protected from table reads executed in other blocks
        CONFIG  EBTR2 = OFF           ; Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks
        CONFIG  EBTR3 = OFF           ; Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks
        CONFIG  EBTRB = OFF           ; Boot Block (000000-0007FFh) not protected from table reads executed in other blocks
    
    #ENDCONFIG
    
    define OSC  20   ' Using 20Mhz oscillator - remember to change fuse to HS
    INCLUDE "bs2defs.bas"
    
    restart:
    
    TRISA     =    %011111  ' Set 0-4 pins on PortA to inputs, 5-7 pins to outputs
    TRISB     =    %000000  ' Set all pins on PortB to outputs
    TRISC   =   %000000  ' Set all pins on PortC to outputs
    
    ANSEL  = %000000  ' Make AN0 - AN7 Digital (pins RA0, RA1, RA2, RA3, RA5 on PIC18F26K20)
    ANSELH = %000000  ' Make AN8 - AN15 Digital (pins RB2, RB3, RB1, RB4, RB0 on PIC18F26K20)
    
    ' Set all pins low to reset any pins that went high due to device connection
    LATA = 0                   ' Set all pins on PORTA low
    LATB = 0                   ' Set all pins on PORTB low
    LATC = 0
    
    ' Port alias setup
    led1 var LATB.0
    led2 VAR LATB.1
    led3 VAR LATB.2
    led4 VAR LATB.3
    lcd  var LATB.4      ' Serial output to LCD
    btnr var PORTA.0      ' Right arrow button
    btns vAR PORTA.1      ' Select button
    btnu var PORTA.2      ' Up arrow button
    btnl var PORTA.3      ' Left arrow button
    btnd var PORTA.4      ' Down arrow button
    
    ' Variable declaration
    
    start:
    
    SerOut lcd,N9600,[254,1] ' Clear LCD screen
    Pause 1
    
    goto ledanims
    
    mainloop:
    ' For now, as a test of the buttons, just send a test string to the LCD
    ' After this is proven, send different texts (bluetooth, PIC to PIC, wordlength, etc.)
    if btnr = 1 then btnrgt
    if btns = 1 then btnsel
    if btnu = 1 then btnup
    if btnl = 1 then btnlft
    if btnd = 1 then btndwn
    
    goto mainloop
    
    ' ----------------------------------------------------------------------------
    
    btnrgt:
    SerOut lcd,N9600,[254,1] ' Clear LCD screen
    Pause 1
    serout lcd,N9600,["Right button"]
    pause 500
    goto start
    
    btnsel:
    SerOut lcd,N9600,[254,1] ' Clear LCD screen
    Pause 1
    serout lcd,N9600,["Select button"]
    pause 500
    goto start
    
    btnup:
    SerOut lcd,N9600,[254,1] ' Clear LCD screen
    Pause 1
    serout lcd,N9600,["Up button"]
    pause 500
    goto start
    
    btnlft:
    SerOut lcd,N9600,[254,1] ' Clear LCD screen
    Pause 1
    serout lcd,N9600,["Left button"]
    pause 500
    goto start
    
    btndwn:
    SerOut lcd,N9600,[254,1] ' Clear LCD screen
    Pause 1
    serout lcd,N9600,["Down button"]
    pause 500
    goto start
    
    
    ' ============================================================================
    
    ledanims:
    
    'high PORTB.0
    'PORTB.0 = 1
    led1 = 1
    pause 500
    led1 = 0
    'led1 = 0                        ' <--- If I add this back in, this pin works correctly
    'PORTB.0 = 0
    'low PORTB.0                  ' <--- This statement does the job by itself
    
    'high PORTB.1
    'PORTB.1 = 1
    led2 = 1
    pause 500
    'led2 = 0
    led2 = 0
    'PORTB.1 = 0
    'PORTB.1 = 0
    'low PORTB.1
    
    'high PORTB.2
    'PORTB.2 = 1
    led3 = 1
    pause 500
    led3 = 0
    'PORTB.2 = 0
    'low PORTB.2
    
    'high PORTB.3
    'PORTB.3 = 1
    led4 = 1
    pause 500
    led4 = 0
    'PORTB.3 = 0
    'low PORTB.3
    
    goto ledanims

  5. #5
    Join Date
    May 2013
    Location
    australia
    Posts
    2,118


    Did you find this post helpful? Yes | No

    Default Re: Strange behavior on PORTB on a PIC18F26K20

    there is some bad advise here

    lcd var LATB.4 ' Serial output to LCD ;THIS IS WRONG
    btnr var PORTA.0 ' Right arrow button
    btns vAR PORTA.1 ' Select button
    btnu var PORTA.2 ' Up arrow button
    btnl var PORTA.3 ' Left arrow button
    btnd var PORTA.4 ' Down arrow button

    ' Variable declaration

    start:

    SerOut lcd,N9600,[254,1] ' Clear LCD screen
    Pause 1


    use of LATx ports in "highlevel" commands is incorrect and will not work as expected
    lcd var PORTB.4 ' Serial output to LCD , IS CORRECT
    Warning I'm not a teacher

  6. #6
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,421


    Did you find this post helpful? Yes | No

    Default Re: Strange behavior on PORTB on a PIC18F26K20

    And there are still digits missing where binary representation is used to set the registers, which can be quite confusing.

  7. #7
    Join Date
    Sep 2016
    Posts
    3


    Did you find this post helpful? Yes | No

    Default Re: Strange behavior on PORTB on a PIC18F26K20

    Quote Originally Posted by HenrikOlsson View Post
    It looks like you're missing the % in front of all numbers that are to be interpreted as binary by the compiler (or is that just the forum engine dropping that character (again)?)

    /Henrik.
    They're in the code, they just didn't copy over into the forum copy/paste for some reason.

    Thanks for the reply,
    Dos

  8. #8
    Join Date
    Sep 2016
    Posts
    3


    Did you find this post helpful? Yes | No

    Default Re: Strange behavior on PORTB on a PIC18F26K20

    Quote Originally Posted by HenrikOlsson View Post
    And there are still digits missing where binary representation is used to set the registers, which can be quite confusing.
    If you're referring to the sets of 0's and 1's which would be immediately following the percentage sign, as a bank of 8 bits, there are 8 digits in the original code. I hadn't noticed that they got truncated to 6 digits in the paste... very interesting. Anyway yeah, that's another forum/paste glitch.

    Dos

    Code:
    TRISA     =    %00011111  ' Set 0-4 pins on PortA to inputs, 5-7 pins to outputs
    TRISB     =    %00000000  ' Set all pins on PortB to outputs
    TRISC   =   %00000000  ' Set all pins on PortC to outputs
    
    ANSEL  = %00000000  ' Make AN0 - AN7 Digital (pins RA0, RA1, RA2, RA3, RA5 on PIC18F26K20)
    ANSELH = %00000000  ' Make AN8 - AN15 Digital (pins RB2, RB3, RB1, RB4, RB0 on PIC18F26K20)

Similar Threads

  1. Strange Behavior 12F1822
    By nobner in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 3rd February 2012, 08:11
  2. Strange LCD Behavior
    By chips123 in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 1st November 2009, 00:48
  3. Strange behavior - PORTG.2, 18F8720
    By Charles Linquis in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 11th January 2009, 23:30
  4. Strange electrical behavior with PIC16F684
    By xnihilo in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 28th March 2008, 06:58
  5. 12F629 Strange interupt behavior
    By BGreen in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 25th May 2007, 15:35

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts