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 14 – STRUCT + ENUM + TYPEDEF: ĐƯA VÀO LẬP TRÌNH STM32

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

📘 BÀI 14 – STRUCT + ENUM + TYPEDEF: ĐƯA VÀO LẬP TRÌNH STM32

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

  • Bài 1: Kiểu dữ liệu C và RAM
  • Bài 2–4: Biến, toán tử, điều kiện, vòng lặp
  • Bài 5: Con trỏ
  • Bài 6: Mảng + con trỏ
  • Bài 7–9: struct, hàm và cách tổ chức dữ liệu
  • Bài 10–13: enum, typedef, struct kết hợp

👉 Bài 14 chúng ta bắt đầu chuyển từ “học C” sang “dùng C để lập trình vi điều khiển”.


1. Tư duy quan trọng nhất của Bài 14

Khi lập trình STM32, bạn sẽ không muốn viết kiểu:

int temperature;
int motorSpeed;
int motorDirection;
int motorState;
int error;

rồi chương trình ngày càng dài.

Thay vào đó, ta gom các thông tin liên quan thành một đối tượng:

typedef struct
{
    int temperature;
    int motorSpeed;
    int motorDirection;
    int motorState;
    int error;
} Motor_t;

Sau đó:

Motor_t motor1;

Ta có một “đối tượng dữ liệu” đại diện cho motor.

Đây chính là tư duy rất quan trọng trong embedded C.


2. STRUCT + ENUM

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

typedef enum
{
    MOTOR_STOP,
    MOTOR_RUN,
    MOTOR_ERROR
} MotorState_t;

Ta có:

MOTOR_STOP  = 0
MOTOR_RUN   = 1
MOTOR_ERROR = 2

Sau đó tạo struct:

typedef struct
{
    int speed;
    MotorState_t state;
} Motor_t;

Tạo biến:

Motor_t motor1;

Gán:

motor1.speed = 100;
motor1.state = MOTOR_RUN;

3. Tại sao cách này cực kỳ hữu ích với STM32?

Hãy tưởng tượng bạn có hệ thống:

Motor 1
Motor 2
Fan
Pump
Valve
Sensor
Alarm

Mỗi thiết bị có nhiều thông tin.

Ví dụ:

typedef enum
{
    DEVICE_OFF,
    DEVICE_ON,
    DEVICE_ERROR
} DeviceState_t;
typedef struct
{
    DeviceState_t state;
    int speed;
    int errorCode;
} Device_t;

Bây giờ:

Device_t motor1;
Device_t motor2;
Device_t fan;
Device_t pump;

Bạn có thể quản lý cả hệ thống rất gọn.


4. Đây chính là kiểu tư duy dùng trong firmware thực tế

Ví dụ máy giặt:

typedef enum
{
    WASH_IDLE,
    WASH_FILL,
    WASH_WASHING,
    WASH_DRAIN,
    WASH_SPIN,
    WASH_FINISH,
    WASH_ERROR
} WashState_t;

Sau đó:

typedef struct
{
    WashState_t state;

    int waterLevel;
    int motorSpeed;
    int temperature;

    int doorClosed;
    int errorCode;

} WashingMachine_t;

Tạo một biến:

WashingMachine_t machine;

Ví dụ:

machine.state = WASH_WASHING;
machine.waterLevel = 60;
machine.motorSpeed = 800;
machine.temperature = 35;
machine.doorClosed = 1;
machine.errorCode = 0;

Bây giờ machine chứa toàn bộ trạng thái của máy giặt.


5. Một điều rất quan trọng: ENUM thực chất là số

Ví dụ:

typedef enum
{
    OFF = 0,
    ON = 1,
    ERROR = 2
} State_t;

Ta có:

State_t state;

state = ON;

Trong bộ nhớ, về bản chất vẫn là một giá trị số.

Có thể hình dung:

state
  │
  ▼
┌───────────┐
│     1     │
└───────────┘

Trong firmware, điều này rất quan trọng vì CPU cuối cùng vẫn xử lý bit và số.


6. STRUCT cũng chỉ là vùng RAM

Ví dụ:

typedef struct
{
    uint8_t state;
    uint16_t speed;
    uint8_t error;
} Motor_t;

Khi khai báo:

Motor_t motor1;

RAM có thể hình dung:

motor1
┌──────────────┐
│ state        │ 1 byte
├──────────────┤
│ speed        │ 2 byte
├──────────────┤
│ error        │ 1 byte
└──────────────┘

Đây là điểm nối rất quan trọng giữa:

C → RAM → STM32


7. STRUCT + POINTER

Đây là phần cực kỳ quan trọng.

Ta có:

typedef struct
{
    int speed;
    int state;
} Motor_t;
Motor_t motor1;

Có thể truyền địa chỉ của motor1 vào hàm:

void Motor_Update(Motor_t *motor)
{
    motor->speed = 1000;
    motor->state = 1;
}

Gọi:

Motor_Update(&motor1);

Chú ý:

motor->speed

tương đương với:

(*motor).speed

Nhưng cách viết:

motor->speed

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


8. Đây là mẫu cực kỳ phổ biến trong STM32

Bạn sẽ gặp kiểu:

void Motor_Init(Motor_t *motor)
{
    motor->speed = 0;
    motor->state = MOTOR_STOP;
}
void Motor_Start(Motor_t *motor)
{
    motor->state = MOTOR_RUN;
}
void Motor_Stop(Motor_t *motor)
{
    motor->state = MOTOR_STOP;
    motor->speed = 0;
}

Sau đó:

Motor_t motor1;

Motor_Init(&motor1);

Motor_Start(&motor1);

Đây chính là cách xây dựng module firmware.


9. Một ví dụ gần với Blue Pill của bạn

Giả sử chúng ta điều khiển LED PC13.

Ta định nghĩa:

typedef enum
{
    LED_OFF,
    LED_ON
} LedState_t;

Tạo cấu trúc:

typedef struct
{
    LedState_t state;
} Led_t;

Tạo biến:

Led_t led;

Hàm:

void LED_On(Led_t *led)
{
    led->state = LED_ON;
}
void LED_Off(Led_t *led)
{
    led->state = LED_OFF;
}

Sau đó:

LED_On(&led);

Lúc này:

led.state = LED_ON

Nhưng lưu ý:

led.state mới chỉ là trạng thái trong RAM.

Nó chưa tự động làm chân PC13 sáng.

Ta cần một tầng điều khiển phần cứng:

void LED_Update(Led_t *led)
{
    if (led->state == LED_ON)
    {
        // GPIO PC13 ON
    }
    else
    {
        // GPIO PC13 OFF
    }
}

Đây chính là tư duy kiến trúc firmware:

        APPLICATION
             │
             ▼
       led.state
             │
             ▼
       LED_Update()
             │
             ▼
          GPIO
             │
             ▼
          PC13
             │
             ▼
           LED

10. Một kiến trúc lớn hơn

Sau này khi lập trình STM32, bạn sẽ thường gặp dạng:

main.c
 │
 ├── GPIO
 ├── UART
 ├── ADC
 ├── Timer
 ├── Motor
 ├── Sensor
 └── Application

Ví dụ:

typedef struct
{
    uint16_t adcValue;
    float voltage;
} Sensor_t;
typedef enum
{
    MOTOR_STOP,
    MOTOR_RUN
} MotorState_t;
typedef struct
{
    MotorState_t state;
    uint16_t speed;
} Motor_t;

Sau đó chương trình có:

Sensor_t sensor;

Motor_t motor;

11. Bài tập Bài 14

Bài tập 1

Tạo enum:

typedef enum
{
    LED_OFF,
    LED_ON,
    LED_ERROR
} LedState_t;

Sau đó tạo:

typedef struct
{
    LedState_t state;
    uint8_t brightness;
} Led_t;

Tạo:

Led_t led1;

Thiết lập:

led1.state = LED_ON;
led1.brightness = 80;

Hãy tự trả lời:

Trong RAM, led1 đang chứa những gì?


Bài tập 2

Viết hàm:

void LED_SetState(Led_t *led, LedState_t state)

để có thể gọi:

LED_SetState(&led1, LED_ON);

và:

LED_SetState(&led1, LED_OFF);

Bài tập 3 – quan trọng

Tạo:

typedef enum
{
    MOTOR_STOP,
    MOTOR_RUN,
    MOTOR_ERROR
} MotorState_t;

và:

typedef struct
{
    MotorState_t state;
    uint16_t speed;
    uint8_t errorCode;
} Motor_t;

Tạo:

Motor_t motor1;

Sau đó viết 3 hàm:

Motor_Start()
Motor_Stop()
Motor_Error()

sử dụng pointer + struct + enum.


🎯 Mục tiêu sau Bài 14

Bạn cần thực sự hiểu được chuỗi này:

enum
  ↓
typedef
  ↓
struct
  ↓
pointer
  ↓
function
  ↓
RAM
  ↓
STM32 peripheral

Nếu bạn nắm chắc chuỗi này, chúng ta có thể bước sang Bài 15: static, const, volatile – 3 từ khóa C cực kỳ quan trọng trong STM32.

Đặc biệt, volatile là thứ bạn bắt buộc phải hiểu khi làm GPIO interrupt, timer, UART, ADC, DMA và RTOS sau này.

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