Full Version : AT1200 Half-Duplex Interrupt-Driven UART (ASM)
avr >>ASSMBLER ROUTINES >>AT1200 Half-Duplex Interrupt-Driven UART (ASM)


Admin5- 04-19-2006
Half-Duplex Interrupt Driven Softare UART
(A Corrected Version of Atme; AVR AppNote #305)

CODE

;**** A P P L I C A T I O N   N O T E   A V R 3 0 5 ************************
;*
;* Title        : Half Duplex Interrupt Driven Software UART
;* Version      : 1.21
;* Last updated     : 98.11.12
;* Update Author        : Stelios Koroneos
;* Target       : 90s1200
;*
;* Support email    : avr@atmel.com
;* Authors E-mail       : skoron@netor.gr
;* Code Size        : 44 Words
;* Low Register Usage   : 0
;* High Register Usage  : 4
;* Interrupt Usage  : None
;*
;* This is a modification of the original application note 305.
;* The original application note program did not run
;* This version works on 90s1200
;* A modifed version with name 305-85 exist for the 90s8515 and all
;* AVR's withRam.
;*
;*******************************************************************
;* DESCRIPTION
;* This Application note contains a very code efficient software UART.
;* The example program receives one character and echoes it back.
;***************************************************************************

.include "1200def.inc"

;***** Pin definitions

.equ    RxD =0         ;Receive pin is PD0
.equ    TxD =1         ;Transmit pin is PD1

;***** Global register variables

.def    bitcnt  =R16           ;bit counter
.def    temp    =R17           ;temporary storage register

.def    Txbyte  =R18           ;Data to be transmitted
.def    RXbyte  =R19           ;Received data


.cseg
.org 0
;*INTERRUPT JUMP TABLE

       rjmp   reset ;Reset
       reti         ;IRQ handle
       reti         ;Timer0
       reti         ;Analog Comp

;***** Program Execution Starts Here

;***** Test program


reset:      sbi PORTD,TxD  ;Init port pins
       sbi DDRD,TxD

       ldi Txbyte,12  ;Clear terminal
       rcall   putchar

forever:    rcall   getchar
       mov Txbyte,Rxbyte
       rcall   putchar    ;Echo received char
       rjmp    forever


;***************************************************************************
;*
;* "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  =1     ;Number of stop bits (1, 2, ...)

putchar:    ldi bitcnt,9+sb;1+8+sb (sb is # of stop bits)
       com Txbyte     ;Inverte everything
       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
                  ;else
       ret        ;   return


;***************************************************************************
;*
;* "getchar"
;*
;* This subroutine receives one byte and returns it in the "Rxbyte" register
;*
;* Number of words  :14 including return
;* Number of cycles :Depens on when data arrives
;* Low registers used   :None
;* High registers used  :2 (bitcnt,Rxbyte)
;* Pointers used    :None
;*
;***************************************************************************

getchar:    ldi     bitcnt,9   ;8 data bit + 1 stop bit

getchar1:   sbic    PIND,RxD   ;Wait for start bit
       rjmp    getchar1

       rcall UART_delay   ;0.5 bit delay

getchar2:   rcall UART_delay   ;1 bit delay
       rcall UART_delay        

       clc        ;clear carry
       sbic    PIND,RxD   ;if RX pin high
       sec        ;

       dec     bitcnt     ;If bit is stop bit
       breq    getchar3   ;   return
                  ;else
       ror     Rxbyte     ;   shift bit into Rxbyte
       rjmp    getchar2   ;   go get next

getchar3:   ret


;***************************************************************************
;*
;* "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":
;*
;*  3·b + 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   =135   ;4800 bps @ 4 MHz crystal


UART_delay: ldi temp,b
UART_delay1:    dec temp
       brne    UART_delay1

       ret




Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.