; ****************************************************************************** ; Pulse Width Modulated 'Linear' LED Bar Graph Display - (c) 1998 ; ; ; Length: 87 bytes ; Author: Craig Webb ; Written: 97/02/26 ; ; This program implements two virtual peripherals using interrupts. ; It shows to read a potentiometer as an 8 bit value and pulse width ; modulate a bar-graph of 16 LEDs arranged in a 4x4 matrix on port B ; in order to provide a smooth 'sliding' signal effect by varying the ; brightness of adjacent LEDs when the potentiometer 8 bit value lies ; somewhere between them. ; ; ;****************************************************************************** ; ;****** Assembler directives ; DEVICE pins18,pages1,banks8,stackx,optionx DEVICE osc4mhz,turbo ID '16 LEDs' RESET Start ;set reset/boot address ; ;******************************* Program Variables *************************** ; ;****** Register definitions (bank 0) ; ORG 08h ;global variables 08-0Fh reading DS 1 ;potentiometer reading display DS 1 ;LED display output level flags DS 1 ;program flags ; ; variables for LED interrupt routine ; ORG 10h ;bank 0 variables mainbank EQU $ ; LED_bank EQU $ ;(can be other than bank 0) LED DS 1 ;holds which LED to light cycle_count DS 1 ;pwm cycle count pot_count DS 1 ;temporary pot timing count clear_delay DS 1 ;delay period to clear cap. sample_delay DS 1 ;delay period per sample ; (reduces power consumption) ; ;****** Bit variable definitions ; pot EQU RA.0 ;potentiometer in RC (input) triggered EQU flags.0 ;status of pot. reading clearing EQU flags.1 ;hi while cap. is clearing ; ;****** Constants ; sample_time = 2 ;time between pot. readings clear_time = 45 ;delay value for clearing ; the capacitor (>=2) int_period = 200 ;interrupt period (based ; on RTCC counts) IO_portA = 00001111b ;Port A input/output setup LEDs_off = 0Fh ;RB value for LEDs=off ; ;************************* Interrupt Routines **************************** ; ORG 0 ; ;***** Virtual Peripheral : Read potentiometer ; ; This routine reads the value of the potentiometer by clearing the ; capacitor in the RC timing circuit and then measuring the time it takes ; the capacitor to charge until the port input goes high. To avoid high ; current draws at low potentiometer values, the routine only resamples ; after (256*sample_time) interrupt cycles. The maximum potentiometer ; reading is 255. ; ; Input variable(s) : none ; Output variable(s) : reading ; Variable(s) affected : pot_count, clear_delay, sample_delay ; Flag(s) affected : clearing, triggered ; Timing cycles (turbo) : 12-charging, 14-triggered, 14-clearing ; JNB clearing,:charge ;are we clearing cap.? MOV W,#11111111b ;get port mask (=done) DECSZ clear_delay ;is count done? MOV W,#11111110b ;no, get port mask (=clearing) TEST clear_delay ;is count done? SNZ ;if not, skip ahead CLRB clearing ;yes, reset clearing flag AND W,#IO_portA ;get port setup byte MOV !RA,W ;adjust pot port status CLR pot_count ;clear timing count JMP :done_pot ;jump past checking routine :charge JNB pot,:adjust_count ;triggered yet? MOV W,pot_count ;get timing count SB triggered ;is this first trigger cycle? MOV reading,W ;yes, store result SETB triggered ;set trigger flag :adjust_count INCSZ pot_count ;adjust reading counter JMP :done_pot ;was counter at maximum? MOV W,#255 ;no, store max. value SB triggered ;did we already get reading? MOV reading,W ;no, so set it to max. SETB triggered ; and flag that we got value DECSZ sample_delay ;time for new sample? JMP :done_pot ;if not, keep cycling :trig CLRB triggered ;yes, reset trigger flag SETB clearing ;set flag to clear cap. MOV sample_delay,#sample_time ;load sample and MOV clear_delay,#clear_time ; clear delay time counts :done_pot ;end of pot. reading routine ; ; ;***** Virtual Peripheral : LED driver ; ; This routine drives the LED bar-graph array, providing 16 levels ; of brightness to allow an output slide effect between adjacent LEDs ; It must be called fairly often, otherwise the pulsing effect will ; become noticeable. ; ; Input variable(s) : display ; Output variable(s) : none ; Variable(s) affected : cycle_count, LED ; Timing cycles (turbo) : 21 ; ;next instruction needed only if multiple variable banks are used ; MOV W,<>display ;get input (nibble-swapped) AND W,#0Fh ;keep high 4 bits (which LED) MOV LED,W ;save it MOV W,display ;get input level again AND W,#00001111b ;keep lower 4 bits for PWM MOV W,cycle_count-W ;calculate which LED to have on :zero_point SZ ;adjust zero baseline up one* SC ;next one up? If not skip ahead INC LED ;yes, increment to next LED MOV W,LED ;get LED number CALL LED_Table ;fetch LED value MOV RB,W ;light LED INC cycle_count ;adjust PWM cycle SNB cycle_count.4 ;time to reset (16 cycles)? CLR cycle_count ;yes, start new cycle ; ;*this instruction shifts the whole display range up by one, thus making the ; first LED dimly lit on a reading of 0, and the last lit fully on a reading ; of 255. If it's preferable that all LEDs be off on a reading of 0, this ; instruction may be removed or commented out. ; ; MOV W,#-int_period ;interrupt again after RETIW ; 'int_period' RTCC counts ; ;******************************* Subroutines ********************************* ; ; ;***** Subroutine : LED_Table ; ; This is a look-up table that returns the output port value to light the LED ; contained in the W register. If W holds 0, then all LEDs are turned off. ; LED_Table ADD PCL,W ;get RB value for LED1-16 RETW 0Fh ;LEDs all off RETW 1Eh ;LED1 RETW 2Eh ;LED2 RETW 4Eh ;LED3 RETW 8Eh ;LED4 RETW 1Dh ;LED5 RETW 2Dh ;LED6 RETW 4Dh ;LED7 RETW 8Dh ;LED8 RETW 1Bh ;LED9 RETW 2Bh ;LED10 RETW 4Bh ;LED11 RETW 8Bh ;LED12 RETW 17h ;LED13 RETW 27h ;LED14 RETW 47h ;LED15 RETW 87h ;LED16 ; ; ;********************************* Main Program ******************************* ; ;***** Initialization routine ; Start CLR RA ;clear port A MOV !RA,#IO_portA ;set up port A MOV RB,#LEDs_off ;set all LEDs off MOV !RB,#0 ;configure port B as outputs CLR FSR ;reset all ram starting at 08h :zero_ram SB FSR.4 ;are we on low half of bank? SETB FSR.3 ;If so, don't touch regs 0-7 CLR IND ;clear using indirect addressing IJNZ FSR,:zero_ram ;repeat until done MOV !OPTION,#10001000b ;enable interrupt on rtcc=xtal/1 MOV sample_delay,#sample_time ;load sampling period ; ;***** Main program loop ; Mainloop ; MOV display,reading ;copy pot. to LED ouput ; ; <program code goes here> ; JMP Mainloop ;keep looping ; END
file: /Techref/scenix/bargraph.src, 6KB, , updated: 1999/6/14 10:18, local time: 2024/12/2 12:45,
18.97.9.168:LOG IN
|
©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://massmind.org/techref/scenix/bargraph.src"> scenix bargraph</A> |
Did you find what you needed? |
Welcome to massmind.org! |
Welcome to massmind.org! |
.