The following project introduces a software for the Atmel TINY15 Controller, that allows 3 LED's to be controlled by a analog voltage from 0.. 2.5V, ideally suited for monitoring and indicator purposes, like fan RPM, temperature, voltage...
This program uses a number of techniques that may be useful in other projects:
Reading and writing of EEPROM
Timer-Interrupt
Software-Counter
Usage of the AD-Converter
Moving Average Digital filter
Usage:
Connect your RGB-LED or three separate LED's to Pin PB0-PB2 (with current limiting resistors of course!)
A pushbutton switch is connected to PB3. The analog Signal is routed to PB4, preferably through a RC Lowpass 100k/100nF
The Main loop of the program generates the PWM Signal for 3 Channels. The Timer Interrupt reads the AD Converter, a Moving average digital filter smoothens the input signal, and a lookup table implements a physiological brightnes correction.
The following functions are implemented:
Pushing the button once for s short period of time changes the order in which the LED's begin to light up. There are 6 possibilities:
RED-GREEN-BLUE
RED-BLUE-GREEN
BLUE-RED-GREEN
BLUE-GREEN-RED
GREEN-RED-BLUE
GREEN-BLUE-RED
pressing the button for more then 3 seconds makes the change permanent, stored in the internal EEPROM
When pressing the button during power-up, the polarity of the output signal is inverted, to provide simple interfacing to driver stages or using LED's with common cathode or anode.
Program developed with AVR Studio 4.10.
When programming, store the OSCCAL-value in EEPROM-Cell $3f ;
Complete sourcecode available on request here .
| ;Voltage Control RGB ;(C) 2004 Markus Vohburger Only for private purposest ;Definitionen für Tiny15 .include "tn15def.inc" ;Programmvariablen .def pwmcount = r01 .def pwmvalue_1 = r02 .def pwmvalue_2 = r03 .def pwmvalue_3 = r04 .def mode_1=r05 .def mode_2=r06 .def mode_3=r07 .def omod=r08 .def sbuffer=r09 .def temp1 = r16 .def temp2 = r17 .def output = r18 .def swcount=r19 .def mode=r20 ;movin' average filter .def adcold1 = r23 .def adcold2 = r24 .def adcold3 = r25 .equ EE_MODE = $00 .equ EE_OMOD = $01 .equ EE_OSCCAL = $3f .equ timer_value = $80 ;reset handler .org $0000 rjmp main ;timer overflow interrut handler .org T0OVAddr rjmp T0OVHandler .org $0010 main: ;read osccal byte ldi temp1,EE_OSCCAL rcall readeeprom out osccal,temp1 ldi temp1,$07 out ddrb,temp1 ;port b output LED's Off,, pullup on pb3 ldi temp1,$0f out portb,temp1 ldi temp1,EE_MODE rcall readeeprom cpi temp1,$06 brlo mode_ok ldi temp1,$00 mode_ok: mov mode,temp1 rcall readsettings ldi temp1,EE_OMOD rcall readeeprom cpi temp1,$00 breq omod_ok cpi temp1,$07 breq omod_ok ldi temp1,$00 omod_ok: mov omod,temp1 ;Taster an PB3 überprüfen sbic pinb,pb3 rjmp no_omod_change ldi temp1,$07 eor omod,temp1 ;Mode umschalten ldi temp1,EE_OMOD mov temp2,omod rcall writeeeprom ;port setup ;port pb0,1,2 outputs no_omod_change: notoggle: ;Timer zurücksetzen ldi temp1,timer_value out tcnt0,temp1 ;Timer interrupts an ldi temp1,(1<<toie0) out timsk,temp1 ;Timer starten ldi temp1,0b00000100 out tccr0,temp1 rcall init_adc clr swcount sei ;Hauptschleife für PWM loop: ;leds aus ldi output,$0f cp pwmvalue_1,pwmcount brsh check_green ;leds an and output,mode_1 check_green: cp pwmvalue_2,pwmcount brsh check_blue ;leds an and output,mode_2 check_blue: cp pwmvalue_3,pwmcount brsh writeoutput ;leds an and output,mode_3 writeoutput: eor output,omod out portb,output inc pwmcount brne loop inc pwmcount rjmp loop ;Timer Interrupt T0OVHandler: ;Status sichern in sbuffer,sreg ;AD-Wandler lesen in temp1,adch ;dividieren lsr temp1 lsr temp1 lsr temp1 ;Moving Average Filter mov temp2,temp1 add temp1,adcold1 adc temp1,adcold2 adc temp1,adcold3 mov adcold3,adcold2 mov adcold2,adcold1 mov adcold1,temp2 lsr temp1 lsr temp1 ;pwm-lookup table clr r0 ldi zl,low(table_pwm_1<<1) ldi zh,high(table_pwm_1<<1) add zl,temp1 adc zh,r0 lpm com r0 mov pwmvalue_1,r0 clr r0 ldi zl,low(table_pwm_2<<1) ldi zh,high(table_pwm_2<<1) add zl,temp1 adc zh,r0 lpm com r0 mov pwmvalue_2,r0 clr r0 ldi zl,low(table_pwm_3<<1) ldi zh,high(table_pwm_3<<1) add zl,temp1 adc zh,r0 lpm com r0 mov pwmvalue_3,r0 ;Taster abfragen sbic pinb,pb3 rjmp releasehandler cpi swcount,$20 brsh exit_ovf0Handler inc swcount exit_ovf0Handler: out sreg,sbuffer reti ;write mode to eeprom releasehandler: cpi swcount,$20 breq writemode ignore short pulses cpi swcount,$02 brsh key_valid clr swcount rjmp exit_ovf0handler Tables initializing routines etc...
Complete sourcecode available on request here . |
Additional Information,Basics,DIY Kit, Links for Schematic
Sponsored Ads: