News:

;) This forum is the property of Proton software developers

Main Menu

16F17146 not working correctly

Started by Fanie, Jun 10, 2025, 03:06 PM

Previous topic - Next topic

Fanie

The program compiles and the 16F17146 programs, but it does not run the program as expected.

The program is very simple and I used the same many times with 16F684.
It reads an analog input and writes a value serial to an LED display.
Vdd = 4.990V and VPP pin is held high.

I cannot get a config done because it gives an error and I have tried every way I can think of using the register names in the 16F17146.PPI

I can only think that the problem is the configuration setup.

PMD0 = 11111111                 '  Peripheral Modules Disable
There is 5, PMD0-4 all gives a warning that value will overflow a byte size variable ?

Config1 - 5 is supposed to turn green and capital letters in the editor, it remains black and lower case, hence the editor does not recognize it as a register ?

If anyone used the 16F17146 and got it working, I will be grateful if you will share the configuration with me.

Is it possible that the editor is not reading the PPI file ?

Thank you kindly.

John Lawton

Quote from: Fanie on Jun 10, 2025, 03:06 PMPMD0 = 11111111                '  Peripheral Modules Disable

ITYM: PMD0 = %11111111 ?

Fanie

#2
Yes, that fixed that, thank you.
The rest however is still through each other (confused).

Fanie

MPLab IPE 6.2 refuses to program the 16F17146 with Xtal = 16, but does so with Xtal = 4, 8 and 32.  Weird.
Returns an incorrect checksum ?  [ Pgm ] at 0x3, expected 0x00002920, got 0x00002922.

top204

#4
The code listing template below should operate the PIC16F17146 device at 16MHz with its internal oscillator. However, I do not have that device, so it is setup from the datasheet:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Internal Oscillator operating at 16MHz with its internal oscillator template for a PIC16F17146 device.
' Written by Les Johnson for the Positron8 BASIC Compiler.
'
    Device = 16F17146                                               ' Tell the compiler what device to compile for
    Declare Xtal = 16                                               ' Tell the compiler what frequency the device is operating at (in MHz)
    Declare Float_Display_Type = Fast                               ' Use the compiler's faster floating point display routine
    Declare Auto_Heap_Arrays = On                                   ' Make all arrays "Heap" types, so they always get placed after standard variables
    Declare Auto_Heap_Strings = On                                  ' Make all Strings "Heap" types, so they always get placed after standard variables
    Declare Auto_Variable_Bank_Cross = On                           ' Make sure all multi-byte variables remain within a single RAM bank
'
' Setup USART1
'
    Declare Hserial_Baud = 9600                                     ' Set the Baud rate for USART1
    Declare HRSOut1_Pin  = PORTC.4                                  ' Tell the compiler to setup pin PORTC.4 for USART1 Tx
    Declare HRSIn1_Pin   = PORTC.5                                  ' Tell the compiler to setup pin PORTC.5 for USART1 Rx

'------------------------------------------------------------------------------------------
' The main program starts here
'
Main:
    Setup()                                                         ' Setup the program and any peripherals

    Do

    Loop

'------------------------------------------------------------------------------------------
' Setup the program and any peripherals
' Input     : None
' Outout    : None
' Notes     : None
'
Proc Setup()
    Osc_Init()                                                      ' Initialise the oscillator on a PIC16F17146 device
'
' More setups here when required
'
EndProc

'------------------------------------------------------------------------------------------
' Initialise the oscillator on a PIC16F17146 device for 16MHz
' Input     : None
' Outout    : None
' Notes     : For internal oscillator
'
Proc Osc_Init()
    OSCCON1 = $62                                                   ' NDIV is 4. NOSC HFINTOSC
    OSCCON3 = $00
    OSCEN   = $00
    OSCFRQ  = $04                                                   ' HFFRQ is 16MHz
    OSCTUNE = $00
    ACTCON  = $00
    DelayMs 100
EndProc

'------------------------------------------------------------------------------------------
' Setup the config fuses for an internal oscillator on a PIC16F17146 device
' OSC pins are general purpose I/O lines
'
    Config1 FEXTOSC_OFF,_                               ' External Oscillator not enabled
            RSTOSC_HFINTOSC_16MHz,_                     ' Reset Oscillator Selection is HFINTOSC (16MHz)
            CLKOUTEN_OFF,_                              ' CLKOUT function is disabled
            CSWEN_ON,_                                  ' Writing to NOSC and NDIV is allowed
            VDDAR_HI,_                                  ' Internal analogue systems are calibrated for operation between VDD = 2.3 to 5.5V
            FCMEN_ON                                    ' Fail-Safe Clock Monitor enabled

    Config2 MCLRE_EXTMCLR,_                             ' RA3 pin function is MCLR
            PWRTS_PWRT_OFF,_                            ' Power-up Timer is disabled
            LPBOREN_OFF,_                               ' Low-Power BOR disabled
            BOREN_ON,_                                  ' Brown-out Reset enabled. SBOREN bit is ignored
            DACAUTOEN_OFF,_                             ' DAC Buffer reference range is determined by the REFRNG bit
            BORV_LO,_                                   ' Brown-out Reset Voltage (VBOR) set to 1.9V
            ZCD_OFF,_                                   ' ZCD can be enabled by setting the ZCDSEN bit of ZCDCON
            PPS1WAY_OFF,_                               ' The PPSLOCKED bit can be set and cleared as needed (unlocking sequence is required)
            STVREN_ON                                   ' Stack Overflow or Underflow will cause a reset

    Config3 WDTCPS_WDTCPS_31,_                          ' Watchdog Timer Period Divider ratio is 1:65536. Software control of WDTPS
            WDTE_OFF,_                                  ' Watchdog Timer Disabled. SEN is ignored
            WDTCWS_WDTCWS_7,_                           ' Watchdog Timer Window always open 100%
            WDTCCS_SC                                   ' Watchdog Timer Clock is software control

    Config4 BBSIZE_BB512,_                              ' 512 words boot block size
            BBEN_OFF,_                                  ' Boot Block disabled
            SAFEN_OFF,_                                 ' Storage Area Flash disabled
            WRTAPP_OFF,_                                ' Application Block is Not write protected
            WRTB_OFF,_                                  ' Boot Block is Not write protected
            WRTC_OFF,_                                  ' Configuration Register is Not write protected
            WRTD_OFF,_                                  ' Data EEPROM is Not write protected
            WRTSAF_OFF,_                                ' Storage Area Flash is Not write protected
            LVP_OFF                                     ' Low Voltage Programming disabled

    Config5 CP_OFF,_                                    ' Program Flash Memory code protection is disabled
            CPD_OFF                                     ' Data EEPROM code protection is disabled

Fanie

Thank you Les, you've gone to a lot of trouble.
I assembled it and programmed but the code is still not doing anything.

To make sure my code is working, I made another board up with a 16F688 at 8MHz (I couldn't find any 16F684's :( ), and the code works perfectly.

The two boards are identical, it is just the micro's which is different.

So it is definitely just the setup of the 16F17146 which is at large.

I will make another attempt by the morrow, after the data sheet and other distracting things I'm making stupid mistakes like loading 11111111 in registers instead of the binary.

Thank you again.

Fanie

If I have an address and the package you prefer I could perhaps buy a few from Mouser Electronics and have them deliver to you ?  Don't know if it will be possible.  They always give me good service.

John Lawton

Hi Fanie,

what should the code do? Have you tried to flash an LED for instance to check the code is actually running?

You've got a lot of peripherals on this part compared to an 16F684 so I would make sure all unused peripherals are disabled, e.g. PWM, CWG, NCO, DAC, comparators, opamp, ZCD. Switch off ADC inputs (ANSELx) unless required.

Fanie

#8
Hello John,
The code reads an analog pin and writes it to an LED display.  This works, used the same many times.
The 16F17146 and 16F684 and 16F688 are pin compatible, which is why I can use them.  My board provides for a narrow or wide chip.
I can give you my code, but I use my own LED display circuit which will not work with your peripherals.

The problem is the 16F17146 have some obscure config bit hidden somewhere which prevents it to work.  Had the same with the 18F before.

' micro setup here, works for the 16F684 and 16F688

       ' Cal voltage to 12V
        Test = ERead 1 : DelayMS 20
        If Test = 120 Then GoTo Prp2      'calibrated DvdR
        DvdR = 280
        DelayMS 2000    ' delay to remove programmer else cal value is faulty
       
Prp1: 
        Vin = ADIn 0                          ' read Volage input
        Vin = Vin * 110                       
        Vin = Vin / DvdR
        If Vin > 120 Then DvdR = DvdR + 1 : GoTo Prp1 : EndIf
        If Vin < 120 Then DvdR = DvdR - 1 : GoTo Prp1 : EndIf
        If Vin = 120 Then
        EWrite 5, [DvdR]
        EWrite 1, [120]
        GoTo Prp2
        EndIf
       
        GoTo Prp1
       
Prp2:
        DvdR = ERead 5 : DelayMS 20   
         

'********************************************************
'*              Main Program Starts Here
'********************************************************

Start:
        Vin = ADIn 0                          ' read Volatge input

        Vin = Vin * 110                       '
        Vin = Vin / DvdR
               
        Dis1 = Dig Vin , 0                  ' Extract Current values for display
        Dis2 = Dig Vin , 1
        Dis3 = Dig Vin , 2
        Dis4 = Dig Vin , 3
       
        GoSub Display
        DelayMS 100
       
        GoTo Start

'***************************************************************************
'                       SUBROUTINES START HERE
'***************************************************************************


'***************************************************************************
'    Write Dis1 to Dis4 to Display
'***************************************************************************

Display:
       
        ' Set corresponding bits on displaying Volt
        Dis1 = LookUpL Dis1 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152] ' Values for my display.
        Dis2 = LookUpL Dis2 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis3 = LookUpL Dis3 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis4 = LookUpL Dis4 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
               
   'Blank leading zeros   
Blank:
       If Dis4 <> 126 Then GoTo Display2
       Dis4 = 0
       If Dis3 <> 126 Then GoTo Display2
       Dis3 = 0
'       If Dis2 <> 126 Then GoTo Display2
'       Dis2 = 0
       
       
       
Display2:

         Dis2 = Dis2 + 1        'Add decimal point XXX.X
         
         SHOut DisD, DisC, 0,[Dis1, Dis2, Dis3, Dis4]
       
         DisS = 1
         DelayUS 10
         DisS = 0
         DelayUS 10
         Return

       End

I have added to the self calibration code
DelayMS 2000    ' delay to remove programmer else cal value is faulty
because it seems the pic finds the calibration value so fast that the programmer is still connected and this results in a faulty value, most likely because the AD0 is the input I use is also a ICSP pin.
You apply a calibration value to the input and the code finds the divider for the value you specify.  No pots to turn or lengthy calibration stories.

John Lawton

Are you using Les's Config settings?

John

Fanie

This is what the boards look like
That is the 16F688 displaying
The 16F17146 dispays random garbage.

Pics1.jpg

Fanie

Quote from: John Lawton on Jun 10, 2025, 10:00 PMAre you using Les's Config settings?

John

I have copied and pasted, and it's not working.  Will re-do tomorrow.

trastikata

Hello Fanie,

add delay after the EEPROM writes:
QuoteEWrite 5, [DvdR]
delayms 5
EWrite 1, [120]
delayms 5

Can you post the code where you set-up the ports and the ADC?

Fanie

#13
I have never encountered a problem writing to eeprom, it's the reading that requires a delay. It won't do anything if you add the delay (thousands of NOP's), but it can cause unwanted delays in a fast app.  The newer pic's should (assumption) read and write faster to eeprom than the old ones, will test when I get the 16F17146 going.

TRISA = %00010001               ' Configure I/O
ANSELA = %00000001               ' Select analog input pin ADin 0
TRISB = %00000000
TRISC = %00001000
ODCONC = %00000000               ' output souce and sink current

charliecoutas

If this is any help Fanie. I had a lot of trouble getting a 16F1704 going and it turned out to be the setup fuses. This eventually worked for me. I know its not the same PIC:

Device = 16F1704                                                       

Config1 FOSC_INTOSC, WDTE_OFF, PWRTE_ON, MCLRE_OFF, CP_OFF, BOREN_OFF, CLKOUTEN_OFF, IESO_OFF, FCMEN_OFF
Config2 WRT_OFF, PLLEN_ON, STVREN_OFF, LVP_OFF

    Declare Xtal = 32
    On_Interrupt int
.
.
        OSCCON = %11110000                                            ;PIC runs at 32Mhz with these settings - 8Mhz clock 4xPLL 125nS per instruction
        WPUA = %00110000                                                ;PORT A input pull-ups enabled
        WPUC = %00100000                                                ;PORTC 5 is encoder switch
        OPTION_REG = %00000000                                     ;enable the pull-ups on PORTA
        TRISA = %00111100                                                 ;4 and 5 are inputs
        TRISC = %11101000
        Clear
Charlie

Stephen Moss

#15
Quote from: Fanie on Jun 10, 2025, 09:36 PMThe 16F17146 and 16F684 and 16F688 are pin compatible, which is why I can use them.  My board provides for a narrow or wide chip.
It appears you have checked the pins are compatible, but did you check that the ADC set-up is compatible?
Unless I am looking at the wrong data sheets the ADin command works with the 16F684 and 16F688 because the ADC set-up old school...

ADCON1 – A/D CONTROL REGISTER 1 (ADDRESS: 9Fh)
R/W-0 R/W-0 U-0 R/W-0 R/W-0 R/W-0 R/W-0   R/W-0
ADFM  VCFG  —   CHS2  CHS1  CHS0  GO/DONE ADON
and
ADCON1 – A/D CONTROL REGISTER 1 (ADDRESS: 9Fh)
R/W-0 R/W-0 U-0 R/W-0 R/W-0 R/W-0 R/W-0   R/W-0
ADFM  VCFG  —   CHS2  CHS1  CHS0  GO/DONE ADON

Whereas the unless I have the wrong datasheet the 16F17146 is vastly different with at least a dozen registers associated with the ADC and ADCON0 appears to have a total different function to that on the other devices you have used, so while the ADin command will work with older devices, that is not necessarily the case with newer devices like the 16F17146.
You should check the assembler listing to see if the resulting ADin code appears to be setting the registers correctly, but I suspect that is not the case in this instance and you will have to read the datasheet and write your own ADC setup and control code.

Compilers like Positron lose a little something when commands like this no longer work, as one of the reasons people use them is that commands like that make it easy to use PIC's particularly for beginners.
The downside of such ease of use is that as devices evolve and as the manufacture alters the Names/Addresses and/or functions of the registers used to accommodate that to maintain that ease of use requires writing multiple versions of the same instruction and potentially having to create and add new functions to control other new aspects of the applicable peripheral.  Which is not easy for a large company to keep up with, let alone a single person.

John Lawton

Quote from: Fanie on Jun 11, 2025, 07:55 AMI have never encountered a problem writing to eeprom, it's the reading that requires a delay
Sorry Fanie, that's just wrong. Reading EEPROM is fast, writing always requires some time.

Fanie

I think I got it working using Les's setup as a guide, although he writes the code bottom to top :o.
I'll have to get another display and perhaps turn it upside down ?

It now reads the A/D correctly and writes to the display, so the I/O is working  8) 

The PMDx registers allow you to set peripherals on and off.
In my case PMD0 = %00100000 has it up and working, only the Interrupt-on-change module is disabled.

It works without the EEPROM read write part, I just have to get that going now.
It does not work with or without the read write delays, I used 20ms.
Something is blocking the use of the EEPROM, I'm sure.


I'm going to ask you guys to give me long programming code that does the same, I think it is a shame if one waste so much memory.  Only 822 bytes used of a possible 16k  :-[

Fanie

In the Data EEPROM Memory Specifications -
I can read write 100 000 times  (Switching the meter on once a day will last for 273 years, minus the testing I do now of course)
Retain data for only 40 years (seems a bit short for me)
Byte Erase and Write Cycle Time 11 ms MAX, so we'll use a delayms 12 for read and write (For John)

Program Flash Memory Specifications
Can reprogram only 10 000 times - (that's where the gorge in the hard drive surface comes from ;D)
And will also retain memory for only 40 years.

I wonder what pic's will be in 40 years ?  User voice programmable perhaps ?  IF you can get the configuration bits...

Fanie

#19
Quote from: Stephen Moss on Jun 11, 2025, 08:53 AMThe 16F17146 and 16F684 and 16F688 are pin compatible...

but did you check that the ADC set-up is compatible?

The 16F684 and the 16F688 are the same, the 16F688 has 4k memory and the 16F684 has 2K
As a result of the more memory there is a page in the 4k memory and you have to use ie lookupL instead of lookup.

The 16F17146 is exactly the same and pin compatible with A/D's, Vpp, power etc with the two mico's above, apart from a different software setup, more peripherals, more memory, faster, 12 bit A/D, ... so if you get the 16F17146 going, it can do everything the smaller pics do.  It has a portB too because of the more pins (20 vs 14).

The exact same code of the smaller pics are now running in the 17146.

I have probably a few hundred of these boards and use them for a verity of applications.  The smaller pics are more expensive and will probably be replaced by newer ones.

I know I lied a few times saying they are the same ;) but you know what I mean.