| CODE |
;Ameer Ali & Paul Lahham ;EE476 Final Project - Hummer Transmitter .nolist .include "c:\avrtools\appnotes\8535def.inc" .list .def save =r1;SREG temp reg .def temp =r16;temporary register .def AnaLo =r17;A to D result .def AnaHi =r18 .def opcode =r19 .def sendcode =r20 .equ samp_rate = 500 ;sample and send every 1000 milliseconds (up to 4194) .equ baud12 =207 ;1200 baud rate for wireless transmission .equ init_code = 0b10010000 ; *** MACROS *** ; Set OCR1A using sampling rate .MACRO SET_OCR1A ldi temp, HIGH((@0*1000)/64) out OCR1AH, temp ldi temp, LOW((@0*1000)/64) out OCR1AL, temp .ENDMACRO ;Returns opcode for given channel in top nibble of AnaLo .MACRO GET_OPCODE in AnaLo, ADCL in AnaHi, ADCH lsr AnaHi ror AnaLo lsr AnaHi ror AnaLo ldi temp, 0b01111000 sbrs AnaLo, 7 ;if bit 7 is off eor AnaLo, temp ;flip bits 5,6 andi AnaLo, 0b11111000 .ENDMACRO ;***** Initialization .cseg .org $0000 rjmp RESET;reset entry vector reti reti reti reti reti rjmp t1match reti reti reti reti reti reti reti reti reti reti RESET: ldi temp, LOW(RAMEND);setup stack pointer out SPL, temp ldi temp, HIGH(RAMEND) out SPH, temp ;set up port B to run LEDS ser temp ;set PORTB to be out DDRB,temp;all outputs to LEDs out PORTB, temp ;enable TX and set baud rate at 1200 ldi temp, 0b00001000 out UCR, temp ldi temp, baud12 out UBRR, temp ;set up Timer 1 to interrupt on compare A match ;and set the compare time to 62500 ticks ldi temp,0b00010000;enable t1 matchA interrupt out TIMSK, temp SET_OCR1A samp_rate ldi temp,0b00001100;prescale timer by 256 (one tick=64 microsec) out TCCR1B, temp;and clear-on-matchA ;enable analog converter and set at 125kHz ldi temp, 0b10000101 out ADCSR, temp clr sendcode sei;enable all interrupts ;Send synchronization sequence to receiver ;*** Rear wheel speed reading *** ADC_sta:;set up analog converter to read channel zero ldi temp, 0 out ADMUX, temp ch0_sta:sbis ADCSR, ADSC;Start conversion when ADSC bit is set rjmp ch0_sta ;this bit is set by t1match interrupt ch0_end:sbic ADCSR, ADSC;Wait for A to D done by checking is ADSC if cleared rjmp ch0_end ;this bit is cleared by the AtoD hardware GET_OPCODE lsr AnaLo lsr AnaLo lsr AnaLo mov opcode, AnaLo ;*** Front wheel direction reading *** ch1_sta:ldi temp, 4 ;switch to channel 4 out ADMUX, temp sbi ADCSR, ADSC;Start A to D conversion on Ch1 ch1_end:sbic ADCSR, ADSC;Wait for A to D done by checking if ADSC is cleared rjmp ch1_end ;this bit is cleared by the AtoD hardware GET_OPCODE andi AnaLo, 0b11100000;only need top 3 bits of direction or opcode, AnaLo ldi temp, init_code clr sendcode send_init: out UDR, temp tst sendcode breq send_init mov temp, opcode com temp out PORTB, temp clr sendcode send_op:out UDR, opcode tst sendcode breq send_op rjmp ADC_sta ;**** timer 1 compare A match 1/sec t1match:in save, SREG ser sendcode sbi ADCSR, ADSC;start ADC conversion out SREG, save reti |
| CODE |
;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 ;************************************** |