It mostly works. The switch does put the device into CAL mode, but releasing the switch does not return it to SINE mode. It's a short program and I just can't see the problem.
The other issue is that the compiler returns a weird warning referencing the last line of the program. It does compile, though.
Below is the program, if anyone has time to look at it.
Regards,
Mike
--
-- Description: Roman Black's 1kHz sine wave generator.
-- Ported to JAL and the PIC12F1840.
--
-- Connections:
-- Green LED on RA1 (to ground, with resistor).
-- Red LED on RA0 (to ground, with resistor).
-- Switch on RA3 (MCLR) switching the pin to ground, using internal pullup.
-- Signal output on RA2.
-- Using the internal oscillator at 8MHz, no crystal.
--
include 12f1840
--
pragma target clock 8_000_000
pragma target OSC INTOSC_NOCLKOUT
pragma target PWRTE enabled -- power up timer
pragma target BROWNOUT disabled -- no brown-out reset
pragma target PLLEN disabled -- PLL off
pragma target WDT disabled -- no watchdog
pragma target DEBUG disabled -- no debugging
pragma target LVP disabled -- no Low Voltage Programming
pragma target MCLR internal -- no external MCLR reset, pin is used as GPIO
pragma target FCMEN disabled -- no fail-safe clock monitor
pragma target IESO disabled -- no internal/external switchover
var byte pwmstep
var byte pwmval
var byte debounce
const byte sine[50] = {52,57,62,66,70,74,77,80,82,84,85,86,86,
86,85,83,81,78,75,72,69,65,61,56,52,
48,44,39,35,31,28,25,22,19,17,15,14,14,
14,15,16,18,20,23,26,30,34,38,43,48}
enable_digital_io()
LATA = 0b0000_0000
TRISA = 0b0000_1000
WPUA = 0b0000_1000
OPTION_REG = 0b0000_0111
OSCCON = 0b0111_0000
while ! OSCSTAT_HFIOFS loop end loop
T2CON = 0b0000_0100 -- postscale 1:1, prescale 1:1, TMR2 on
PR2 = 40-1 -- 20us tick
_usec_delay(300_000) -- small settling delay
procedure set_sine_mode() is
pwmstep = 0
debounce = 0
LATA = 0b000_0010 -- turn on SINE mode LED
CCP1CON = 0b0000_1100 -- turn on PWM
end procedure
procedure set_cal_mode() is
CCP1CON = 0b0000_0000 -- turn off PWM
LATA = 0b000_0001 -- turn on CAL mode LED
assembler
local loop, done
loop:
bsf LATA,2
bcf LATA,2
btfsc PORTA,3 ; check if switch was set to SINE mode
goto done
bsf LATA,2
bcf LATA,2
goto loop
done:
end assembler
end procedure
set_sine_mode()
forever loop
-- just sit in loop and load new PWM value every TMR2 cycle
while (!PIR1_TMR2IF) loop
end loop
CCPR1L = pwmval -- store PWM value for this cycle
PIR1_TMR2IF = false -- clear TMR2 interrupt flag
pwmstep = pwmstep + 1
if (pwmstep >= 50) then
pwmstep = 0
end if
pwmval = sine[pwmstep]
if (pin_A3 == low) then
debounce = debounce + 1
if (debounce > 250) then
set_cal_mode()
-- return from cal mode
set_sine_mode()
end if
else
debounce = 0
end if
end loop