Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

Prelab vi xu ly hcmut, Assignments of Computer Science

Prelab vi xu ly HCMUT 2025 thi nghiem

Typology: Assignments

2024/2025

Uploaded on 04/21/2025

huy-huynh-5
huy-huynh-5 🇻🇳

4 documents

1 / 17

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
SOẠN PRELAB2
Lab 2_1
Bài 1
a. Khoảng thời gian trễ lớn nhất của Timer 0 với tần số 8MHz
Timer 0 là bộ định thời 8-bit, có thể đếm từ 0 đến 255 (tổng cộng 256 giá trị). Công thức tính
thời gian trễ tối đa:
Tmax= số giá trị điếm: tần số bộ điếm
Khi sử dụng prescaler lớn nhất (1024):
Tmax: 256×1024:8x
106
= 32.768ms
b. Khoảng thời gian trễ lớn nhất của Timer 1 với tần số 8MHz
Timer 1 là bộ định thời 16-bit, có thể đếm từ 0 đến 65535 (tổng cộng 65536 giá trị). Công thức
tương tự như Timer 0:
Tmax=
65536 ×1024
8x106
= 8.388608s≈8.39s
c. Tính toán Prescaler và giá trị nạp vào Timer 0
Nếu cần tạo thời gian trễ TTT, ta chọn giá trị prescaler phù hợp để tính toán giá trị nạp vào
thanh ghi Timer:
GiaˊXtrịXnạp=256-
T × fclk
prescaler
d. Mã nguồn chương trình (C, sử dụng AVR-GCC)
#include <avr/io.h>
#include <avr/interrupt.h>
void timer0_init() {
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff

Partial preview of the text

Download Prelab vi xu ly hcmut and more Assignments Computer Science in PDF only on Docsity!

SOẠN PRELAB

Lab 2_

Bài 1 a. Khoảng thời gian trễ lớn nhất của Timer 0 với tần số 8MHz Timer 0 là bộ định thời 8-bit, có thể đếm từ 0 đến 255 (tổng cộng 256 giá trị). Công thức tính thời gian trễ tối đa: Tmax= số giá trị điếm: tần số bộ điếm Khi sử dụng prescaler lớn nhất (1024): Tmax: 256×1024:8x 10 6 = 32.768ms b. Khoảng thời gian trễ lớn nhất của Timer 1 với tần số 8MHz Timer 1 là bộ định thời 16-bit, có thể đếm từ 0 đến 65535 (tổng cộng 65536 giá trị). Công thức tương tự như Timer 0: Tmax=

65536 × 1024

8 x 10 6 = 8.388608s≈8.39s c. Tính toán Prescaler và giá trị nạp vào Timer 0 Nếu cần tạo thời gian trễ TTT, ta chọn giá trị prescaler phù hợp để tính toán giá trị nạp vào thanh ghi Timer: Giaˊ trị nạp=256- T × fclk prescaler d. Mã nguồn chương trình (C, sử dụng AVR-GCC) #include <avr/io.h> #include <avr/interrupt.h> void timer0_init() {

TCCR0B |= (1 << CS02) | (1 << CS00); // Prescaler = 1024 TCNT0 = 178; // Giá trị nạp ban đầu TIMSK0 |= (1 << TOIE0); // Bật ngắt Timer 0 sei(); // Bật ngắt toàn cục } ISR(TIMER0_OVF_vect) { TCNT0 = 178; // Nạp lại giá trị PORTB ^= (1 << PB0); // Đảo trạng thái chân PB } int main() { DDRB |= (1 << PB0); // Đặt PB0 làm output timer0_init(); while (1) { // Chương trình chính } } Bài 2 a. Ở mode Normal, khi nào bit TOVx được set lên 1? Trong mode Normal, bộ đếm Timer (TCNTx) tăng dần từ 0 đến giá trị cực đại (255 với Timer 0, 65535 với Timer 1).  Khi TCNTx đếm đến giá trị lớn nhất và tăng tiếp một đơn vị, nó sẽ tràn về 0.  Lúc này, bit TOVx (Timer Overflow Flag) trong thanh ghi TIFRx sẽ được set lên 1.  Nếu ngắt tràn (Overflow Interrupt) được bật, một ngắt sẽ được kích hoạt.

TCNT0 = 178; // Giá trị nạp ban đầu TIMSK0 = (1 << TOIE0); // Bật ngắt tràn sei(); // Bật ngắt toàn cục } ISR(TIMER0_OVF_vect) { TCNT0 = 178; // Nạp lại giá trị PORTB ^= (1 << PB0); // Đảo trạng thái chân PB } int main() { DDRB |= (1 << PB0); // Đặt PB0 làm output timer0_init_normal(); while (1) { // Chương trình chính } } Trường hợp 2: Mode CTC (Ngắt so khớp giá trị) #include <avr/io.h> #include <avr/interrupt.h> void timer0_init_ctc() { TCCR0A = (1 << WGM01); // Mode CTC TCCR0B = (1 << CS02) | (1 << CS00); // Prescaler 1024

OCR0A = 78; // Giá trị so khớp TIMSK0 = (1 << OCIE0A); // Bật ngắt CTC sei(); // Bật ngắt toàn cục } ISR(TIMER0_COMPA_vect) { PORTB ^= (1 << PB0); // Đảo trạng thái chân PB } int main() { DDRB |= (1 << PB0); // Đặt PB0 làm output timer0_init_ctc(); while (1) { // Chương trình chính } } Bài 3 a. Dạng sóng trên oscilloscope Bạn cần chụp ảnh dạng sóng trên oscilloscope bằng cách đo tại PB3 (OC0A) và PB4 (OC0B). Dự đoán dạng sóng:  PB3 (OC0A): PWM có duty cycle = (100/255) × 100% ≈ 39%.  PB4 (OC0B): PWM có duty cycle = (75/255) × 100% ≈ 29%. b. Giải thích lý do có dạng sóng  1. Tần số PWM

 Cấu hình TCCR0A & TCCR0B TCCR0A = 0b00000010 (WGM02:0 = 010) TCCR0B = 0b00001010 (WGM02 = 1, CS01 = 1 → Prescaler = 8)  Hoạt động: o Bộ đếm đếm từ 0 → OCR0A, sau đó reset về 0. o Khi TCNT0 = OCR0A, bit OCF0A được set.  Dạng sóng: Xung vuông có tần số cố định, có thể tạo xung chính xác. 1.3. Mode Fast PWM  Cấu hình TCCR0A & TCCR0B TCCR0A = 0b10100011 (WGM02:0 = 011, COM0A1 = 1, COM0B1 = 1) TCCR0B = 0b00000010 (CS01 = 1 → Prescaler = 8)  Hoạt động: o Bộ đếm đếm từ 0 → 255, reset về 0. o Khi giá trị TCNT0 bằng OCR0A hoặc OCR0B, chân OC0A/OC0B thay đổi trạng thái.  Dạng sóng: PWM có tần số cao, không đối xứng. 1.4. Mode Phase Correct PWM  Cấu hình TCCR0A & TCCR0B TCCR0A = 0b10100001 (WGM02:0 = 001, COM0A1 = 1, COM0B1 = 1) TCCR0B = 0b00000010 (CS01 = 1 → Prescaler = 8)  Hoạt động: o Bộ đếm đếm từ 0 → 255 rồi giảm ngược về 0. o Khi giá trị TCNT0 bằng OCR0A hoặc OCR0B, chân OC0A/OC0B thay đổi trạng thái.  Dạng sóng: PWM đối xứng hơn so với Fast PWM.

2. Chụp và Giải Thích Dạng Sóng Bạn cần đo dạng sóng trên oscilloscope và chụp lại để so sánh với lý thuyết. 2.1. Mode Normal  Dạng sóng: Không có PWM, chỉ có xung nếu sử dụng ngắt.  Giải thích: Bộ đếm chỉ tràn mà không tác động đến OC0A hay OC0B. 2.2. Mode CTC  Dạng sóng: Xung vuông có chu kỳ chính xác.  Giải thích: Xung có chu kỳ bằng (OCR0A + 1) / f_timer. 2.3. Mode Fast PWM  Dạng sóng: Sóng PWM không đối xứng.  Giải thích: Khi TCNT0 = OCR0A hoặc OCR0B, tín hiệu OC0A/OC0B thay đổi. 2.4. Mode Phase Correct PWM  Dạng sóng: Sóng PWM đối xứng.  Giải thích: Bộ đếm đếm lên rồi xuống, tạo xung đối xứng hơn. **Bài 5

  1. Mã nguồn Assembly với chú thích .org 00** call initTimer start: rjmp start ; Lặp vô hạn ; Hàm khởi tạo Timer 0 ở chế độ Fast PWM, tạo PWM 1kHz, duty cycle 25% trên OC0B (PB4) initTimer0: ldi r16, (1 << PB4) ; Cấu hình PB4 (OC0B) là output out DDRB, r

Số lần điếm= 5 ms 4 μs

 o Vì OCR0 chỉ chứa giá trị tối đa 255, ta chọn OCR0 = 250 để tạo ngắt mỗi 1ms và đếm 5 lần để đạt 5ms.

2. Mã nguồn và chú thích (AVR C - Atmel Studio) #include <avr/io.h> #include <avr/interrupt.h> #define F_CPU 16000000UL // Định nghĩa tần số CPU const uint8_t LED_digits[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; uint8_t display_index = 0; // Vị trí LED đang quét uint8_t digits[4] = {0, 1, 2, 3}; // Số hiển thị trên 4 LED void timer0_init() { TCCR0 |= (1 << WGM01); // Chế độ CTC OCR0 = 250; // Ngắt mỗi 1ms (với prescaler 64) TIMSK |= (1 << OCIE0); // Cho phép ngắt Timer 0 TCCR0 |= (1 << CS01) | (1 << CS00); // Prescaler 64 sei(); // Cho phép ngắt toàn cục } ISR(TIMER0_COMP_vect) { static uint8_t count = 0;

count++; if (count >= 5) { // 5ms mỗi lần quét LED tiếp theo PORTB = LED_digits[digits[display_index]]; // Xuất dữ liệu LED PORTD = ~(1 << display_index); // Chọn LED tương ứng display_index = (display_index + 1) % 4; // Quét sang LED tiếp theo count = 0; } } int main(void) { DDRB = 0xFF; // Cổng B xuất dữ liệu LED DDRD = 0xFF; // Cổng D điều khiển LED 7 đoạn timer0_init(); while (1) { // Chương trình chính không làm gì, mọi thứ do ngắt xử lý } } Bài 2 a. Giá trị PORTA * 9 là số có bao nhiêu bit?  PORTA là 8 bit, giá trị có thể từ 0 đến 255.  Tính toán: 255∗9=2295255 * 9 = 2295255∗9= o 2295 trong hệ nhị phân: 100011110111 (12 bit). o Kết luận: Kết quả của PORTA * 9 có thể lên đến 12 bit. b. Làm thế nào để hiển thị từng chữ số lên 4 LED? Vì giá trị tối đa là 2295, cần hiển thị 4 chữ số.

digits[1] = (temp / 100) % 10; // Hàng trăm digits[2] = (temp / 10) % 10; // Hàng chục digits[3] = temp % 10; // Hàng đơn vị } // Cấu hình Timer 0 để tạo ngắt mỗi 1ms void timer0_init() { TCCR0 |= (1 << WGM01); // Chế độ CTC (Clear Timer on Compare Match) OCR0 = 250; // Ngắt mỗi 1ms (với prescaler 64) TIMSK |= (1 << OCIE0); // Cho phép ngắt Timer 0 TCCR0 |= (1 << CS01) | (1 << CS00); // Prescaler 64 sei(); // Cho phép ngắt toàn cục } // Ngắt Timer 0: Quét LED mỗi 5ms ISR(TIMER0_COMP_vect) { static uint8_t count = 0; count++; if (count >= 5) { // 5ms mỗi lần quét LED tiếp theo PORTB = LED_digits[digits[display_index]]; // Xuất dữ liệu LED PORTD = ~(1 << display_index); // Chọn LED tương ứng display_index = (display_index + 1) % 4; // Quét sang LED tiếp theo count = 0; } }

int main(void) { DDRA = 0x00; // PORTA nhập từ dip switch DDRB = 0xFF; // PORTB xuất dữ liệu LED DDRD = 0xFF; // PORTD điều khiển LED 7 đoạn timer0_init(); while (1) { value = PINA * 9; // Đọc giá trị từ dip switch và nhân 9 update_digits(); // Cập nhật từng chữ số hiển thị } } a. Mô tả kết nối trên kit LED ma trận có 2 loại: anode chung và cathode chung. Thông thường, LED ma trận có:  Cột (Columns): Điều khiển mức điện áp để bật/tắt toàn bộ LED trong một cột.  Hàng (Rows): Xác định LED nào trong cột đang sáng. Trên kit AVR:  Cổng điều khiển cột: Cắm vào một port xuất (ví dụ: PORTB).  Cổng điều khiển hàng: Cắm vào một port xuất khác (ví dụ: PORTD).  Sử dụng transistor hoặc mạch kéo dòng để đảm bảo dòng điện đủ lớn cho LED ma trận.  Dùng timer để quét LED từng cột một, tạo hiệu ứng hiển thị cả ma trận. b. Để có tần số quét 25Hz thì một cột LED sáng trong bao lâu?  Tần số quét 25Hz nghĩa là toàn bộ ma trận LED quét trong 1/25 giây = 40ms.  Nếu có 8 cột, mỗi cột sáng trong: 40ms/8=5ms40ms / 8 = 5ms40ms/8=5ms => Mỗi cột sáng trong 5ms. c. Sự khác nhau khi quét ở tần số 25Hz và 125Hz

// Hàm khởi tạo timer (chỉnh sửa để đổi từ 25Hz sang 125Hz) void timer_init(uint16_t delay_ms) { TCCR0 |= (1 << WGM01); // Chế độ CTC OCR0 = (delay_ms * 250) / 5; // Tạo ngắt sau mỗi delay_ms TIMSK |= (1 << OCIE0); // Cho phép ngắt Timer 0 TCCR0 |= (1 << CS01) | (1 << CS00); // Prescaler 64 sei(); // Bật ngắt toàn cục } // Ngắt Timer quét LED ma trận ISR(TIMER0_COMP_vect) { PORTD = 0x00; // Tắt tất cả hàng trước khi chuyển cột PORTB = (1 << column); // Bật cột hiện tại PORTD = letter_A[column]; // Gửi dữ liệu hàng column = (column + 1) % 8; // Quét sang cột tiếp theo } int main(void) { DDRB = 0xFF; // Cổng B điều khiển cột DDRD = 0xFF; // Cổng D điều khiển hàng timer_init(5); // Tần số quét 25Hz (mỗi cột sáng 5ms) while (1) { // Chờ timer quét LED }