1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
| ; --------------------------------------
list p=16f1508 ; Define processor
#include p16f1508.inc ; Variable definitions
; --------------------------------------
; +---u---+
; Vdd <|1 20|> Vss
; RA5 <|2 19|> RA0/ICSPDAT
; **CLKOUT/RA4 <|3 18|> RA1/ICSPCLK
; MCLR/Vpp/RA3 <|4 17|> RA2
; CWG1A/RC5 <|5 16|> RC0
; *CWG1B/RC4 <|6 15|> RC1/NCO1***
; RC3 <|7 14|> RC2
; RC6 <|8 13|> RB4
; RC7 <|9 12|> RB5
; RB7 <|10 11|> RB6
; +-------+
; * CWG1B is inverted with respect to CWG1A.
; ** CLKOUT = Fosc/4 (4MHz w/ HFINTOSC) when CONFIG1 = CLKOUTEN_ON.
; *** NCO output on RC1 only when NCO1CON bit6 is Set.
; --------------------------------------
; Configuration Bits & Error Level
; --------------------------------------
; The "& 0x3FFF" was added to fix an error in the *.inc file that causes a 303 Warning in MPASM 5.51.
; See forum post: [url]https://www.microchip.com/forums/FindPost/714197[/url]
; Config Bits Info: \Program Files\Microchip\MPASM Suite\p16f1508.inc
__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF & 0x3FFF
__CONFIG _CONFIG2, _WRT_OFF & _STVREN_OFF & _BORV_LO & _LPBOR_OFF & _LVP_OFF & 0x3FFF
errorlevel -302 ; Suppresses assembler Messages pertaining to banks, so be careful!
; --------------------------------------
; Custom Variable Definitions (Equates)
; --------------------------------------
CountA EQU 0x070 ; Memories for delay routines
CountB EQU 0x071 ; (RAM Addresses 70h - 7Fh are common to all banks)
CountC EQU 0x072
; --------------------------------------
; Core Registers (present in all Banks)
; --------------------------------------
; INDF0 & INDF1
; PCL
; STATUS
; FSR0L & FSR0H & FSR1L & FSR1H
; BSR
; WREG
; PCLATH
; INTCON
; --------------------------------------
ORG 0x000 ; Reset vector.
goto Main ; Go to main program.
ORG 0x004 ; Interrupt vector location
; NOTE: W, STATUS, BSR, FSTs & PCLATH are saved
; automatically in Shadow regs (Bank 31)
retfie ; Return from interrupt.
Main
; ---------[ Interrupts ]-------------------------------------------
movlw b'01000000' ; Interrupts disabled, PEIE bit6 enabled
clrf INTCON ; INTCON is a Core Register (in all banks)
banksel PIE2 ; [Bank 1]
movlw b'00000100' ; NCO1IE = 1 (enabled) for NCO Interrupts
movwf PIE2
banksel PIR2 ; [Bank 0]
clrf PIR2 ; Peripheral Inter. Flags (NCO1IF bit2 = 1 on Accum.Overflow)
; ---------[ Oscillator Setup ]--------------------------------------
banksel OSCCON ; [Bank 1]
movlw b'01111000' ; Internal OSC = 16 MHz
movwf OSCCON
btfss OSCSTAT, HFIOFR ; Internal OSC running?
goto $-1 ; No, loop until running.
btfss OSCSTAT, HFIOFS ; OSC stable?
goto $-1 ; No, loop until stable.
; ---------[ Ports & I/O Setup ]------------------------------------
banksel PORTA ; [Bank 0] Initialize Ports.
clrf PORTA
clrf PORTB
clrf PORTC
banksel LATA ; [Bank 2] Clear data Latches.
clrf LATA
clrf LATB
clrf LATC
banksel ANSELA ; [Bank 3] Setup I/O.
clrf ANSELA ; PORTA = Digital I/O.
clrf ANSELB ; PORTB = Digital I/O. (NOTE: missing on 16F1503)
clrf ANSELC ; PORTC = Digital I/O.
banksel OPTION_REG ; [Bank 1]
movlw b'11000010' ; Pull-ups Off, TMR0 Prescaler = 1:8
movwf OPTION_REG
movlw b'11111111' ; Make CWG1A & CWG1B Inputs for now. (See CWG Setup below.)
movwf TRISC ; PORTC
movlw b'00000000' ; All outputs
movwf TRISB ; PORTB
movlw b'11101111' ; RA4 the only Output (pin 3)
movwf TRISA ; PORTA
; ---------[ CWG Setup ]------------------------------------------
; The sequence below follows "26.11 Configuring the CWG" in the PIC16(L)F1508/9 datasheet:
; [url]https://ww1.microchip.com/downloads/en/DeviceDoc/40001609E.pdf[/url]
; CWG1A (RC1) & CWG1B (RC0) are configured as Inputs for now.
banksel CWG1CON0 ; [Bank 13]
bcf CWG1CON0, 7 ; Clear GxEN (bit 7) to Disable CWG.
movlw .20 ; Put 20d into "CWG Rising DEAD-BAND Count Register"
movwf CWG1DBR ; (20 clock cycles = 1.25us @ HFINTOSC=16MHz)
movlw .20 ; Put 20d into "CWG Falling DEAD-BAND Count Register"
movwf CWG1DBF
movlw b'10000000' ; GxASE(b7)=1, GxARSEN(b6)=0
movwf CWG1CON2 ; (CWG in Shutdown State, Auto-Restart Disabled)
movlw b'10100110' ; CWG1B(b7&6) & CWG1A(b5&4) will be LO on Shutdown, Source = NCO1
movwf CWG1CON1
movlw b'01100001' ; Leave GxEN=0, CWG1A/B to Output pins, Normal Polarity, HFINTOSC
movwf CWG1CON0 ; (CWG1A clones the NCO output, CWG1B is inverted.)
bsf CWG1CON0, 7 ; Set GxEN (bit 7) to Enable CWG.
banksel TRISC ; [Bank 1]
movlw b'11001111' ; RC4=CWG1B, RC5=CWG1A (set to Outputs)
movwf TRISC ; PORT C
banksel CWG1CON2 ; [Bank 13]
bcf CWG1CON2, 7 ; Clear GxASE to start the CWG.
; ---------[ NCO Setup ]------------------------------------------
banksel APFCON ; [Bank 2]
clrf APFCON ; NCO1 function is on RC1 (NCO not using pin. See NC01CON below.)
banksel NCO1CLK ; [Bank 9]
clrf NCO1CLK ; NxPWS n/a due to fixed DC, clock source HFINTOSC (16 MHz).
clrf NCO1ACCU ; Clear the Accumulator (UPPER->HI->LO).
clrf NCO1ACCH
clrf NCO1ACCL
clrf NCO1INCH ; HI Incr.Value = 0 (NCO1INCH must execute before NCOINCL)
movlw .82 ; LO Incr.Value = 82d
movwf NCO1INCL ; Foverflow = (NCO Clock x Incr.Value)/(2^21)=626Hz square-wave
movlw b'10000000' ; Enable NCO, Disable Out-pin b6, Polarity=HI(non-inverted), Fixed D.C.
movwf NCO1CON ; Bit5 (NxOUT) is 1 when NCO output is HI, 0 when LO.
SET847
call DEL600m ; Wait 600ms.
movlw .111 ; LO Incr.Value = 111d
movwf NCO1INCL ; Foverflow = (NCO Clock x Incr.Value)/(2^21)=847Hz square-wave
call DEL600m ; Wait 600ms.
movlw .82 ; LO Incr.Value = 82d
movwf NCO1INCL ; Foverflow = (NCO Clock x Incr.Value)/(2^21)=626Hz square-wave
goto SET847
; NCO square wave continues to be output until NCO1CON bit7 is cleared.
; NCO1CON bit5 (NxOUT) can be polled to determine when Accumulator Overflows (half-cycle) occur.
; Alternatively, Peripheral Interrupt PIR2 bit2 (NCOxIF) = 1 on Accumulator Overflows:
; * NCOxIF = 1 on Accumulator Overflows, even if Interrupts are Disabled, and can be polled.
; * NCOxIF must be cleared before exiting the ISR, if Interrupts are Enabled.
; ------------------------------------------------------------------
DEL600m ; 600ms delay routine(@Fosc=16MHz)
movlw .13
movwf CountC
movlw .45
movwf CountB
movlw .215
movwf CountA
loop decfsz CountA,1
goto loop
decfsz CountB,1
goto loop
decfsz CountC,1
goto loop
retlw 0
end |