Skip to content

Công nghệ 9 giây

“Website hướng dẫn, thử nghiệm và giải thích công nghệ theo cách dễ hiểu cho mọi người.”

Menu
  • Home
  • Công nghệ
  • STM32
  • ESP32
  • Altium Desinger
  • Kiến thức điện máy
Menu

🟦 BÀI 12 – struct + typedef + enum trong chương trình STM32

Posted on August 20, 2026August 23, 2026 by congnghe9s

Được 👍 Chúng ta tiếp tục Bài 12 trong lộ trình học C để lập trình STM32.

🟦 BÀI 12 – struct + typedef + enum trong chương trình STM32

Ở các bài trước, bạn đã đi qua:

  • Kiểu dữ liệu C
  • Biến và bộ nhớ
  • Toán tử
  • Mảng
  • Con trỏ
  • struct
  • Hàm
  • typedef
  • enum

Bây giờ chúng ta ghép chúng lại. Đây là bước rất quan trọng vì từ đây bạn sẽ bắt đầu đọc được kiểu code giống firmware STM32 thực tế.


1. Tại sao STM32 cần struct?

Giả sử chúng ta có một động cơ:

int speed;
int direction;
int enabled;

Ba biến này liên quan với nhau nhưng đang nằm riêng rẽ.

Ta có thể gom chúng thành:

struct Motor
{
    int speed;
    int direction;
    int enabled;
};

Sau đó:

struct Motor motor1;

Truy cập:

motor1.speed = 100;
motor1.direction = 1;
motor1.enabled = 1;

Ta có một đối tượng Motor chứa toàn bộ thông tin của động cơ.


2. typedef làm code dễ đọc hơn

Cách trên hơi dài:

struct Motor motor1;

Ta có thể viết:

typedef struct
{
    int speed;
    int direction;
    int enabled;
} Motor;

Bây giờ:

Motor motor1;

Dễ đọc hơn rất nhiều.


3. enum dùng để biểu diễn trạng thái

Ví dụ động cơ có 3 trạng thái:

STOP
FORWARD
REVERSE

Không nên tùy tiện dùng:

int state;

vì người lập trình có thể ghi:

state = 123;

Trong khi 123 chẳng có ý nghĩa gì.

Ta dùng:

typedef enum
{
    MOTOR_STOP,
    MOTOR_FORWARD,
    MOTOR_REVERSE
} MotorState;

Mặc định:

MOTOR_STOP     = 0
MOTOR_FORWARD  = 1
MOTOR_REVERSE  = 2

4. Ghép struct + enum

Đây mới là phần quan trọng.

typedef enum
{
    MOTOR_STOP,
    MOTOR_FORWARD,
    MOTOR_REVERSE
} MotorState;

typedef struct
{
    int speed;
    MotorState state;
    int enabled;
} Motor;

Ta tạo động cơ:

Motor motor1;

Thiết lập:

motor1.speed = 100;
motor1.state = MOTOR_FORWARD;
motor1.enabled = 1;

5. Đọc dữ liệu

if (motor1.state == MOTOR_FORWARD)
{
    // động cơ quay thuận
}

Hoặc:

if (motor1.enabled == 1)
{
    // cho phép động cơ hoạt động
}

6. Đây chính là kiểu tư duy của firmware

Ví dụ STM32 có một LED:

typedef enum
{
    LED_OFF,
    LED_ON
} LedState;

typedef struct
{
    int pin;
    LedState state;
} Led;

Tạo LED:

Led led1;

Cấu hình:

led1.pin = 13;
led1.state = LED_OFF;

Bật:

led1.state = LED_ON;

Ta đã biến một nhóm biến rời rạc thành một cấu trúc quản lý thiết bị.


7. Nhưng STM32 thực tế còn mạnh hơn

Ví dụ ta có:

typedef struct
{
    int pin;
    int speed;
    int direction;
    int enabled;
} Motor;

Ta có thể tạo nhiều motor:

Motor motor1;
Motor motor2;
Motor motor3;

Hoặc:

Motor motors[3];

Khi đó:

motors[0].speed = 100;
motors[1].speed = 200;
motors[2].speed = 150;

Đây là sự kết hợp:

struct
   ↓
typedef
   ↓
array
   ↓
function
   ↓
pointer

Đây là một trong những nền tảng quan trọng nhất của lập trình embedded C.


8. struct chứa cả enum

Một ví dụ rất gần với STM32:

typedef enum
{
    STATE_IDLE,
    STATE_RUNNING,
    STATE_ERROR
} SystemState;

typedef struct
{
    SystemState state;
    int temperature;
    int voltage;
    int current;
} System;

Tạo:

System system1;

Gán:

system1.state = STATE_RUNNING;
system1.temperature = 35;
system1.voltage = 3300;
system1.current = 120;

Ta có thể kiểm tra:

if (system1.state == STATE_ERROR)
{
    // xử lý lỗi
}

9. Vì sao điều này cực kỳ quan trọng với STM32?

Trong firmware thực tế, bạn sẽ gặp rất nhiều kiểu:

typedef struct
{
    ...
} xxx;

Ví dụ trong HAL của STM32, bạn sẽ gặp những cấu trúc kiểu:

UART_HandleTypeDef huart1;

hoặc:

GPIO_InitTypeDef GPIO_InitStruct;

Đừng nhìn những dòng này và nghĩ:

“Cái này phức tạp quá.”

Thực chất phía dưới vẫn là những thứ bạn đang học:

typedef
   +
struct
   +
biến

Ví dụ về tư duy:

GPIO_InitTypeDef GPIO_InitStruct;

có thể hình dung đơn giản là:

typedef struct
{
    ...
} GPIO_InitTypeDef;

rồi:

GPIO_InitTypeDef GPIO_InitStruct;

tức là tạo một biến có kiểu GPIO_InitTypeDef.


10. Một điểm rất quan trọng: . và ->

Bạn đã học con trỏ ở Bài 5.

Nếu có:

Motor motor1;

thì:

motor1.speed = 100;

dùng dấu:

.

Nhưng nếu:

Motor *pMotor;

và:

pMotor = &motor1;

thì:

pMotor->speed = 100;

dùng:

->

Hai cách này tương đương về mục đích:

motor1.speed = 100;

và:

pMotor->speed = 100;

với:

pMotor = &motor1;

Đây là thứ bạn sẽ gặp rất nhiều trong STM32 HAL.


11. Một ví dụ hoàn chỉnh

Hãy đọc thật chậm đoạn này:

typedef enum
{
    MOTOR_STOP,
    MOTOR_FORWARD,
    MOTOR_REVERSE
} MotorState;

typedef struct
{
    int speed;
    MotorState state;
    int enabled;
} Motor;

void Motor_Start(Motor *motor)
{
    motor->enabled = 1;
    motor->state = MOTOR_FORWARD;
}

void Motor_Stop(Motor *motor)
{
    motor->enabled = 0;
    motor->state = MOTOR_STOP;
}

int main(void)
{
    Motor motor1;

    motor1.speed = 100;
    motor1.state = MOTOR_STOP;
    motor1.enabled = 0;

    Motor_Start(&motor1);

    return 0;
}

Hãy phân tích:

Bước 1

typedef enum

Tạo kiểu trạng thái.

Bước 2

typedef struct

Tạo kiểu Motor.

Bước 3

Motor motor1;

Tạo một motor.

Bước 4

Motor_Start(&motor1);

Truyền địa chỉ của motor1 vào hàm.

Bước 5

Trong hàm:

motor->enabled = 1;

Dùng con trỏ để thay đổi trực tiếp motor1.


12. Mô hình tư duy bạn cần nhớ

Từ bây giờ hãy hình dung:

enum
 ↓
mô tả các trạng thái

struct
 ↓
gom nhiều thông tin

typedef
 ↓
đặt tên kiểu dữ liệu cho dễ dùng

pointer
 ↓
cho phép hàm thao tác trực tiếp lên struct

function
 ↓
thực hiện hành động trên struct

Ghép lại:

             ┌──────────────┐
             │     enum     │
             │   trạng thái  │
             └──────┬───────┘
                    ↓
             ┌──────────────┐
             │    struct    │
             │  thông tin    │
             └──────┬───────┘
                    ↓
             ┌──────────────┐
             │    typedef   │
             │ đặt tên kiểu │
             └──────┬───────┘
                    ↓
             ┌──────────────┐
             │   pointer    │
             │ thao tác trực│
             │ tiếp dữ liệu │
             └──────┬───────┘
                    ↓
             ┌──────────────┐
             │   function   │
             │ điều khiển   │
             └──────────────┘

🎯 Bài tập Bài 12

Bạn hãy tự viết một chương trình C quản lý một LED STM32 với:

LED_OFF
LED_ON
LED_BLINK

Yêu cầu:

  1. Dùng enum tạo 3 trạng thái trên.
  2. Dùng struct chứa:
    • pin
    • state
    • brightness
  3. Dùng typedef.
  4. Tạo biến:
Led led1;
  1. Tạo hàm:
Led_On()
Led_Off()
Led_Blink()
  1. Các hàm phải nhận:
Led *led
  1. Trong main() hãy:
    • tạo led1
    • đặt pin = 13
    • bật LED
    • sau đó chuyển sang BLINK.

Nếu bạn làm được bài này thì Bài 13 chúng ta sẽ bắt đầu một phần cực kỳ quan trọng: const, static, volatile — đặc biệt là volatile, thứ bạn bắt buộc phải hiểu khi lập trình thanh ghi, interrupt và ngoại vi STM32.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • Bạn có thể hướng dẫn tôi quy trình sửa chữa một mainboard laptop cũng như mainboard của máy tính để bàn không?
  • Có những mức nguồn DC nào trên một bo mạch mainboard laptop?Kỹ thuật đốt dòng để kiểm tra nguồn laptop được thực hiện như thế nào?
  • bài tiếp theo hợp lý là: BÀI 63 – SENSOR FUSION THỰC CHIẾN: ENCODER + IMU MPU6050 + EKF + ODOMETRY X,Y,θ TRÊN STM32F103
  • BÀI 62 – EKF (EXTENDED KALMAN FILTER) CHO ROBOT 2 BÁNH: FUSION ENCODER + IMU + ƯỚC LƯỢNG X, Y, θ, V, ω
  • BÀI 61 – KALMAN FILTER CHO ENCODER + IMU: ƯỚC LƯỢNG TỐC ĐỘ, GÓC θ VÀ SENSOR FUSION

Recent Comments

No comments to show.

Archives

  • September 2026
  • August 2026
  • July 2026
  • June 2026
  • May 2026
  • February 2026

Categories

  • Altium Desinger
  • Công nghệ
  • ESP32
  • Khác
  • Kiến thức điện máy
  • STM32
Live 3D Globes Visitor
©2026 Công nghệ 9 giây | Design: Newspaperly WordPress Theme