Skip to main content

PIC16F1708 a Dilly

I always wondered what is a dilly, why would you pick it and what could you possibly do with it in a circus, but those English are crazy - it must be something in the water.

The last time I used a Microchip PIC processor - some time before the dinosaurs in the previous century - there were only a handful of different chips.  Nowadays there are over 300.  A problem with this proliferation is that it is now much more difficult to find relevant information on the exact chip that you want to use and getting started with the infernal things can be very time consuming.

I wanted to use a PIC16F1708, which includes an ADC, DAC and even a couple of Op Amps for anti-aliasing filters, an all in one CODEC chip for an audio interface widget.

Here are a few tips on things that I discovered along the way.

No Power

When trying out the evaluation board I got with the PICkit3, I kept getting the error: 
Target device was not found. You must connect to a target device to use PICkit 3. 

The problem is that there is no power supply on the evaluation target board. The PICkit3 needs to supply the power and it is turned off somewhere, despite the power LED on the probe lighting up.

Try this:
    1. Go to Run > Set Project Configuration > Customize...
    2. In "Categories" window click once on PICkit 3.
    3. In the right side you have "Option Categories" drop down box, click on "Power".
    4. Now check the box for "Power target circuit from PICkit 3".
    5. Choose the "voltage level" from the drop down menu. (My PIC18F45K20 devkit is 3V)

And your target should now power up and be happy.

MPASM Configuration Registers

You must set the Configuration bits in the assembler code at the top of the main file. 

First configure the processor type PIC16F1708 in MPLabX then:
Change Configuration bits in MPLabX in the Configuration Bits window (Window>PIC Memory Views>Configuration Bits). 

Then you can export the settings by right clicking in the window and selecting “Generate Source Code to Output” and copy this code from the Output Window into your code.

First I would put a List command:
 LIST   P=PIC16F1708

Then copy and paste the generated code:

; PIC16F1708 Configuration Bit Settings

; ASM source line config statements

 #include "p16f1708.inc"

; CONFIG1
; __config 0xFFE0
 __CONFIG _CONFIG1, _FOSC_LP & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
; CONFIG2
; __config 0xFFFF
 __CONFIG _CONFIG2, _WRT_OFF & _PPS1WAY_ON & _ZCDDIS_ON & _PLLEN_ON & _STVREN_ON & _BORV_LO & _LPBOR_OFF & _LVP_ON

Read the PIC data sheet for details, since each of these devices is rather different.

An interesting page layout annoyance to note is that only labels, comments and #include may start in the left-most column.  The __CONFIG macro for example, is indented by one character.

PIC18F45K20 MPASM Example

Here is a LED flasher for the PICkit3 with the PIC18F45K20 development board in MPASM.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; LED flasher
; PIC18F45K20
; Herman Oosthuysen, Copyright Reserved, General Public License (GPL) v2, 2014
; Version 1.00, 7 July 2014
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    LIST   P=PIC18F45K20

; PIC18F45K20 Configuration Bit Settings

#include "p18f45k20.inc"

; CONFIG1H
  CONFIG  FOSC = INTIO7         ; Oscillator Selection bits (Internal oscillator block, port function on RA6 and RA7)
  CONFIG  FCMEN = OFF           ; Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
  CONFIG  IESO = OFF            ; Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

; CONFIG2L
  CONFIG  PWRT = OFF            ; Power-up Timer Enable bit (PWRT disabled)
  CONFIG  BOREN = SBORDIS       ; Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
  CONFIG  BORV = 18             ; Brown Out Reset Voltage bits (VBOR set to 1.8 V nominal)

; CONFIG2H
  CONFIG  WDTEN = OFF           ; Watchdog Timer Enable bit (WDT is controlled by SWDTEN bit of the WDTCON register)
  CONFIG  WDTPS = 32768         ; Watchdog Timer Postscale Select bits (1:32768)

; CONFIG3H
  CONFIG  CCP2MX = PORTC        ; CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
  CONFIG  PBADEN = ON           ; PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)
  CONFIG  LPT1OSC = OFF         ; Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
  CONFIG  HFOFST = ON           ; HFINTOSC Fast Start-up (HFINTOSC starts clocking the CPU without waiting for the oscillator to stablize.)
  CONFIG  MCLRE = ON            ; MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)

; CONFIG4L
  CONFIG  STVREN = ON           ; Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
  CONFIG  LVP = OFF             ; Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
  CONFIG  XINST = OFF           ; Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

; CONFIG5L
  CONFIG  CP0 = OFF             ; Code Protection Block 0 (Block 0 (000800-001FFFh) not code-protected)
  CONFIG  CP1 = OFF             ; Code Protection Block 1 (Block 1 (002000-003FFFh) not code-protected)
  CONFIG  CP2 = OFF             ; Code Protection Block 2 (Block 2 (004000-005FFFh) not code-protected)
  CONFIG  CP3 = OFF             ; Code Protection Block 3 (Block 3 (006000-007FFFh) not code-protected)

; CONFIG5H
  CONFIG  CPB = OFF             ; Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
  CONFIG  CPD = OFF             ; Data EEPROM Code Protection bit (Data EEPROM not code-protected)

; CONFIG6L
  CONFIG  WRT0 = OFF            ; Write Protection Block 0 (Block 0 (000800-001FFFh) not write-protected)
  CONFIG  WRT1 = OFF            ; Write Protection Block 1 (Block 1 (002000-003FFFh) not write-protected)
  CONFIG  WRT2 = OFF            ; Write Protection Block 2 (Block 2 (004000-005FFFh) not write-protected)
  CONFIG  WRT3 = OFF            ; Write Protection Block 3 (Block 3 (006000-007FFFh) not write-protected)

; CONFIG6H
  CONFIG  WRTC = OFF            ; Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
  CONFIG  WRTB = OFF            ; Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)
  CONFIG  WRTD = OFF            ; Data EEPROM Write Protection bit (Data EEPROM not write-protected)

; CONFIG7L
  CONFIG  EBTR0 = OFF           ; Table Read Protection Block 0 (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
  CONFIG  EBTR1 = OFF           ; Table Read Protection Block 1 (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
  CONFIG  EBTR2 = OFF           ; Table Read Protection Block 2 (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
  CONFIG  EBTR3 = OFF           ; Table Read Protection Block 3 (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)

; CONFIG7H
  CONFIG  EBTRB = OFF           ; Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Macros
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Compare file register to constant and jump to destination
;
; if register >= constant
_BGE    MACRO reg, const, dest
        MOVLW const & 0xff
        SUBWF reg, W
        BTFSC STATUS, CARRY
        GOTO dest
        ENDM

; If register == constant
_BEQ    MACRO reg, const, dest
        MOVLW  const & 0xff
        SUBWF  reg, W
        BTFSC  STATUS, Z
        GOTO   dest
        ENDM

; If register <= constant
_BLT    MACRO reg, const, dest
        MOVLW  const & 0xff
        SUBWF  reg, W
        BTFSS  STATUS, C
        GOTO   dest
        ENDM

; If register != constant
_BNE    MACRO reg, const, dest
        MOVLW  const & 0xff
        SUBWF  reg, W
        BTFSS  STATUS, Z
        GOTO   dest
        ENDM


; Swap the accumulator and a file register
_SWAPWF MACRO  reg
        XORFW  reg,F
        XORFW  reg,W
        XORFW  reg,F
        ENDM

; Decrement the accumulator (a readability macro)
_DECW   MACRO
        ADDLW  0xFF       ; Add W to -1
        ENDM




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Variables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        UDATA 0x0020

delay1  res 1
delay2  res 1


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Vector Table
; Code space = 4kW (0000 - 0FFF)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

START   CODE 0x0000
start
        GLOBAL start
        PAGESEL main
        GOTO main

ISR     CODE 0x0004
isr
        GLOBAL isr
        ; ISR code goes here
        RETFIE

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MAIN    CODE            ; Linker to place immediately after ISR
main
        GLOBAL    main

        CLRF PORTD
        CLRF TRISD
        CLRF delay1
        CLRF delay2

mainloop:
        BTG PORTD,RD1   ; Toggle PORT D PIN 1 (20)
delay:
        DECFSZ delay1,1 ; Roughly 1 Hz with internal clock
        GOTO delay
        DECFSZ delay2,1
        GOTO delay
        GOTO mainloop

        END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

This should be a good starting template for assembler jobs with this processor.

PIC16F1708 MPASM Example

Annoyingly, each PIC has a somewhat different instruction set and whatever works on one processor, may not work at all on another.  So when developing something, you got to keep the data sheet open on one screen - a dual screen computer setup is pretty much required to get anything done with the least amount of pain.  A virtual desktop system as in Linux and Mac helps a lot, but two screens are better.

On a PIC, doing anything remotely useful, requires at least 2 instructions and usually more like 4 and each instruction takes at least 2 cycles.   Therefore a machine running at 20 MHz is not as fast as one would think at first glance, but even with a 1 MHz effective 'do something' rate, it is still fast enough to make my head hurt thinking about it.

We used to build frequency hopping radios with 256 kHz processors - the advantage of a low clock speed is low power consumption, which is critical on battery powered equipment.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PIC16F1708
; Herman Oosthuysen, Copyright Reserved, 2014
; General Public License (GPL) version 2
; Version 0.01, 5 July 2014
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Power
; The PIC16F1708 uses 4 to 6V
; The PICkit3 can power the target, but 5V may not be available on a laptop PC
; Go to Run > Set Project Configuration > Customize...
; In "Categories" window click once on PICkit 3.
; In the right side you have "Option Categories" drop down box, click on "Power".
; Now check the box for "Power target circuit from PICkit 3".
; Choose the "voltage level" from the drop down menu and set it to 4.5V
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Include Files
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    LIST        P=PIC16F1708
    #include    "p16f1708.inc"

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Configuration
; First configure the processor type then do:
; Window>PIC Memory Views>Configuration Bits
; Edit then click "Generate Source Code to Output"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; CONFIG1
; __config 0x17C4
 __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _BOREN_ON & _CLKOUTEN_ON & _IESO_ON & _FCMEN_OFF
; CONFIG2
; __config 0x37FB
 __CONFIG _CONFIG2, _WRT_OFF & _PPS1WAY_OFF & _ZCDDIS_ON & _PLLEN_ON & _STVREN_ON & _BORV_LO & _LPBOR_ON & _LVP_ON


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Macros
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Initialize Clock
_INITOSC MACRO
        BANKSEL OSCCON
        MOVLW B'11111010'   ; Internal oscillator, 16 MHz
        MOVWF OSCCON
        ENDM

; Initialize PORTB
_INITB  MACRO
        BANKSEL PORTB
        CLRF PORTB
        BANKSEL LATB
        CLRF LATB
        BANKSEL ANSELB
        CLRF ANSELB         ; Analogue functions disable = 0
        BANKSEL TRISB       ; Tristate = 1 = Input
        MOVLW B'01110000'   ; Out: B7, In: B6-4
        MOVWF TRISB
        BANKSEL RB7PPS
        MOVLW B'00000'      ; Peripheral Pin Select
        MOVWF RB7PPS        ; LatchB7 = Out
        ENDM


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Variables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        UDATA   0x20
stateb  res 1                ; LATB status
delay1  res 1                ; Delay LSB
delay2  res 1                ; Delay MSB
        

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Vector Table
; Code space = 4kW (0000 - 0FFF)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
START   CODE 0x0000             ; Reset Vector
start
        GLOBAL start
        PAGESEL main
        GOTO main

ISR     CODE 0x0004             ; Interrupt Service Routine
isr
        GLOBAL isr
        ; ISR code goes here
        RETFIE

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Main Code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MAIN    CODE              ; Main program start vector
main
        GLOBAL    main

        _INITOSC                ; Configure the Clocks
        _INITB                  ; Configure PortB

        BANKSEL stateb          ; Zap the latch variable
        CLRF stateb
        CLRF delay1
        CLRF delay2

flashled
        BANKSEL PORTB           ; Toggle PORT B bit 7 (pin 10)
        MOVLW 0x80              ; set bit 7 in W
        XORWF stateb, 1         ; XOR W with port & store result
        MOVFW stateb            ; get the result again
        MOVWF PORTB             ; Output the latch state to the port latch

delay
        DECFSZ delay1,1         ; Roughly 4 Hz with internal 16 MHz clock
        GOTO delay
        DECFSZ delay2,1
        GOTO delay
        GOTO flashled

        END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



La voila!

Comments

Popular posts from this blog

Parasitic Quadrifilar Helical Antenna

This article was reprinted in OSCAR News, March 2018:  http://www.amsat-uk.org If you want to receive Satellite Weather Pictures , then you need a decent antenna, otherwise you will receive more noise than picture. For polar orbit satellites, one needs an antenna with a mushroom shaped radiation pattern .  It needs to have strong gain towards the horizon where the satellites are distant, less gain upwards where they are close and as little as possible downwards, which would be wasted and a source of noise.  Most satellites are spin stabilized and therefore the antenna also needs circular polarization, otherwise the received signal will flutter as the antennas rotate through nulls. The helical antenna, first proposed by Kraus in 1948, is the natural solution to circular polarized satellite communications.  It is a simple twisted wire - there seems to be nothing to it.  Various papers have been published on helix antennas, so the operation is pretty well understood. Therefore,

Weather Satellite Turnstile Antennas for the 2 meter Band

NEC2, 2 m band, 146 MHz, Yagi Turnstile Simulation and Build This article describes a Turnstile Antenna for the 2 meter band, 146 MHz amateur satcom, 137 MHz NOAA and Russian Meteor weather satellites.  Weather satellite reception is described here .  A quadrifilar helical antenna is described here .   Engineering, is the art of making what you need,  from what you can get. Radiation Pattern of the Three Element Yagi-Uda Antenna Once one combine and cross two Yagis, the pattern becomes distinctly twisted. The right hand polarization actually becomes visible in the radiation pattern plot, which I found really cool. Radiation Pattern of Six Element Turnstile Antenna Only a true RF Geek can appreciate the twisted invisible inner beauty of a herring bone antenna... Six Element Turnstile Antenna Essentially, it is three crosses on a stick.  The driven elements are broken in the middle at the drive points.  The other elements can go straight throug

Patch Antenna Design with NEC2

The older free Numerical Electromagnetic Code version 2 (NEC2) from Lawrence Livermore Lab assumes an air dielectric.  This makes it hard (but not impossible) for a radio amateur to experiment with Printed Circuit Board Patch antennas and micro strip lines. Air Spaced Patch Antenna Radiation Pattern You could use the free ASAP simulation program , which handles thin dielectrics, you could shell out a few hundred Dollars for a copy of NEC4 , You could buy GEMACS if you live in the USA, or you could add distributed capacitors to a NEC2 model with LD cards (hook up one capacitor in the middle of each element.), but that is far too much money/trouble for most. More information on driving an array antenna can be found here: https://www.aeronetworks.ca/2019/03/driving-quad-patch-array-antenna.htm l Air Dielectric Patch   The obvious lazy solution is to accept the limitation and make an air dielectric patch antenna. An advantage of using air dielectric, is that the antenn