; lightSensor.asm ; ; Ryan Castonia ; December 2009 ; ; light sensor code for weightlifting power meter. See http://fab.cba.mit.edu/classes/MIT/863.09/people/ryan/index.htm .include "tn44def.inc" ; ; definitions ; .equ commPin = PA0 .equ LEDPin = PB2 .equ checkValue = 750 ; ; registers ; .def bitcnt = R16; bit counter .def temp = R17; temporary storage .def temp1 = R18; temporary storage .def txbyte = R19; data byte .def ADOutput = R20 .def velocity = R21 .def flag = R22 .def previous = R23 ; ; code segment ; .cseg .org 0 rjmp reset ;counter/timer output compare A interrupt .org 6 ; compare current velocity count with previous value mov temp, velocity mov temp1, previous cpc temp, temp1 ; if the current value is lower, print the previous value brlo print ; otherwise, move the current value into the previous value mov previous, velocity clr velocity sei rjmp main_loop print: ; send the highest velocity count recieved during the lift mov txbyte, previous rcall putchar clr velocity clr previous sei rjmp main_loop ; ; half_bit_delay ; serial half bit delay ; half_bit_delay: ldi temp, 100 half_bit_delay_loop: dec temp brne half_bit_delay_loop ret ; ; putchar ; assumes no line driver (doesn't invert bits) ; putchar: ldi bitcnt, 10; 1 start + 8 data + 1 stop bit com txbyte; invert everything sec; set start bit putchar0: brcc putchar1; if carry set sbi PORTA, commpin; send a '0' rjmp putchar2; else putchar1: cbi PORTA, commpin ; send a '1' nop; even out timing putchar2: rcall half_bit_delay; bit delay rcall half_bit_delay; " lsr txbyte; get next bit dec bitcnt; if not all bits sent brne putchar0; send next bit ret; ; ; main program ; reset: ; ; set stack pointer to top of RAM ; ldi temp, high(RAMEND) out SPH, temp ldi temp, low(RAMEND) out SPL, temp ; ; init comm pin and LED pin for output ; sbi PORTA, commPin sbi DDRA, commPin sbi PORTB, LEDPin sbi DDRB, LEDPin ; ; init A/D for the sensor pin ; cbi ADMUX, REFS1 ; use Vcc as reference cbi ADMUX, REFS0 ; " cbi ADMUX, ADLAR ; right-adjust result cbi ADMUX, MUX5 ; set MUX to ADC7 (PA7) cbi ADMUX, MUX4 ; " cbi ADMUX, MUX3 ; " sbi ADMUX, MUX2 ; " sbi ADMUX, MUX1 ; " sbi ADMUX, MUX0 ; " sbi ADCSRA, ADEN ; enable A/D cbi ADCSRA, ADPS2 ; set prescaler to /2 cbi ADCSRA, ADPS1 ; " cbi ADCSRA, ADPS0 ; " ; allow timer/counter interrupt sei ldi temp, (1 << OCIE1A) ; output compare A out TIMSK1, temp ; set up 16bit counter1 with clock/64 and CTC ldi temp1, (1 << WGM12) | (0 << CS12) | (1 << CS11) | (1 << CS10) out TCCR1B, temp1 ; set Output Compare Register A value (1/4 sec) ldi temp, 16 ldi temp1, 0 out OCR1AH, temp out OCR1AL, temp1 sbi PORTB, LEDPin ldi previous, 0 ; ; start main loop ; main_loop: sbi ADCSRA, ADSC ; start conversion AD_loop: sbic ADCSRA, ADSC ; loop until complete rjmp AD_loop rcall update rjmp main_loop update: in ADOutput, ADCL ; low byte in ADOutput, ADCH ; hi byte ldi temp, high(checkValue) cpc temp, ADOutput brsh lightOn rjmp lightOff ; these methods make sure that the rotary encoder properly counts the teeth lightOn: ldi flag, 0 rjmp main_loop lightOff: sbrs flag, 0 rjmp up rjmp main_loop up: inc velocity ldi flag, 1 rjmp main_loop