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.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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
; 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!
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.
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!
No comments:
Post a Comment
On topic comments are welcome. Junk will be deleted.