;Ameer Ali & Paul Lahham ;EE476 Final Project - Hummer Receiver .include "c:\avrtools\appnotes\8535def.inc" .def save =r1 ;SREG temp reg .def temp =r16 ;temporary register .def RXcode =r17 ;received opcode .def DACin =r19 ;used to output to spd DAC .def count =r20 ;timer0 count .def RXtimes =r21 ;debouncing counter for init code .equ baud12 = 207 ;1200 baud constant for 4Mhz crystal .equ D_F = 0 ;PortC0-3 used for forward speed .equ D_R = 1 ;PortC4-7 used for reverse speed .equ SVO = 7 ;Servo control bit = PORTD7 ;Light 1 .equ L1G_F = 0 ;green = forward .equ L1R_R = 1 ;red = reverse ;Light 2 .equ L2G_R = 2 ;green = right .equ L2R_L = 3 ;red = left .equ init_code = 0b10010000 .equ cycle = 10750 ;so each cycle is 20 millisecs .equ cyc = 750 ;add 1.5ms, pulse off for 20ms ;***** Initialization .cseg .org $0000 rjmp RESET ;reset entry vector reti reti reti reti reti rjmp T1CompA rjmp T1CompB reti rjmp T1ov reti rjmp RXdone ;UART receive done reti reti reti reti reti StrTR: ;3 different steering magnitudes, OCR1B (TABLE OF OFF TIMES) .db high(9200+cyc), low(9200+cyc) .db high(9150+cyc), low(9150+cyc) .db high(9100+cyc), low(9100+cyc) ;turn right all the way StrTL: ;3 different steering magnitudes, OCR1B (TABLE OF OFF TIMES) .db high(9300+cyc), low(9300+cyc) .db high(9350+cyc), low(9350+cyc) .db high(9400+cyc), low(9400+cyc) ;turn left all the way SpdV: ;15 different speed voltages .db 0b00000000 .db 0b00001100 ;1.875V .db 0b00001101 ;2.03V .db 0b00001111 ;2.34V .db 0b00010000 ;2.5V .db 0b00010001 ;2.656V .db 0b00010011 ;2.969V .db 0b00010100 ;3.125V .db 0b00010110 ;3.4375V .db 0b00011000 ;3.75V .db 0b00011001 ;3.906V .db 0b00011010 ;4.06V .db 0b00011011 ;4.218V .db 0b00011101 ;4.53V .db 0b00011111 ;5V RESET: ldi temp, LOW(RAMEND) ;setup stack pointer out SPL, temp ldi temp, HIGH(RAMEND) out SPH, temp ;setup UART -- enable RX ISR & pin ;9 bits enabled ldi temp, 0b10010000 out UCR, temp ;set baud rate to 1200 ldi temp, baud12 out UBRR, temp ;Enable timer1 compare A & B match interrupt ldi temp, 0b00011001 out TIMSK, temp ;prescale timer1 by 8 & clear on matchA ldi temp, 0b00001010 out TCCR1B, temp ;each tick = 2 microsec ;T0 prescale by 256 ldi temp, 0b00000100 out TCCR0, temp ldi temp, high(cycle) out OCR1AH, temp ldi temp, low(cycle) out OCR1AL, temp ;give OCR1B an initial value to center servo ldi temp, high(cycle-750) ; 750*2usec=1.5msec out OCR1BH, temp ldi temp, low(cycle-750) out OCR1BL, temp ;PortD as output & power for Receiver ser temp out DDRD, temp ;PORTC as a output for rear motor ser temp out DDRC, temp clr temp out PORTC, temp ;turn it off ;PORTB as output to LED's (** For testing **) ser temp out DDRB, temp out PORTB, temp ;turn them off ;PORTA as output for RED-GREEN LIGHTS out DDRA, temp clr temp out PORTA, temp ;turn them off out TCNT1H, temp out TCNT1L, temp clr RXcode clr RXtimes sei ;enable all interrupts winit: clr count winit_: cpi count, 32 breq turnoff cpi RXcode, init_code ;wait for init code brne winit_ clr RXtimes idle_wait: cpi RXtimes, 50 brne idle_wait cpi RXcode, init_code breq wcode turnoff:ldi RXcode, 0 rjmp ex_code wcode: cpi RXcode, init_code breq wcode ;wait for code to change ex_code:cbi UCR, RXCIE ;disable UART RX ISR mov temp, RXcode andi temp, 0b00001111 ;get and set speed breq no_spd sbrs RXcode, 4 sbi PORTA, L1R_R sbrs RXcode, 4 cbi PORTA, L1G_F ;turn on reverse light sbrc RXcode, 4 cbi PORTA, L1R_R sbrc RXcode, 4 sbi PORTA, L1G_F ;turn on forward light rjmp _spd no_spd: cbi PORTA, L1R_R cbi PORTA, L1G_F ;turn on forward light _spd: out PORTB, RXcode mov temp, RXcode andi temp, 0b00001111 ;get and set speed cpi temp, 0b00001111 breq ful_spd lsl temp ldi ZL, low(SpdV*2) ldi ZH, high(SpdV*2) add ZL, temp ;index into table based on RX mag. clr temp adc ZH, temp lpm ;r0 mov DACin, r0 sbrs RXcode, 4 breq rev fwd: ldi temp, 0b10111111 ;Set c6 as input out DDRC, temp out PORTC, DACin ;pullup on c6 turned off automatically rjmp spd_done rev: ldi temp, 0b01111111 ;Set c7 as input out DDRC, temp out PORTC, DACin rjmp spd_done ful_spd:;Forward at full speed sbrc RXcode, 4 ldi DACin, 0b01000000 sbrc RXcode, 4 rjmp rev ;Backward at full speed ldi DACin, 0b10000000 rjmp fwd spd_done: ;get and set steering mov temp, RXcode andi temp, 0b01100000 brne str ;if magn. of str=0, center the servo (1.5ms pulses) ldi temp, high(cycle-750) out OCR1BH, temp ldi temp, low(cycle-750) out OCR1BL, temp cbi PORTA, L2G_R ;turn on right light cbi PORTA, L2R_L rjmp done str: lsr temp ;shift to get integer value lsr temp lsr temp lsr temp ;*2, since 2 bytes per entry subi temp, 2 ;since there is no zero case sbrs RXcode, 7 rjmp strL ldi ZL, low(StrTR*2) ldi ZH, high(StrTR*2) add ZL, temp ;index into table based on RX mag. clr temp adc ZH, temp lpm ;r0 sbi PORTA, L2G_R ;turn on right light cbi PORTA, L2R_L rjmp str_done strL: ldi ZL, low(StrTL*2) ldi ZH, high(StrTL*2) add ZL, temp ;index into table based on RX mag. clr temp adc ZH, temp lpm ;r0 cbi PORTA, L2G_R ;turn on left light sbi PORTA, L2R_L str_done: out OCR1BH, r0 ;get values and place adiw ZL, 1 ;them in OCR1B lpm ;r0 out OCR1BL, r0 done: sbi UCR, RXCIE ;now enable UART RX ISR rjmp winit ;======================================================================== ;======================================================================== ;***************************** ;interrupt routines ;**** Receive complete interrupt RXdone: in save, SREG ;save processor status in RXcode, UDR ;Read received byt into register inc RXtimes out SREG, save ;restore proc status reti ;back to pgm ;***************************** ;***************************** ;**** TIMER 1 compare B ;counts off time, this ISR turns front servo T1CompB:in save, SREG sbi PORTD, SVO ;enable servo pulse out SREG, save reti ;************************************** ;**** TIMER 1 compare A ;counts on time, this ISR turns front servo T1CompA:in save, SREG cbi PORTD, SVO ;disable servo pulse out SREG, save reti ;************************************** T1ov: in save, SREG inc count out SREG, save reti ;**************************************