Code:
' For production version of this code, comment out the line below re:
' LCD debugging and also update config fuses to have code protect on
#DEFINE USE_LCD_FOR_DEBUG ; comment out for non-debug use
' ***************************************************************
' Pin Connections
' ***************************************************************
' VDD -> pin 1 -> +5V
' RA5/Rc -> pin 2 -> EUSART receive
' RA2 -> pin 5 -> 1kohm -> 2N2222A transistor -> LEDs
' RA1 -> pin 6 -> Trim pot input
' RA0/Tx -> pin 7 -> EUSART transmit (LCD)
' VSS -> pin 8 -> GND
DEFINE OSC 16 ; Set oscillator 16Mhz
' ***************************************************************
' EUSART Settings for Tx/Rc (e.g. LCD)
' ***************************************************************
' > use Mister E PIC Multi-Calc application to get register/DEFINE settings
' > as the values are dependent on the OSC and desired baud rate
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_SPBRG 160 ' 9600 Baud @ 16MHz, -0.08%
' ***************************************************************
' Device Fuses
' ***************************************************************
' PIC chip data sheets can be found here: C:\Program Files\Microchip\MPASM Suite
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF
__config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF
#ENDCONFIG
' ***************************************************************
' Initialization
' ***************************************************************
OSCCON = %01111000 ' 16MHz internal osc
pause 100
APFCON.2 = 0 ; Tx on RA0 for LCD display
APFCON.7 = 1 ; Rc on RA5
APFCON.0 = 0 ; CCP1 on RA2
' Some LCD serial modules need inverted data, some do not
' Enable the line below if needed, but for SparkFun SerLCD it should be
' commented out
'BAUDCON.4 = 1 ; Transmit inverted data to the Tx pin
' From Mister E's Multi-Calc for EUSART:
' *****************************************************************
SPBRGH = 1
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator
' *****************************************************************
TRISA = %00100010 ' Make all pins output except for RA1 (trim pot input)
' and RA5 (EUSART Rc)
ANSELA = %00000010 ; Analog on PORTA.1 (AN1) only
FVRCON = 0 ' Fixed Voltage Reference is disabled
ADCON0 = %00000101 ' ADC (analog-to-digital) is enabled on AN1 (RA1) only
PAUSEUS 20 ; wait for the analog switch 'glitch' to die down
ADCON1 = %00110000 ; Left-justified results in 8-bits; Frc as timer
#IFDEF USE_LCD_FOR_DEBUG
LCD_INST CON 254 ' instruction
LCD_CLR CON 1 ' Clear screen
LCD_L1 CON 128 ' LCD line 1
LCD_L2 CON 192 ' LCD line 2
LCD_SP_CMD CON 124 ' special command character (for adjusting backlight brightness or toggling splash screen)
LCD_BR_LVL CON 140 ' 140==40%
LCD_SPLASH CON 9 ' toggles splash screen display
#ENDIF
ADCInVal VAR BYTE ; stores ADCIN result read from trim pot
compVal VAR BYTE ; stores last-changed ADC value
CounterA var BYTE ' Just a BYTE Temporary working variable
DataW var WORD ' Just a WORD Temporary working variable
RawData var BYTE [16] ' Array holding ADC Result
LEDBrVal VAR WORD
i VAR WORD
' Array size = 100
' Total PWM steps: 512
' Gamma correction: 1.35
' # of values per line: 25
'-----[The data table]--------------------------------------------------------
DataWord VAR WORD
DataTable CON EXT
GOTO OverData ; Make sure data doesn't try to execute
ASM
DataTable
DW 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2
DW 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11
DW 12, 13, 14, 15, 16, 17, 18, 20, 21, 23, 24, 26, 28, 30, 33, 35, 38, 41, 44, 47, 51, 55, 59, 64, 69
DW 74, 80, 86, 93,101,109,118,128,138,150,162,176,190,206,224,243,263,286,310,337,366,398,433,471,511
endasm
OverData:
'-----[Continue with code]----------------------------------------------------
' ***************************************************************
' Set up PWM on CCP1
' ***************************************************************
CCP1CON = %00001100 ; Use CCP1 in PWM mode
' Set duty cycle registers initially to 0
CCP1CON.4 = 0
CCP1CON.5 = 0
CCPR1L = 0
' Use Mister E's PICMultiCalc_1.3.1.exe application (Windows only)
' to determine prescaler and PR2 values for given OSC frequency (e.g. 16Mhz)
' and duty cycle (use 100% to see highest actual value)
' ************************
' CCP1 uses TMR2
' ************************
T2CON = %00000110 ; Timer2 on with 1:16 prescaler
PR2 = 127 ; For 16Mhz OSC the desired output freq of 1954Hz
; is achieved with this PR2 value (9-bit resolution
; with 1:16 prescaler)
; MAX DUTY = 100
MaxDuty VAR WORD ; According to Darrel:
; MaxDuty = (PR2 + 1) * 4
MaxDuty = (PR2 + 1) * 4 ; 100
MinDuty CON 75 ; Minimum brightness for this application
PWMDuty VAR WORD ; Duty cycle variable for PWM
' Fade in LED to set brightness
FOR i = 0 to 100 ; must match ARRAY SIZE of data table above
ReadCODE (DataTable + i), DataWord
PWMDuty = DataWord
GOSUB ChngLEDBrightness
pause 1
NEXT i
#IFDEF USE_LCD_FOR_DEBUG
HSEROUT [LCD_INST, LCD_CLR]
pause 5
HSEROUT ["i=",DEC i," "]
#ENDIF
Main:
PAUSE 100
GOTO Main
'*********** Set duty registers ****************************************
ChngLEDBrightness:
CCP1CON.4 = PWMDuty.0
CCP1CON.5 = PWMDuty.1
CCPR1L = PWMDuty >> 2
RETURN
Bookmarks