;Andrew Bell and Cory Nazarian ;EE 476 Final Project ;Code for controller ;Also see rccar.asm ;Version 2.0 Uart Communication with Forward and Reverse Motor Control ;and Full turning control ;All known bugs fixed ;Port B used as push buttons at this piont .include "4414def.inc" .device AT90S4414 ;******************************* ;Register Definitions .def temp =r16 ;temporary register .def savSREG =r17 ;save the status register .def TXbusy =r18 ;transmit busy flag .def RXchar =r19 ;a received character .def TXflash =r20 ;text to be sent is in flash if <>0 .def command =r21 .def lcommand=r22 .def wreg =r23 ;temp register to be used in isrs ;******************************* ;Constants .equ baud96 =25 ;9600 baud constant for 4Mhz crystal ;All possible directions for the car to be going .equ stop =0b00000001 .equ fwd =0b00000010 .equ rev =0b00000100 .equ left =0b00001000 .equ right =0b00010000 ;Bits in command that directions represent .equ stopb =0 .equ fwdb =1 .equ revb =2 .equ leftb =3 .equ rightb =4 .macro addi subi @0, -@1 .endmacro ;******************************* .dseg ;define variable strings to be tranmitted from RAM stdir: .byte 3 ;the direction stored in mem ;******************************* ;******************************* .cseg .org $0000 rjmp RESET ;reset entry vector reti reti reti reti reti reti reti reti reti rjmp TXempty ;UART buffer empty rjmp TXdone ;UART transmit done reti ;define fixed strings to be tranmitted from flash- zero terminated crlf: .db 0x0d, 0x0a, 0x00 ;carrage return/line feed RESET: ldi temp, LOW(RAMEND) ;setup stack pointer out SPL, temp ldi temp, HIGH(RAMEND) out SPH, temp clr TXbusy ;start out not busy on TX ldi command,stop ;start the car in stop mode ldi lcommand,0 ;make sure last command is not = command at start ;setup UART -- enable TXempty int, TX pin ldi temp, 0b00001000 out UCR, temp ;set baud rate to 9600 ldi temp, baud96 out UBRR, temp ;setup port b for control clr temp out DDRB, temp ser temp out PORTB,temp ;setup port a7 for power ser temp out DDRA,temp ldi temp,0b10000000 out PORTA,temp ;intialize text pointer BEFORE turning on interrupts ;because RESET causes the TX empty flag to be SET ldi ZL, LOW(crlf<<1) ;do shift to convert word-addr to byte ldi ZH, HIGH(crlf<<1) sei ;now print three strings and wait for incoming character interrupt TXloop: in command,PINB com command cpi command,0 brne notstop ldi command,stop ;if command is 0, set it to stop (0b00000001) notstop:ldi ZL, LOW(stdir) ;ptr to RAM ldi ZH, HIGH(stdir) st Z, command ;the direction to ram inc ZL ;zero string terminator to RAM clr temp st Z, temp ;now the pointer to the variable message in RAM ldi ZL, LOW(stdir) ;ptr to RAM ldi ZH, HIGH(stdir) 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 rjmp TXloop ;******************************* ;interrupt routines ; UART needs a character TXempty:in savSREG, SREG ;save processor status tst TXflash ;Is the string in flash memory? breq TXram ;If not, it is in RAM inc ZL ;get the next char from flash lpm ;and put it in r0 rjmp TXfls TXram: inc ZL ;get the next char from RAM ld r0,Z TXfls: tst r0 ;if char is zero then exit breq TXend out UDR, r0 ;otherwise transmit it rjmp TXexit ;exit until next char TXend: clr TXbusy ;no more chars cbi UCR, UDRIE ;clear the TXempty interrupt TXexit: out SREG, savSREG ;restore proc status reti ;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 TXbusy ;now wait for the tranmission to finish brne TXwait ret