News:

Let's find out together what makes a PIC Tick!

Main Menu

Trouble with toggle PORTA.2

Started by midali, Sep 17, 2024, 02:02 PM

Previous topic - Next topic

midali

Hello,

I have a trouble with toggle PORTA.2 an 16F1703 . The PORTA.2 remaining always ON. Any other ports work .Here is a code :

Device = 16F1703

Config1 FOSC_INTOSC, WDTE_OFF, PWRTE_OFF, MCLRE_OFF, CP_ON, BOREN_OFF, CLKOUTEN_OFF
Config2 WRT_OFF, PPS1WAY_OFF, ZCDDIS_OFF, PLLEN_OFF, STVREN_OFF, BORV_LO, LPBOR_OFF, LVP_OFF

Declare Xtal =  4
OSCCON  = %01101010   'sets the internal oscillator to 4Mhz
;-------------------------------------------------------------------------------
 
Declare  CCP2_Pin   = PORTC.3
Declare  CCP1_Pin   = PORTC.5

TRISA  = %00000001
TRISC  = %00000000
ANSELA = %00000001
ANSELC = %00000000
PORTA  = 0
PORTC  = 0

Symbol vm     =  PORTA.2

'-------------------PROGRAM----------------------
While
    Toggle vm
    DelayMS 500
Wend



If I use high and low PORTA.2 , its working .
'-------------------PROGRAM----------------------
While
    High vm
    DelayMS 500
    Low vm
    DelayMS 500
Wend


Its something wrong in my code or its a bug in the compiler ?

Thank you to all for  help!




trastikata

Hi,

can you try this code:

Device = 16F1703

Config1 FOSC_INTOSC, WDTE_OFF, PWRTE_OFF, MCLRE_OFF, CP_ON, BOREN_OFF, CLKOUTEN_OFF
Config2 WRT_OFF, PPS1WAY_OFF, ZCDDIS_OFF, PLLEN_OFF, STVREN_OFF, BORV_LO, LPBOR_OFF, LVP_OFF

Declare Xtal =  4
OSCCON  = %01101010   'sets the internal oscillator to 4Mhz
;-------------------------------------------------------------------------------
 
Declare  CCP2_Pin   = PORTC.3
Declare  CCP1_Pin   = PORTC.5

TRISA  = %00000001
TRISC  = %00000000
ANSELA = %00000001
ANSELC = %00000000
PORTA  = 0
PORTC  = 0

Symbol vm     =  PORTA.2

'-------------------PROGRAM----------------------
While
    @ Movlb 0x01
    @ Bcf TRISA,2
    @ Movlb 0x00
    @ Movlw 4
    @ Xorwf PORTA,F
    DelayMS 500
Wend

John Lawton

Alternatively instead of
Symbol vm     =  PORTA.2
Substitute LAT for PORT:
Symbol vm     =  LATA.2
See if that works

John

trastikata

#3
Hello John,

writes to PORTA should be fully equivalent to writing in LATA.

In the original code where Toggle is used, TRISA.2 is cleared after PORTA.2 being toggled and I suspect this might somehow interfere with the PORTA.2 state.

That's while I suggested to try reversed code order for TRISA and PORTA to see if this could be the reason.

Edit:

You are correct John, just found out about the "Read Modify Write Problem with Mid-Range PIC Microcontrollers" - everyday learning something new, thanks.  :)

midali


   Substituted LATA for PORT and working.
   I was confused , because in datasheet write : "Writes to PORTA are actually written to corresponding LATA register. Reads from PORTA register is return
of actual I/O pin values" . More, only  PORTA.2 caused this trouble .


Thank you John and Trastikata !

top204

#5
I've ran tests, and the Toggle command is working as it should with all valid pins.

I tested using the code listing below:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Test the Toggle command on pin PORTA.2 of a PIC16F1703 device.
'
    Device = 16F1703                            ' Tell the compiler what device to compile for
    Declare Xtal = 4                            ' Tell the compiler what frequency the device is operating at (in MHz)

    Symbol MyPin = PORTA.2

'------------------------------------------------------------------
' The main program starts here
' Toggle the PORTA.2 pin
;
Main:
    OSCCON  = %01101010                         ' Set the internal oscillator to 4MHz
    PinLow MyPin
    Do
        Toggle MyPin
        DelayMS 500
    Loop

'------------------------------------------------------------------
' Setup the config fuses for internal oscillator
'
    Config1 FOSC_INTOSC, WDTE_OFF, PWRTE_OFF, MCLRE_OFF, CP_ON, BOREN_OFF, CLKOUTEN_OFF
    Config2 WRT_OFF, PPS1WAY_OFF, ZCDDIS_OFF, PLLEN_OFF, STVREN_OFF, BORV_LO, LPBOR_OFF, LVP_OFF

The assembler code produced for the Toggle command on this device is, 'as it should be', and RAM banks are manipulated correctly from the commands leading up to it, and after it:

F1_000025 equ $ ; in [TEST_16F1703.BAS] OSCCON  = %01101010
    movlb 0x01
    movlw 106
    movwf OSCCON
F1_000026 equ $ ; in [TEST_16F1703.BAS] PinLow MyPin
    bcf TRISA,2
    movlb 0x00
    bcf PORTA,2
F1_000027 equ $ ; in [TEST_16F1703.BAS] Do
_lbl__2
F1_000028 equ $ ; in [TEST_16F1703.BAS] Toggle MyPin
    movlw 4
    xorwf PORTA,F
    movlb 0x01
    bcf TRISA,2
F1_000029 equ $ ; in [TEST_16F1703.BAS] DelayMs 500
    movlw 1
    movlb 0x00
    movwf PP1H
    movlw 244
    call __delay_ms_wreg_
F1_000030 equ $ ; in [TEST_16F1703.BAS] Loop
    bra _lbl__2


midali

Hi Les,

Now I tested your code on my board . The PORTA.2 is HIGH all time .

Thank you!

midali

Mr LES ,

Initially the code was made in PBP and worked well with TOGGLE PORTA.2. Now I convert it in Positron and I had a this trouble.

trastikata

Hello midali,

out of curiosity could you try the code I posted earlier?

midali

Quote from: trastikata on Sep 17, 2024, 05:43 PMHello midali,

out of curiosity could you try the code I posted earlier?

Sure ,I tested your code Trastikata and not working . Now I measured the voltage on PORTA.2 and the voltage is 3.18V , so "isn't fully high" . The PIC Vcc is 5.00V. I connected a led to port via ULN 2003 , so an over-consumer can be excluded.

trastikata

Really looks like a problem with the read-modify-write effect which seems to pester the 16F devices.

Anyway since an easy LAT fix can be effected no need of further investigation, I think.  :)   

midali

#11
You are right Trastikata !

I was very confused because before I used PBP and I didn't have this problem, with the same PIC, the same code , but instead, with PBP if I readed an RC signal with pulsein, on PORTC ,the signal was modified by that input pin(PORTC). This does not happen in positron, but here Toggle does not work.

top204

#12
You must remember, the Positron compiler's assembler code is a lot more efficient than PBP's, so it operates a lot faster in most cases.

This will have an effect with the dreaded read-modify-write querk that the 8-bit devices have, which is why microchip also brought out a Port's LAT SFR to the user and not just hidden in the port's mechanism as the older devices did.

Whenever possible, the compiler automatically uses the LAT of a port within the assembler code produced. However, the earlier enhanced 14-bit core devices made the LAT, TRIS and PORTS SFRs all in different RAM banks for some inexplicable reason, so the current compiler version only converts a port to a LAT if using the later enhanced 14-bit core devices that have them in the same RAM bank, because this is more efficient, but I will look into it and allow the compiler to change all of the PORTS to LATs on all enhanced 14-bit core devices, regardless of the RAM banks, so it does not cause problems because of its speed.

The 18F devices have a different RAM orientation, and the PORT, LAT and TRIS SFRs are all in access RAM, so the compiler always converts a PORT to a LAT when it generates the assembler code.

Also, remember that the Toggle command always sets a pin to output before it toggles it, which wastes a bit of space and time if the pin has already been made an output, and is a throwback to the original BASIC Stamp II operation.

So the code is more efficient if the Toggle command is replaced with:

MyPin = ~MyPin

Which produces the efficient assembler code of:

F1_000028 equ $ ; in [TEST_16F1703.BAS] MyPin = ~MyPin
    movlw 4
    xorwf PORTA,F


The Xor value depends on the pin value of the Port. So for bit-2 of PORTA, it is an Xor of 4.

To make the code listing even more readable, a preprocessor meta-macro can be created such as:

$define Toggle_Pin(pPin) pPin = ~pPin

Then, instead of the Toggle command, use:

Toggle_Pin(MyPin)