; title "led_ppm.asm" ; LED Peak Program Level Meter with 24 LEDs and 48 dB range using AD8307, PIC12F617 and HEF4094B ; 210225 v0.1 First giraffe ; 210226 v0.2 A/D (note: fix GO bit in p12f617.inc) ; 210226 v0.3 LED24 level test (UNDERFLOW) ; 210226 v0.4 Max Hold and decay ; 210226 v0.5 left justify A/D result to fix underflow ; 210226 v0.6 1 dB steps, 10 dB markings ; 210226 v0.7 A/D conversions interruptized ; 210227 v0.8 That didn't work well... Outputs went crazy! Clockcycle spikes, bar haywire, WTF! ; 210228 v1.0 Release. Still some aliasing at 1.83 kHz but it is about 2 dB. ; GPL Copyleft 2021 pic@polonai.se LIST P=12F617, F=INHX8M #include <p12f617.inc> __CONFIG _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_ON & _CP_OFF & _IOSCFS_8MHZ & _BOR_OFF ERRORLEVEL -302 ; sod compiler message about using proper bank ; Equates RESET_V EQU 0x00 ; Address of RESET Vector ; Registers TEMP EQU 0x20 ; TEMP register HEF1 EQU 0x21 ; First shift register HEF2 EQU 0x22 ; Second shift register HEF3 EQU 0x23 ; Third shift register d1 EQU 0x24 ; Delay registers used during Lamp Test, decay d2 EQU 0x25 PPM EQU 0x26 ; Value to decode and display LEVEL EQU 0x27 ; Result from A/D Conversions ; GPIO,2 (AN2) input from AD8307 has no name defined #define SDI GPIO,0 ; Serial Data line of HEF4094 #define CLK GPIO,1 ; Clock for HEF4094 (high pulse) #define STRO GPIO,4 ; Strobe for HEF4094 (high pulse) #define OE GPIO,5 ; Output Enable for HEF4094 (active high) #define LED1 HEF1,0 ; Q5 output of HEF1, -2 dB LED #define LED2 HEF1,1 ; Q6 output of HEF1, -4 dB LED #define LED3 HEF1,2 ; Q7 output of HEF1, -6 dB LED #define LED4 HEF1,3 ; Q8 output of HEF1, -8 dB LED #define LED5 HEF1,4 ; Q1 output of HEF1, -10 dB LED #define LED6 HEF1,5 ; Q2 output of HEF1, -12 dB LED #define LED7 HEF1,6 ; Q3 output of HEF1, -14 dB LED #define LED8 HEF1,7 ; Q4 output of HEF1, -16 dB LED #define LED9 HEF2,0 ; Q5 output of HEF2, -18 dB LED #define LED10 HEF2,1 ; Q6 output of HEF2, -20 dB LED #define LED11 HEF2,2 ; Q7 output of HEF2, -22 dB LED #define LED12 HEF2,3 ; Q8 output of HEF2, -24 dB LED #define LED13 HEF2,4 ; Q1 output of HEF2, -26 dB LED #define LED14 HEF2,5 ; Q2 output of HEF2, -28 dB LED #define LED15 HEF2,6 ; Q3 output of HEF2, -30 dB LED #define LED16 HEF2,7 ; Q4 output of HEF2, -32 dB LED #define LED17 HEF3,0 ; Q5 output of HEF3, -34 dB LED #define LED18 HEF3,1 ; Q6 output of HEF3, -36 dB LED #define LED19 HEF3,2 ; Q7 output of HEF3, -38 dB LED #define LED20 HEF3,3 ; Q8 output of HEF3, -40 dB LED #define LED21 HEF3,4 ; Q1 output of HEF3, -42 dB LED #define LED22 HEF3,5 ; Q2 output of HEF3, -44 dB LED #define LED23 HEF3,6 ; Q3 output of HEF3, -46 dB LED #define LED24 HEF3,7 ; Q4 output of HEF3, -48 dB LED org 0x00 GOTO START org 0x04 ; Interrupts ; There are none RETFIE ; Just in case START ;Init stuff CLRF STATUS ; Do initialization, select Bank 0 CLRF INTCON ; Clear int-flags, disable interrupts CLRF PCLATH ; Keep in lower 2KByte BSF STATUS,RP0 ; Select Bank 1 CLRF OPTION_REG ; TMR0 prescaler 1:2 (256 µs) MOVLW B'00001100' ; GPIO2,3 inputs, all others outputs MOVWF TRISIO MOVLW B'00001100' ; Enable weak pull-ups on GPIO2,3 MOVWF WPU MOVLW B'01010100' ; 2 µs conversion (Fosc/16), AN2 analog input MOVWF ANSEL BCF STATUS,RP0 ; Select Bank 0 MOVLW B'00001001' ; A/D AN2, left justify (ADRESL:7,6 in Bank 1) MOVWF ADCON0 MOVWF LEVEL ; LEVEL should not be zero due to LEVEL decay CLRF GPIO CLRF HEF1 CLRF HEF2 CLRF HEF3 CALL LAMPTEST MAIN CALL MEASURE MOVFW LEVEL ; Get LEVEL MOVWF PPM ; Save LEVEL to PPM BCF LED1 ; Test PPM for LED1 ADDLW 0x06 BTFSC STATUS,C BSF LED1 MOVFW PPM BCF LED2 ADDLW 0x0B BTFSC STATUS,C BSF LED2 MOVFW PPM BCF LED3 ADDLW 0x10 BTFSC STATUS,C BSF LED3 MOVFW PPM BCF LED4 ADDLW 0x16 BTFSC STATUS,C BSF LED4 MOVFW PPM BCF LED5 ADDLW 0x1A BTFSC STATUS,C BSF LED5 MOVFW PPM BCF LED6 ADDLW 0x1F BTFSC STATUS,C BSF LED6 MOVFW PPM BCF LED7 ADDLW 0x24 BTFSC STATUS,C BSF LED7 MOVFW PPM BCF LED8 ADDLW 0x29 BTFSC STATUS,C BSF LED8 CALL MEASURE ; Extra measurement to prevent aliasing MOVFW PPM BCF LED9 ADDLW 0x2F BTFSC STATUS,C BSF LED9 MOVFW PPM BCF LED10 ADDLW 0x34 BTFSC STATUS,C BSF LED10 MOVFW PPM BCF LED11 ADDLW 0x39 BTFSC STATUS,C BSF LED11 MOVFW PPM BCF LED12 ADDLW 0x3E BTFSC STATUS,C BSF LED12 MOVFW PPM BCF LED13 ADDLW 0x44 BTFSC STATUS,C BSF LED13 MOVFW PPM BCF LED14 ADDLW 0x49 BTFSC STATUS,C BSF LED14 MOVFW PPM BCF LED15 ADDLW 0x4E BTFSC STATUS,C BSF LED15 MOVFW PPM BCF LED16 ADDLW 0x53 BTFSC STATUS,C BSF LED16 MOVFW PPM BCF LED17 ADDLW 0x59 BTFSC STATUS,C BSF LED17 MOVFW PPM BCF LED18 ADDLW 0x5F BTFSC STATUS,C BSF LED18 MOVFW PPM BCF LED19 ADDLW 0x65 BTFSC STATUS,C BSF LED19 MOVFW PPM BCF LED20 ADDLW 0x6B BTFSC STATUS,C BSF LED20 MOVFW PPM BCF LED21 ADDLW 0x71 BTFSC STATUS,C BSF LED21 MOVFW PPM BCF LED22 ADDLW 0x78 BTFSC STATUS,C BSF LED22 MOVFW PPM BCF LED23 ADDLW 0x80 BTFSC STATUS,C BSF LED23 MOVFW PPM BCF LED24 ADDLW 0x87 BTFSC STATUS,C BSF LED24 CALL MEASURE CALL Show GOTO MAIN ; Subroutines Show ; Fill shift register BCF OE ; Disable (Hi-Z) outputs HEF chip to prevent ghosting BTFSC LED20 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED20 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED19 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED19 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED18 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED18 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED17 ; Bit clear? BSF SDI ; Clear Data Line BTFSS LED17 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED24 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED24 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED23 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED23 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED22 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED22 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED21 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED21 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit CALL MEASURE ; Extra measurement to prevent aliasing BTFSC LED12 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED12 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED11 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED11 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED10 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED10 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED9 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED9 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED16 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED16 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED15 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED15 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED14 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED14 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED13 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED13 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED4 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED4 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED3 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED3 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED2 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED2 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED1 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED1 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED8 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED8 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED7 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED7 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED6 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED6 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BTFSC LED5 ; Bit clear? BSF SDI ; No, set Serial Data Line BTFSS LED5 ; Bit set? BCF SDI ; No, clear Serial Data Line BSF CLK BCF CLK ; Output bit BSF STRO BCF STRO ; Strobe latch BCF SDI ; Clear Data Line BSF OE ; Done shift register, enable outputs RETURN MEASURE ; Measure LEVEL (9 bit A/D) BSF ADCON0,GO ; Start A/D (read LEVEL) CONV0 NOP BTFSC ADCON0,GO ; Test if A/D conversion done GOTO CONV0 BTFSC ADRESH,7 ; Input > 2.50 V? GOTO OVERFLOW BSF STATUS,RP0 ; Select Bank 1 MOVFW ADRESL ; Get A/D result BCF STATUS,RP0 ; Select Bank 0 MOVWF TEMP ; Save measurement LEVEL RLF TEMP,F ; Rotale MSB into carry RLF ADRESH,W ; Rotate carry and ADRESH into W MOVWF TEMP ; Save for max hold DECFSZ d1,F ; Decay counter looped? GOTO MAXH ; No DECFSZ LEVEL ; Decay level GOTO MAXH INCF LEVEL,F ; Ensure LEVEL doesn't become zero MAXH ; Max Hold routine MOVFW TEMP ; Get new measurement SUBWF LEVEL,W ; Subtract W from LEVEL and keep in W BTFSC STATUS,C ; new measurement larger than LEVEL? RETURN ; No MOVFW TEMP ; Retrieve new measurement again MOVWF LEVEL ; Store new LEVEL RETURN OVERFLOW MOVLW 0xFF MOVWF LEVEL RETURN LONGDLY ; 25 ms delay, used with Lamp Test MOVLW 0x14 MOVWF d2 LONGDLY_0 DECFSZ d1,F GOTO $+2 DECFSZ d2,F GOTO LONGDLY_0 NOP RETURN LAMPTEST ; Lamp Test! Yeah! BSF LED24 CALL Show CALL LONGDLY BSF LED23 CALL Show CALL LONGDLY BSF LED22 CALL Show CALL LONGDLY BSF LED21 CALL Show CALL LONGDLY BSF LED20 CALL Show CALL LONGDLY BSF LED19 CALL Show CALL LONGDLY BSF LED18 CALL Show CALL LONGDLY BSF LED17 CALL Show CALL LONGDLY BSF LED16 CALL Show CALL LONGDLY BSF LED15 CALL Show CALL LONGDLY BSF LED14 CALL Show CALL LONGDLY BSF LED13 CALL Show CALL LONGDLY BSF LED12 CALL Show CALL LONGDLY BSF LED11 CALL Show CALL LONGDLY BSF LED10 CALL Show CALL LONGDLY BSF LED9 CALL Show CALL LONGDLY BSF LED8 CALL Show CALL LONGDLY BSF LED7 CALL Show CALL LONGDLY BSF LED6 CALL Show CALL LONGDLY BSF LED5 CALL Show CALL LONGDLY BSF LED4 CALL Show CALL LONGDLY BSF LED3 CALL Show CALL LONGDLY BSF LED2 CALL Show CALL LONGDLY BSF LED1 CALL Show CALL LONGDLY BCF LED24 CALL Show CALL LONGDLY BCF LED23 CALL Show CALL LONGDLY BCF LED22 CALL Show CALL LONGDLY BCF LED21 CALL Show CALL LONGDLY BCF LED20 CALL Show CALL LONGDLY BCF LED19 CALL Show CALL LONGDLY BCF LED18 CALL Show CALL LONGDLY BCF LED17 CALL Show CALL LONGDLY BCF LED16 CALL Show CALL LONGDLY BCF LED15 CALL Show CALL LONGDLY BCF LED14 CALL Show CALL LONGDLY BCF LED13 CALL Show CALL LONGDLY BCF LED12 CALL Show CALL LONGDLY BCF LED11 CALL Show CALL LONGDLY BCF LED10 CALL Show CALL LONGDLY BCF LED9 CALL Show CALL LONGDLY BCF LED8 CALL Show CALL LONGDLY BCF LED7 CALL Show CALL LONGDLY BCF LED6 CALL Show CALL LONGDLY BCF LED5 CALL Show CALL LONGDLY BCF LED4 CALL Show CALL LONGDLY BCF LED3 CALL Show CALL LONGDLY BCF LED2 CALL Show CALL LONGDLY BCF LED1 CALL Show CALL LONGDLY RETURN END