;Blair Lee ;John McDonald ;EE 476 Final Project ;RC Car - TRANSMITTER ;PORTA ;PORTB ;PORTC ;PORTD
is is is is
used used used used
for for for for
speed control input. pushbutton input. steering control input. serial output.
.include "4414def.inc" .def .def .def .def .def .def .def .def .def .def .def .def .def
savSREG =r16 TXbusy =r17 TXflash =r18 command =r19 temp =r20 Volt =r21 Count =r22 LEDReg =r23 debounce =r24 DBcnt =r25 status =r26 release =r27 temp2 =r28
.equ .equ .equ .equ .equ .equ .equ .equ .equ
baud96 =25 SpdMid =0x0c StrMid =0x0c FwdOffset=0xfd RevOffset=0xfc LftOffset=0xfd RgtOffset=0xfd OFF =0x00 ON =0xff
.equ .equ .equ .equ
AADCDO AADCCLK AADCCS AADCDI
=1 =2 =3 =4
;ADC ;ADC ;ADC ;ADC
data out clock chip-select data in
.equ .equ .equ .equ
CADCDO CADCCLK CADCCS CADCDI
=1 =2 =3 =4
;ADC ;ADC ;ADC ;ADC
data out clock chip-select data in
.equ .equ .equ .equ
TOP =4 TRIG =5 SWmask =0x30 Maxlights=0x04
.equ .equ .equ .equ .equ
fwdcmd bakcmd lftcmd rgtcmd gocmd
=0x00 =0x10 =0x20 =0x30 =0x40
;save the status register ;transmit busy flag ;text to be sent is in flash if <> 0 ;command register ;general-purpose temporary register ;ADC sample value ;a counter ;register to store LED output (debug) ;debounce ON or OFF ;debounce counter ;running and lights status ;button release register ;another temporary register ;9600 baud constant for 4Mhz crystal ;midpoint for fwd-back control ;midpoint for left-right control ;forward offset ;reverse offset ;left offset ;right offset ;off ;on
;top hat switch ;trigger switch ;switch mask ;nuumber of light modes ;forward prefix ;backward prefix ;left prefix ;right prefix ;lights prefix
.equ
stpcmd
.equ .equ .equ .equ .equ .equ .equ .equ
But1 But2 But3 But4 But5 But6 But7 But8
=0x50
;other prefix
=0x01; =0x02; =0x04; =0x08; =0x10; =0x20; =0x40; =0x80;
;======================================================== ; Toggle ADC Clock - PORTA ;ADC reads and outputs data on falling edge of the clock .MACRO
A_CLOCKPULSE sbi PORTA, AADCCLK nop cbi PORTA, AADCCLK nop .ENDMACRO
;CLK high ;CLK low
;======================================================== ; Toggle ADC Clock - PORTC ;ADC reads and outputs data on falling edge of the clock .MACRO
C_CLOCKPULSE sbi PORTC, CADCCLK nop cbi PORTC, CADCCLK nop .ENDMACRO
;CLK high ;CLK low
;======================================================== ;************************ .dseg ;define variable strings to be tranmitted from RAM cntstr: .byte 2 ;************************ .cseg .org $0000 rjmp reti reti reti reti reti reti reti reti reti rjmp rjmp reti
Reset
;reset entry vector
TXempty ;UART buffer empty TXdone ;UART transmit done
RESET: cli ldi out ldi out
temp, LOW(RAMEND) ;setup stack pointer SPL, temp temp, HIGH(RAMEND) SPH, temp
;initial conditions clr TXbusy
;start out not busy on TX
;setup UART -- enable TXempty & RXdone int, and RX, TX pins ldi temp, 0b00101000 out UCR, temp ;set baud rate to 9600 ldi temp, baud96 out UBRR, temp ;initialize ADCs on ports A and C ldi temp, 0b00011101 out DDRA, temp ldi temp, 0b00001001 out PORTA, temp ldi temp, 0b00011101 out DDRC, temp ldi temp, 0b00001001 out PORTC, temp
;power ADC and set AADCCS ;power ADC and set AADCCS ;power ADC and set CADCCS ;power ADC and set CADCCS
;set up leds on port B ldi temp, 0b00000011 joystick out DDRB, temp out PORTB, temp ;debounce setup clr debounce clr DBcnt clr status
;input from switches on
;debounce on or off ;debounce counter ;initialize car to off
sei ;*********************Setup and Read Speed********************* Getspd: clr Volt ldi Count, 5 ;get top 5 bits A_CLOCKPULSE cbi PORTA, A_CLOCKPULSE sbi PORTA, A_CLOCKPULSE sbi PORTA, A_CLOCKPULSE cbi PORTA, A_CLOCKPULSE
AADCCS
;initiate conversion
AADCDI
;startbit
AADCDI
;single ended
AADCDI
;channel 0
ReadA:
A_CLOCKPULSE clc sbic PINA, AADCDO sec rol Volt dec Count brne ReadA ldi
;set carry if high ;more bits remaining
Count, 8
IgnoreA:A_CLOCKPULSE dec Count brne IgnoreA sbi
;clear carry
;ignore lsb first data
PORTA, AADCCS
;conversion complete
;***********************Transmit Speed*********************** _bakCmd:
cpi brlt cpi breq lsr subi ori mov rjmp
Volt, SpdMid _fwdCmd Volt, SpdMid _stpCmd Volt Volt, RevOffset Volt, bakcmd command, Volt Sendspd
_fwdCmd: ldi sub subi ori mov rjmp
temp, SpdMid temp, Volt temp, FwdOffset temp, fwdcmd command, temp Sendspd
_stpCmd: ldi Sendspd: ; rcall rcall
command, 0x00 LEDSt SendMsg
;********************Setup and Read Steering******************** Getstr: clr Volt ldi Count, 5 ;get top 5 bits C_CLOCKPULSE cbi PORTC, C_CLOCKPULSE sbi PORTC, C_CLOCKPULSE sbi PORTC, C_CLOCKPULSE cbi PORTC,
CADCCS
;initiate conversion
CADCDI
;startbit
CADCDI
;single ended
CADCDI
;channel 0
C_CLOCKPULSE ReadC:
C_CLOCKPULSE clc sbic PINC, CADCDO sec rol Volt dec Count brne ReadC ldi
;set carry if high ;more bits remaining
Count, 8
IgnoreC:C_CLOCKPULSE dec Count brne IgnoreC sbi
;clear carry
PORTC, CADCCS
;ignore lsb first data ;conversion complete
;***********************Transmit Steering*********************** _rgtCmd:
cpi brlt cpi breq lsr subi ori mov rjmp
Volt, StrMid _lftCmd Volt, StrMid _ctrCmd Volt Volt, RgtOffset Volt, rgtcmd command, Volt Sendstr
_lftCmd: ldi sub subi ori mov rjmp
temp, StrMid temp, Volt temp, LftOffset temp, lftcmd command, temp Sendstr
_ctrCmd: ldi ori Sendstr: ; rcall rcall
command, 0x00 command, rgtcmd LEDSt SendMsg
;***************************Get Status*************************** Getstat: cpi breq in cpi breq
debounce, ON _debounce temp, PORTB release, OFF _release
;check if debounce is on ;check if buttons have been released
;buttons have been debounced and released
sbic rjmp _running: sbis rjmp mov com andi andi or rjmp _trig:
mov andi inc cpi brge rjmp
_lightsoff: ori rjmp _debounce: inc breq rjmp _DBdone: ldi rjmp _release: ori brne ldi
PINB, TRIG _trig PINB, TOP _status temp, status temp temp, 0xf0 status, 0x0f status, temp _status temp2, status temp2, 0x0f temp2 temp, Maxlights _lightsoff _running status, 0xf0 _running DBcnt _DBdone _release
;increment debounce counter
debounce, OFF _release
;turn debounce off
temp, 0x30 _status release, ON
;************************Transmit Status************************* _status:
_on: _off:
mov ori breq
command, status command, 0xf0 _off
mov ori
command, status command, 0x5f
mov ori
command, status command, 0x4f
rcall rjmp
SendMsg GetSpd
;***************************Return******************************* ;******************
;Pause procedure ;****************** ;_Wait: ; cli ; clr temp2 ;outerL: ; clr temp3 ;innerL: ; inc temp3 ; cpi temp3, 0 ; brne innerL ; inc temp2 ; cpi temp2, 255 ; brne outerL ; sei complete; approx. 1 ms has passed ; ret
;disable interrupts ;clear upper 8 bits of counter ;clear lower 8 bits of counter
;here the outer loop is ;return from wait subroutine
;******************* ;message sending sub ;******************* SendMsg: ldi ZL, LOW(cntstr) ;ptr to RAM ldi ZH, HIGH(cntstr) inc ZL st Z, command ld r0,Z out UDR, r0 ;fire off the UART transmit clr TXflash ;the string is in RAM ser TXbusy ;and set the TX busy flag sbi UCR, UDRIE ;enable the TXempty interrupt rcall TXwait ret ;****************** ;Debug procedure ;****************** LEDSt: mov LEDReg, command com LEDReg ;invert to send correct output to leds out PORTB, LEDReg ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;UART stuff follows. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; UART needs a character TXempty:in savSREG, SREG tst TXflash breq TXram inc ZL
TXram:
lpm rjmp inc
TXfls ZL
;save processor status ;Is the string in flash memory? ;If not, it is in RAM ;get the next char from flash ;and put it in r0 ;get the next char from RAM
ld tst breq out rjmp TXend: clr cbi TXexit: out reti TXfls:
r0,Z r0 TXend UDR, r0 TXexit TXbusy UCR, UDRIE SREG, savSREG
;if char is zero then exit ;otherwise transmit it ;exit until next char ;no more chars ;clear the TXempty interrupt ;restore proc status ;back to pgm
; TX done -- buffer is empty -- unused here TXdone: in savSREG, SREG ;save processor status out SREG, savSREG ;restore proc status reti ;back to pgm ;***************************** ;subroutine TXwait: tst brne ret
TXbusy TXwait
;now wait for the tranmission to finish