Chuyển đến nội dung
AIOTAIOT
  • Trang chủ
  • Giới thiệu
  • Tin tức
  • Sản phẩm
  • Giải pháp
    • Chấm công bằng Face ID
    • Thiết bị đọc căn cước
    • IoT trong giáo dục
    • IoT trong quản lý năng lượng
    • IoT trong y tế
  • Đào tạo
    • Khóa đào tạo cơ bản
      • Hệ thống nhúng
      • LabVIEW FPGA
      • Phần cứng máy tính & Truyền thông công nghiệp
      • FPGA cơ bản
    • Khóa đào tạo nâng cao
      • LabVIEW FPGA High Performance
    • Tài liệu
  • PCCC
  • Liên hệ
  • icon
    097 186 8316    |    0839 799 889
Đào tạo, Hệ thống nhúng, Khóa đào tạo cơ bản

[Embedded Series – Bài 22] Giao Tiếp I2C Chuyên Sâu Và Làm Chủ UART Interrupt Trên STM32

Đã đăng trên 12/05/202628/04/2026 bởi ThaoNguyen
12
Th5

Sau khi đã làm quen với UART và SPI ở các bài trước, hôm nay chúng ta sẽ đi sâu vào I2C – một giao thức giao tiếp nối tiếp cực kỳ thông minh và phổ biến trong giới nhúng. Bên cạnh đó, chúng ta sẽ quay trở lại thực hành với UART ở cấp độ nâng cao: sử dụng Ngắt (Interrupt) kết hợp với Timer để xây dựng một hệ thống truyền nhận dữ liệu chuyên nghiệp.

🎯 Mục tiêu học tập

  • Hiểu rõ nguyên lý hoạt động của bus I2C và cơ chế địa chỉ hóa thiết bị.
  • Nắm vững cấu trúc phần cứng Open-Drain và vai trò của điện trở kéo lên (Pull-up).
  • Phân tích chi tiết khung truyền I2C: Start, Stop, ACK/NACK và địa chỉ 7-bit.
  • Thành thạo cấu hình UART Interrupt trên STM32 bằng CubeMX.
  • Thực hành truyền dữ liệu theo chu kỳ và nhận dữ liệu phản hồi (Echo) bằng Ngắt.

1. Tổng quan về giao tiếp I2C (Inter-Integrated Circuit)

a) Khái niệm và Lịch sử

I2C (phát âm là I-squared-C hoặc IIC) được phát triển bởi Philips Semiconductors (nay là NXP) vào những năm 1980. Đây là chuẩn giao tiếp đồng bộ, nối tiếp, cho phép kết nối nhiều thiết bị Master và Slave trên cùng một đường truyền chỉ với 2 dây tín hiệu.

I2C là lựa chọn hàng đầu cho các ngoại vi không yêu cầu tốc độ quá cao nhưng ưu tiên sự đơn giản và tiết kiệm chân linh kiện như: Cảm biến nhiệt độ, EEPROM, đồng hồ thời gian thực (RTC), màn hình OLED…

b) Cấu tạo phần cứng: SCL và SDA

Hệ thống I2C chỉ sử dụng đúng 2 đường bus:

  • SCL (Serial Clock Line): Đường xung nhịp đồng bộ do thiết bị Master phát đi.
  • SDA (Serial Data Line): Đường truyền nhận dữ liệu hai chiều.
⚠️ Lưu ý quan trọng: Cả hai đường SCL và SDA đều hoạt động ở chế độ Open-Drain. Điều này có nghĩa là các thiết bị chỉ có thể kéo bus xuống mức THẤP (0V). Để có mức CAO (3.3V/5V), chúng ta bắt buộc phải sử dụng điện trở kéo lên (Pull-up) từ 1kΩ đến 4.7kΩ. Thiết kế này giúp tránh hiện tượng ngắn mạch khi nhiều thiết bị cùng giao tiếp trên bus.

c) Khung truyền dữ liệu và Địa chỉ hóa

Trong một mạng I2C, mỗi thiết bị Slave được định danh bằng một địa chỉ 7-bit duy nhất. Một khung truyền I2C điển hình bao gồm:

  1. Tín hiệu START: Master kéo SDA xuống thấp trước SCL.
  2. Địa chỉ 7-bit: Master gửi địa chỉ của Slave muốn giao tiếp.
  3. Bit R/W: Bit thứ 8 xác định Master muốn Đọc (1) hay Ghi (0) dữ liệu.
  4. Bit ACK/NACK: Slave phản hồi bằng cách kéo SDA xuống thấp nếu đúng địa chỉ.
  5. Dữ liệu (8-bit): Các byte dữ liệu được truyền đi, mỗi byte kèm theo 1 bit ACK xác nhận.
  6. Tín hiệu STOP: Master kéo SDA lên cao sau SCL để kết thúc phiên giao tiếp.

2. Thực hành cấu hình UART nâng cao trên STM32

Trong phần này, chúng ta sẽ ứng dụng Timer để gửi dữ liệu định kỳ 1 giây/lần và sử dụng Ngắt (Interrupt) để nhận dữ liệu từ máy tính gửi về vi điều khiển.

a) Các bước cấu hình trên STM32CubeMX

  • Bước 1: Kích hoạt USART1 (Mode: Asynchronous).
    • Baud Rate: 115200.
    • Word Length: 8 Bits.
    • Stop Bits: 1.
  • Bước 2: Trong tab NVIC Settings, tích chọn “USART1 global interrupt” để bật ngắt nhận.
  • Bước 3: Cấu hình Timer 2 để tạo ngắt mỗi 1 giây (dùng để gửi dữ liệu định kỳ).
  • Bước 4: Thiết lập ưu tiên ngắt (Preemption Priority): Ưu tiên Timer cao hơn UART (ví dụ Timer = 2, UART = 3).

b) Giải thích các hàm API quan trọng

  • HAL_UART_Transmit(...): Gửi dữ liệu ở chế độ Polling (chờ gửi xong mới chạy tiếp).
  • HAL_UART_Receive_IT(...): Kích hoạt ngắt nhận dữ liệu. CPU sẽ rảnh tay để làm việc khác cho đến khi nhận đủ số byte quy định.
  • HAL_UART_RxCpltCallback(...): Hàm được gọi tự động sau khi nhận đủ dữ liệu qua ngắt.

c) Ví dụ mã nguồn thực tế

Chương trình sau sẽ gửi chuỗi “Data” lên máy tính mỗi giây và sẽ phản hồi lại bất kỳ dữ liệu nào nhận được từ máy tính.

/* Khai báo biến toàn cục */
uint8_t tx_data[6] = "\nData"; 
uint8_t rx_buffer[6];

int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_TIM2_Init();
    MX_USART1_UART_Init();

    /* 1. Kích hoạt ngắt nhận 6 byte đầu tiên */
    HAL_UART_Receive_IT(&huart1, rx_buffer, 6);

    /* 2. Khởi động Timer tạo chu kỳ gửi */
    HAL_TIM_Base_Start_IT(&htim2);

    while (1) {
        // Vòng lặp chính hoàn toàn rảnh rỗi cho các tác vụ khác
    }
}

/* 3. Hàm xử lý khi Timer tràn (mỗi 1 giây) */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
    if(htim->Instance == TIM2) {
        // Gửi dữ liệu định kỳ lên PC
        HAL_UART_Transmit(&huart1, tx_data, 6, 500); 
    }
}

/* 4. Hàm xử lý khi nhận đủ 6 byte qua UART */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    if(huart->Instance == USART1) {
        // Gửi trả lại (Echo) dữ liệu vừa nhận được
        HAL_UART_Transmit(&huart1, rx_buffer, 6, 200);
        
        // Quan trọng: Kích hoạt lại ngắt nhận cho lần tiếp theo
        HAL_UART_Receive_IT(&huart1, rx_buffer, 6);
    }
}

3. Kết nối và Giám sát trên Máy tính

Để giao tiếp với máy tính, chúng ta sử dụng module USB to UART (PL2303/CP2102). Sơ đồ kết nối chân như sau:

STM32 (Pin) Module USB-to-UART
PA9 (TX) RX
PA10 (RX) TX
GND GND

Sử dụng phần mềm Hercules, chọn đúng cổng COM và Baudrate 115200 để quan sát dữ liệu. Bạn sẽ thấy dòng chữ “Data” xuất hiện mỗi giây, và khi bạn gửi 6 ký tự từ Hercules, vi điều khiển sẽ phản hồi lại ngay lập tức.

🚀 Bài tập thực hành

  1. Địa chỉ I2C: Tra cứu Datasheet của cảm biến nhiệt độ LM75 hoặc module DS3231. Cho biết địa chỉ I2C mặc định của chúng là gì?
  2. Xử lý chuỗi UART: Cấu hình ngắt nhận từng ký tự (Size = 1). Nếu nhận được ký tự ‘R’, bật LED Đỏ. Nếu nhận được ký tự ‘G’, bật LED Xanh.
  3. Nâng cao: Kết hợp UART và Timer. Nhận một con số từ máy tính qua UART (ví dụ ‘5’), sau đó thay đổi chu kỳ gửi dữ liệu của Timer thành 5 giây.
📝 Tóm tắt: I2C là giao thức mạnh mẽ cho việc kết nối đa thiết bị với số lượng chân tối thiểu. Trong khi đó, việc làm chủ UART ở chế độ Ngắt là kỹ năng bắt buộc để xử lý các luồng dữ liệu bất đồng bộ mà không làm treo hệ thống. Hãy luôn nhớ cấu hình Pull-up cho I2C và gọi lại hàm Receive_IT sau mỗi lần Callback UART thành công.

“Kỹ sư giỏi không chỉ truyền được dữ liệu, mà còn biết cách truyền dữ liệu một cách hiệu quả và tin cậy.”

Gợi ý bài tiếp theo: Thực Hành Lập Trình SPI Với DAC MCP4922 Và I2C Với EEPROM AT24C32.

 

Mục nhập này đã được đăng trong Đào tạo, Hệ thống nhúng, Khóa đào tạo cơ bản và được gắn thẻ Embedded Systems.
ThaoNguyen

[Embedded Series – Bài 21] Làm Chủ Giao Tiếp UART Và SPI Trong Hệ Thống Nhúng
[Embedded Series – Bài 23] Thực Hành Lập Trình SPI Với DAC MCP4922 Và I2C Với EEPROM AT24C32

Để lại một bình luận Hủy

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Bài viết mới
  • [Embedded Series – Bài 27] Chuyên Sâu Bootloader: Cơ Chế Khởi Động, Quản Lý Vector Table Và Kỹ Thuật Jump Firmware
  • [Embedded Series – Bài 26] Làm Chủ Giao Tiếp Bộ Nhớ Flash Trên Vi Điều Khiển STM32F407
  • [Embedded Series – Bài 25] Lập Trình FreeRTOS Trên STM32: Từ Ngắt, Queue Đến Quản Lý Tài Nguyên
  • [Embedded Series – Bài 24] Hệ Điều Hành Thời Gian Thực (RTOS): Giải Pháp Đa Tác Vụ Chuyên Nghiệp
  • [Embedded Series – Bài 23] Thực Hành Lập Trình SPI Với DAC MCP4922 Và I2C Với EEPROM AT24C32
Danh mục
  • Đào tạo
  • FPGA cơ bản
  • Giải pháp
  • Hệ thống nhúng
  • IoT trong giáo dục
  • IoT trong y tế
  • Khóa đào tạo cơ bản
  • Khóa đào tạo nâng cao
  • LabVIEW FPGA
  • LabVIEW FPGA High Performance
  • Phần cứng máy tính & Truyền thông công nghiệp
  • Sản xuất công nghiệp
  • Thiết bị dịch vụ thông minh
  • Thiết bị đọc căn cước
  • Tin tức

CÔNG TY CỔ PHẦN HỆ THỐNG AIOT

VPGD: Số A21-TT9 Đường Foresa 1 KĐT Xuân Phương, Phường Xuân Phương, Hà Nội.

Địa chỉ kinh doanh: Đường Phú Diễn, Tổ dân phố 18, phường Phú Diễn, Thành phố Hà Nội, Việt Nam

Hotline/Zalo: 097 186 8316 | 0839 799 889

Email: aiot@aiots.vn

VỀ CHÚNG TÔI

Giới thiệu

Sản phẩm

Giải pháp

Đào tạo

Tin tức

QUY ĐỊNH & CHÍNH SÁCH

Chính sách thanh toán

Chính sách vận chuyển

Chính sách bảo hành

Chính sách đổi trả

Chính sách bảo mật

ĐỊA CHỈ VĂN PHÒNG GIAO DỊCH

Copyright 2024 © Bản quyền thuộc về AIOT. Thiết kế bởi Jamina JSC
  • Trang chủ
  • Giới thiệu
  • Tin tức
  • Sản phẩm
  • Giải pháp
    • Chấm công bằng Face ID
    • Thiết bị đọc căn cước
    • IoT trong giáo dục
    • IoT trong quản lý năng lượng
    • IoT trong y tế
  • Đào tạo
    • Khóa đào tạo cơ bản
      • Hệ thống nhúng
      • LabVIEW FPGA
      • Phần cứng máy tính & Truyền thông công nghiệp
      • FPGA cơ bản
    • Khóa đào tạo nâng cao
      • LabVIEW FPGA High Performance
    • Tài liệu
  • PCCC
  • Liên hệ
Zalo
Phone

Đăng nhập

Quên mật khẩu?