# Implementation and Assembly Code Examples

This page contains basic implementation examples of USART serial communication using the Assembly programming language on an AVR Microcontroller (ATmega328p).

## 1. Printing Text to Serial Monitor

This code is used to repeatedly send the string "Programming Serial Interface!" to the Serial Monitor via the USART port.

```assembly
;------------------------
; Assembly Code - Print Text
;------------------------
#define __SFR_OFFSET 0x00
#include "avr/io.h"
;------------------------
.global main

main:
    CLR   R24
    STS   UCSR0A, R24               ; Clear UCSR0A register
    STS   UBRR0H, R24               ; Clear UBRR0H
    LDI   R24, 103                  ; Set UBRR value = 103 (9600 Baud Rate)
    STS   UBRR0L, R24

    LDI   R24, (1<<RXEN0) | (1<<TXEN0) ; Enable RX and TX
    STS   UCSR0B, R24

    LDI   R24, (1<<UCSZ00) | (1<<UCSZ01) ; Mode: 8-bit data, 1 stop bit, No Parity
    STS   UCSR0C, R24

print_msg:
    LDI   R30, lo8(message)
    LDI   R31, hi8(message)         ; Z points to string message
agn:
    LPM   R18, Z+                   ; Load character into R18
    CPI   R18, 0                    ; Check if end of string (null)
    BREQ  ext                       ; If yes, exit loop

l1:
    LDS   R17, UCSR0A
    SBRS  R17, UDRE0                ; Wait until buffer is empty (UDRE0=1)
    RJMP  l1
    STS   UDR0, R18                 ; Send character to Serial Monitor
    RJMP  agn                       ; Loop to next character

ext:
    RCALL delay_sec                 ; Wait for a moment
    RJMP  print_msg                 ; Repeat string transmission

message:
    .ascii "Programming Serial Interface!"
    .byte 10, 13, 0

delay_sec:                          ; Delay Subroutine (~3 seconds)
    LDI   R20, 255
l4: LDI   R21, 255
l5: LDI   R22, 255
l6: DEC   R22
    BRNE  l6
    DEC   R21
    BRNE  l5
    DEC   R20
    BRNE  l4
    RET
```

---

## 2. Reading Input from Serial Monitor

This code reads characters sent from the Serial Monitor and controls an LED. If the character 'H' is received, the LED turns ON; if 'L' is received, the LED turns OFF.

```assembly
;------------------------
; Assembly Code - Input Text and Control LED
;------------------------
#define __SFR_OFFSET 0x00
#include "avr/io.h"
;------------------------
.global main

main:
    CLR   R24
    STS   UBRR0H, R24
    LDI   R24, 103
    STS   UBRR0L, R24
    LDI   R24, (1<<RXEN0 | 1<<TXEN0)
    STS   UCSR0B, R24
    LDI   R24, (1<<UCSZ01 | 1<<UCSZ00)
    STS   UCSR0C, R24

    SBI   DDRB, 5               ; Set PB5 as output

wait_input:
    ; 1. Check if a byte arrived
    LDS   R17, UCSR0A
    SBRS  R17, RXC0             ; Wait for Receive Complete
    RJMP  wait_input

    ; 2. Read the character into R18
    LDS   R18, UDR0

    ; 3. Check if character is 'H'
    CPI   R18, 'H'
    BREQ  led_on

    ; 4. Check if character is 'L'
    CPI   R18, 'L'
    BREQ  led_off

    RJMP  wait_input

led_on:
    SBI   PORTB, 5              ; Turn LED ON
    RJMP  wait_input

led_off:
    CBI   PORTB, 5              ; Turn LED OFF
    RJMP  wait_input
```