Scenix Bargraph.src
; ******************************************************************************
; 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: 2025/1/12 03:38,
|
| ©2025 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://linistepper.com/techref/scenix/bargraph.src"> scenix bargraph</A> |
Did you find what you needed?
|