FinalLab LeNguyenQuangThai EEACIU21147
FinalLab LeNguyenQuangThai EEACIU21147
Instructions:
• Read each problem carefully.
• Provide clear and concise answers.
• Make sure to label your diagrams and code appropriately.
Variant 4
Problem 1: Circuit Design and C Programming
Task:
1. Draw the circuit diagram in Proteus for the following scenario:
o Connect the ATmega32 microcontroller running at 16 MHz to a UART0 serial
interface.
o Connect four LEDs to PORTD (PD0, PD2, PD4, PD6) to indicate the received
characters.
o Connect the microcontroller to a Hyperterminal setup for serial
communication.
2. Write a C program that:
o Configures UART0 for a 9600 baud rate, 8 data bits, 1 stop bit, and no parity.
o Sets up the interrupt for receiving characters via UART.
o Toggles the relevant LED on PORTD based on the received character and
displays the character on an LCD.
Evaluation Criteria
• Accuracy of the circuit diagram.
• Correctness of the C program and Assembly code.
• Clarity and organization of the submission.
Solution:
Problem 1:
Code C :
#include <avr/io.h>
#include <avr/interrupt.h>
char received_data;
void Tx(unsigned char data) {
while (!(UCSRA & (1 << UDRE)));
UDR = data;
}
void init_UART() {
UBRRH = 0;
UBRRL = 103; // Baud rate 9600 for 16 MHz crystal
UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE); // Enable UART RX, TX, and RX
interrupt
UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0); // Asynchronous mode, no
parity, 8-bit data
}
ISR(USART_RXC_vect) {
received_data = UDR; // Fetch the received byte
switch (received_data) {
case '1': PORTD ^= (1 << PD2); break; // Toggle LED on PD2
case '2': PORTD ^= (1 << PD3); break; // Toggle LED on PD3
case '3': PORTD ^= (1 << PD6); break; // Toggle LED on PD6
case '4': PORTD ^= (1 << PD7); break; // Toggle LED on PD7
default: break; // Do nothing for undefined characters
}
Tx(received_data); // Echo the received character
}
int main() {
DDRD = (1 << PD2) | (1 << PD3) | (1 << PD6) | (1 << PD7); // Set PD2, PD3, PD6, PD7 as
output
PORTD = 0x00; // Ensure LEDs are off initially
init_UART(); // Initialize UART
sei(); // Enable global interrupts
while (1) {
// Main loop remains empty as ISR handles the logic
}
}
On Proteus:
Problem 2:
Code asm. :
#include <avr/io.h>
#include <avr/interrupt.h>
char received_data;
void init_UART() {
UBRRH = 0;
UBRRL = 103; // Baud rate 9600 for 16 MHz crystal
UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE); // Enable UART RX, TX, and RX
interrupt
UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0); // Asynchronous mode, no
parity, 8-bit data
}
ISR(USART_RXC_vect) {
received_data = UDR; // Fetch the received byte
switch (received_data) {
case '1': PORTD ^= (1 << PD2); break; // Toggle LED on PD2
case '2': PORTD ^= (1 << PD3); break; // Toggle LED on PD3
case '3': PORTD ^= (1 << PD6); break; // Toggle LED on PD6
case '4': PORTD ^= (1 << PD7); break; // Toggle LED on PD7
default: break; // Do nothing for undefined characters
}
Tx(received_data); // Echo the received character
}
int main() {
DDRD = (1 << PD2) | (1 << PD3) | (1 << PD6) | (1 << PD7); // Set PD2, PD3, PD6, PD7 as
output
PORTD = 0x00; // Ensure LEDs are off initially
init_UART(); // Initialize UART
sei(); // Enable global interrupts
while (1) {
// Main loop remains empty as ISR handles the logic
}
}
On proteus: