; AVR software UART demo by Randy Ott - 4/15/98 (my first) ; Reads a message in EEPROM and serially sends it out a port pin ; Some code snippits plagerized from Atmel examples ; **** inverted data version **** ;***** Pin definitions .equ TxD =0 ;Transmit pin is PD0 ;***** Global register variables .def bitcnt =R16 ;bit counter .def temp =R17 ;temporary storage register .def temp2 =R20 .def Txbyte =R18 ;Data to be transmitted .def EEard =R19 ;EEPROM address to read from .cseg .org 0 rjmp reset .org 16 ;avoid all possible interrupt vectors ;***** Program Execution Starts Here reset: ldi temp,0xff out DDRB,temp cbi PORTD,TxD ;Init port pins sbi DDRD,TxD forever: sbis PIND,2 rjmp forever ldi EEard,0 ;set EEPROM address to 0 EERead: sbic EECR,EEWE ;if EEWE not clear rjmp EERead ; wait more out EEAR,EEard ;output address ;***** Issue EEPROM read strobe twice due to a bug in AVR! ; sbi EECR,EERE ;set EEPROM Read strobe ;This instruction takes 4 clock cycles since ;it halts the CPU for two clock cycles sbi EECR,EERE ;set EEPROM Read strobe 2nd time ;This instruction takes 4 clock cycles since ;it halts the CPU for two clock cycles in Txbyte,EEDR ;get data ldi temp,0xff waitsome: ldi temp2,0xff waitmore: dec temp2 brne waitmore dec temp brne waitsome tst Txbyte ;see if at end of message breq forever ;if zero found, start over rcall putchar ;sent out char inc EEard ;point to next EE address rjmp EERead ;*************************************************************************** ;* ;* "putchar" ;* ;* This subroutine transmits the byte stored in the "Txbyte" register ;* The number of stop bits used is set with the sb constant ;* ;* Number of words :14 including return ;* Number of cycles :Depens on bit rate ;* Low registers used :None ;* High registers used :2 (bitcnt,Txbyte) ;* Pointers used :None ;* ;*************************************************************************** .equ sb=2 ;Number of stop bits (1, 2, ...) putchar: sbi PORTD,1 ldi bitcnt,9+sb ;1+8+sb (sb is # of stop bits) com Txbyte ;Invert everything out PORTB,Txbyte ;put data on port B for debugging sec ;Start bit putchar0: brcc putchar1 ;If carry set cbi PORTD,TxD ; send a '0' rjmp putchar2 ;else putchar1: sbi PORTD,TxD ; send a '1' nop putchar2: rcall UART_delay ;One bit delay rcall UART_delay lsr Txbyte ;Get next bit dec bitcnt ;If not all bit sent brne putchar0 ; send next cbi PORTD,1 ;else ret ; return ;*************************************************************************** ;* ;* "UART_delay" ;* ;* This delay subroutine generates the required delay between the bits when ;* transmitting and receiving bytes. The total execution time is set by the ;* constant "b": ;* ;* 3xb + 7 cycles (including rcall and ret) ;* ;* Number of words :4 including return ;* Low registers used :None ;* High registers used :1 (temp) ;* Pointers used :None ;* ;*************************************************************************** ; Some b values: (See also table in Appnote documentation) ; ; 1 MHz crystal: ; 9600 bps - b=14 ; 19200 bps - b=5 ; 28800 bps - b=2 ; ; 2 MHz crystal: ; 19200 bps - b=14 ; 28800 bps - b=8 ; 57600 bps - b=2 ; 4 MHz crystal: ; 19200 bps - b=31 ; 28800 bps - b=19 ; 57600 bps - b=8 ; 115200 bps - b=2 ;.equ b=185 ;9600 bps @ 11.0592 MHz crystal .equ b=66 ;9600 bps @ 11.0592 MHz crystal UART_delay: ldi temp,b UART_delay1: dec temp brne UART_delay1 ret .eseg .org 0 msg: .db 0x0d, 0x0d, 0x0a, "Hello world from AVR land!", 0 .include "1200def.inc"