Download as pdf or txt
Download as pdf or txt
You are on page 1of 36

BÀI 1.

PROJECT MẪU
Phần mềm chuẩn bị: STM32CubeMX, Keil uVision5,
https://www.keil.com/dd2/pack/
https://www.mediafire.com/file/y69tkgd0f4s4yb9/%5BHshop.vn%5D+ST-
Link+V2.zip
Bước 1: Tạo Folder lưu Project, ví dụ:

Bước 2: Tạo Project sử dụng STM32CubeMX


- Click vào New Project

- Chọn dòng vi điều khiển sử dụng: STM32F103C8


- Cấu hình Debug
- Cấu hình thạch anh ngoài

- Cấu hình đồng hồ dao động


Chọn HCLK là 72MHz
- Cấu hình biên dịch code

- Chọn tên Project và IDE sử dụng


BÀI 2: BLINK LED
Bài tập: Viết chương trình thực hiện nhấp nháy LED với thời gian 500ms
LÝ THUYẾT GPIO
GPIO_Mode có 8 tùy chọn (tức là 8 chế độ làm việc của GPIO):
GPIO_Mode_AIN analog input;
GPIO_Mode_IN_FLOATING floating input;
GPIO_Mode_IPD pull-down input;
GPIO_Mode_IPU pull-up input;
GPIO_Mode_Out_OD open-drain output;
GPIO_Mode_Out_PP push-pull output;
GPIO_Mode_AF_OD Alternate function Push Pull;
GPIO_Mode_AF_PP Alternate function Open Drain.
STM32 GPIO được cấu tạo như sau:

Hình 2-3-6. GPIO_Mode


STM32 GPIO bao gồm 2 khối cơ bản:
Input Driver: Bao gồm thanh ghi Input Data (IDR), và 1 trigger. Tín hiệu Input
ngoài việc được ghi vào IDR còn theo các đường Analog để vào bộ ADC, hoặc theo
đường Alternate function input vào các ngoại vi khác
Output Drive: Bao gồm thanh ghi Output Data (ODR), một khối output control để
chọn tín hiệu ra là từ ODR hay từ các ngoại vi khác. Tiếp đến điều khiển 2 mosfet cho
điện áp ra ở I/O pin
Chức năng của STM32 GPIO bao gồm:
 Input:
- Input pullup: Đầu vào có trở kéo lên (điện áp mặc định trên chân là Vcc)
- Input pulldown: Đầu vào có trở kéo xuống (điện áp mặc định trên chân là 0V)
- Input floating: Đầu vào thả nổi, điện áp không cố định dao động từ 0V tới
Vcc
- Analog: Đầu vào tương tự, dùng để đo ADC
 Output:
- Output Push Pull: Cấu hình Pin IO là đầu ra dạng đẩy kéo, tín hiệu sẽ chỉ có
Vcc hoặc 0V tương ứng với Bit 1 và 0 ghi vào chân đó.
- Output Open drain: Cấu hình Pin IO là đầu ra dạng cực máng hở. Chỉ có thể
kéo về 0V bằng cách ghi bit 0, khi ghi bit 1, chân IO sẽ có điện áp tương ứng
với nguồn nối vào IO đó.
- Alternate function Push Pull: Cấu hình Pin IO vừa là ngõ ra, vừa là ngõ vào,
trong đó đầu ra kiểu đẩy kéo, đầu vào không có điện trở kéo lên và kéo
xuống.
- Alternate function Open Drain: Cấu hình Pin IO vừa là ngõ ra, vừa là ngõ
vào, trong đó đầu ra dạng cực máng hở, đầu vào không có điện trở kéo lên và
kéo xuống (thường gặp trong I2C).
Bước 1: Cấu hình trên phần mềm STM32CubeMX
Lập trình nhấp nháy LED 100ms
- Hàm đảo trạng thái của Pin
Tham số: void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
GPIOx: Các khối GPIO của vi điều khiển, bao gồm GPIOA, GPIOB, GPIOC.
GPIO_Pin: Pin muốn điều khiển, từ Pin 0 đến Pin 15.
Ví dụ:
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_13);

HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15);
- Hàm xuất tín hiệu đầu ra của Pin
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)

GPIOx: Các khối GPIO của vi điều khiển, bao gồm GPIOA, GPIOB, GPIOC.
GPIO_Pin: Pin muốn điều khiển, từ Pin 0 đến Pin 15.
PinState: Trạng thái Pin
GPIO_PIN_SET: mức 1
GPIO_PIN_RESET: mức 0
Ví dụ:
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);
HAL_Delay(500);

Kết nối mạch nạp


- Đối với mạch nạp STM8, STM32 ST-Link V2 Mini
PA13: SWDIO
PA14: SWCLK

- Mạch Nạp STM8, STM32 ST-Link V2 (hỗ trợ 2 chuẩn nạp: JTAG, SWD)
Kiểm tra mạch nạp
BÀI 3: LẬP TRÌNH ĐIỀU KHIỂN LED QUA NÚT NHẤN
Bài tập: Lập trình STM32F1 sử dụng một ngõ vào (nút nhấn PA0) và một ngõ
ra (LED PC13). Mỗi lần nhấn nút thì thay đổi trạng thái LED.

- Hàm đọc giá trị đầu vào của Pin:


HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

Tham số:

GPIOx: Các khối GPIO của vi điều khiển, bao gồm GPIOA, GPIOB, GPIOC.
GPIO_Pin: Pin muốn điều khiển, từ Pin 0 đến Pin 15.
Hàm trả về giá trị SET (mức 1) hoặc RESET (mức 0)

Cấu hình trên CubeMX


Bài tập 1: Lập trình điều khiển theo yêu cầu sau:
+ Nhấn nút nhấn KEY0 thì LED0 sáng
+ Nhấn nút nhấn KEY1 thì LED0 tắt

BÀI 4: NGẮT NGOÀI VỚI STM32


I. Lý thuyết

External interrupt (EXTI) hay còn gọi là ngắt ngoài. Là 1 sự kiện ngắt xảy ra khi có tín
hiệu can thiệp từ bên ngoài, từ phần cứng, người sử dụng hay ngoại vi, … Phần này sẽ
trình bày ngắt ngoài của vi điều khiển STM32F103C8T6.
Sơ đồ các khối điều khiển ngắt ngoài:
Các line ngắt ngoài của STM32F103:
STM32F103 có 16line ngắt ngoài riêng biệt. LineX sẽ chứa ngắt cho các chân Px của
các Port. Ví dụ Line0 bao gồm ngắt ở các chân PA0, PB0, …, Line1 bao gồm các chân PA,
PB, …

Lưu ý rằng: Mỗi Line chỉ được phép có được 1 chân ngắt ngoài, nghĩa là nếu đã chọn
PA0 làm ngắt thì những chân 0 của các Port khác không được phép chọn làm ngắt
ngoài.

Bảng vector ngắt ngoài:


Line0 đến Line4 được phân vào các vector ngắt phân biệt EXTI0 → EXTI4.
Line5 đến Line9 được phân vào vector ngắt EXTI9_5.
Line10 đến Line15 được phân vào vector ngắt EXTI15_10.

Ngoài các Line kể trên ra, STM32F103 còn có 4 Line đặc biệt hỗ trợ ngắt ngoài cho các
ứng dụng như PVD, RTC, USB, Ethernet.

Ngắt ngoài hoạt động như thế nào?


Giả sử một chân của vi điều khiển được cấu hình ngắt ngoài, nếu như tín hiệu mà chân
đó nhận được bị thay đổi trạng thái mức năng lượng (từ mức HIGH xuống LOW hoặc
ngược lại) thì ngắt sẽ được kích hoạt. Dựa vào sự chuyển đổi trạng thái, người ta chia ra
làm 3 loại:

• Rising edge (sườn lên): phát hiện ngắt khi tín hiệu chuyển từ mức LOW lên HIGH.
• Falling edge (sườn xuống): phát hiện ngắt khi tín hiệu chuyển từ mức HIGH xuống
LOW.
• Rising/Falling edge (sườn lên và xuống): phát hiện ngắt khi tín hiệu thay đổi mức
năng lượng, từ HIGH xuống LOW và từ LOW lên HIGH.

Mức độ ưu tiên của ngắt:

Không chỉ riêng ngắt ngoài, tất cả các ngắt đều có mức độ ưu tiên mặc định hoặc
người dùng có thể thiết lập lại. Mức độ ưu tiên ngắt có thể hiểu là độ ưu tiên thực hiện
công việc. Ví dụ, chúng ta lập trình 2 chương trình ngắt A và B, trong đó B có mức độ ưu
tiên cao hơn. Nếu vi điều khiển đang thực hiện chương trình ngắt A mà đột nhiên nhận
được yêu cầu ngắt B, thì A sẽ bị tạm dừng và B sẽ chiếm dụng vi xử lý.

Người ta đưa ra 2 khái niệm ưu tiên ngắt là Preemption Priority và Sub Priority. Vi điều
khiển sẽ so sánh Preemption Priority của từng ngắt trước, rồi mới đến Sub Priority. Cụ
thể:

- Ngắt có Preemption Priority cao hơn thì sẽ được ưu tiên thực hiện trước.
Nếu một ngắt Preemption Priority thấp đang trong quá trình được thực thi mà có ngắt
có Preemption Priority cao hơn yêu cầu thì ngắt có Preemtion Priority thấp hơn sẽ tạm
ngưng thực thi, đồng thời ngắt có Preemption Priority cao hơn sẽ chiếm dụng vi xử lý để
thực thi.

- Nếu một ngắt đang thực thi, một ngắt khác có cùng Preemption Priority nhưng có Sub
Priority cao hơn yêu cầu thì cũng sẽ không chiếm dụng vi xử lý. Vi xử lý vẫn tiếp tục thực
hiện ngắt có Sub Priority thấp hơn.

- Nếu các ngắt có cùng Preemtion Priority đang ở trạng thái chờ thì ngắt nào có Sub
Priority cao hơn thì sẽ được thực hiện trước.

- Nếu các ngắt có cùng Preemtion Priority và Sub Priority thì ngắt nào đến trước sẽ
được phục vụ trước.

II. Hướng dẫn cấu hình ngắt ngoài trên CubeMX

1. Chọn chip STM32F103C8T6, cấu hình SYS là Serial Wire, và cấu hình dao động.
2. Khởi tạo chân dùng làm ngắt ngoài.
Chọn chân muốn cấu hình ngắt ngoài, click chuột trái và chọn GPIO_EXTI.

3. Cấu hình ngắt ngoài.


Vào mục GPIO, chọn những chân đã khởi tạo ngắt ngoài để cấu hình nhé.
Ở đây chúng ta quan tâm tới 2 mục thôi:
GPIO mode: Chọn chế độ bắt tín hiệu để ngắt

• Rising edge trigger detection: Chế độ bắt sườn lên.


• Falling edge trigger detection: Chế độ bắt sườn xuống.
• Rising/Falling edge trigger detection: Chế độ bắt cả sườn lên và xuống.

GPIO Pull-up/Pull-down: Chọn trở nội kéo lên nguồn hay xuống đất.
(tham khảo lại bài STM32 GPIO)

4. Cho phép ngắt và thiết lập ưu tiên ngắt


Vào mục NVIC, tích vào ô Enable và có thể thiết lập ưu tiên ngắt.
Nên chọn Preemtion Priority khác 0 để tránh với những ngắt mặc định dưới hình.
III. Các hàm quan trọng

Hàm sự kiện ngắt, khi vi điều khiển phát hiện ngắt ngoài sẽ nhảy vào thực hiện chương
trình trong hàm này.
void HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin)
Tham số:
GPIO_Pin: Chân cấu hình ngắt ngoài
Lưu ý: Bất cứ yêu cầu ngắt ngoài tại chân nào cũng nhảy vào hàm này, vì thế nếu sử dụng nhiều
chân ngắt ngoài thì cần kiểm tra xem đó là chân nào. Ví dụ:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)


{
if (GPIO_Pin == GPIO_PIN_0)
{
// chương trình ngắt của chân 0
}
else if (GPIO_Pin == GPIO_PIN_1)
{
// chương trình ngắt của chân 1
}
}
IV. Bài tập ví dụ
Bài 1: Viết một chương trình sử dụng chip STM32F1 để điều khiển trạng thái 2 đèn led,
trong đó một led nhấp nháy chu kỳ 100ms, một led được điều khiển bởi hai nút nhấn
(yêu cầu sử dụng ngắt ngoài).

Cấu hình CubeMX

Bước 1: Chọn chip STM32F103C8T6, chọn debug bằng Serial Wire.

Bước 2: Khởi tạo chân làm ngắt ngoài, ở đây mình chọn chân nút bấm là PA0 và PA1

Bước 3: Cấu hình cho ngắt ngoài


Chọn trở nội kéo lên nguồn, khi đó khi nhấn nút thì chân tín hiệu nhận mức logic0. Để
yêu cầu ngắt ngay khi nhấn nút thì chúng ta chọn mode là bắt sườn xuống (Falling Edge)
khi tín hiệu chuyển từ mức HIGH xuống LOW.

Bước 4: Cho phép ngắt và thiết lập ưu tiên:

Bước 5: Khởi tạo và cấu hình cho ngõ ra là led, ở đây mình chọn chân PC13 là led có sẵn
trên kit và thêm 1 led ở chân PC14.
Bước 6: Vào mục Project Manager, đặt tên, chọn đường dẫn lưu Project, chọn trình biên
dịch và sinh code thôi.

Code Keil C

1. Lập trình cho đèn Led 1 nhấp nháy chu kỳ 1s


while (1)
{
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
HAL_Delay(1000);
}
2. Lập trình hàm ngắt ngoài
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_1) == 0)
{
HAL_Delay(20);
if (HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_1) == 0)
{
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_8);
}
}
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)


{
if (GPIO_Pin == GPIO_PIN_0)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, 1);
}
else if (GPIO_Pin == GPIO_PIN_1)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, 0);
}
}
Giải thích: Led ở PC13 nhấp nháy liên tục chu kỳ 1s
Cứ mỗi lần nhấn nút, chương trình sẽ dừng xử lý ở hàm while và nhảy vào hàm ngắt.
Tiếp đó kiểm tra xem yêu cầu ngắt ứng với chân số bao nhiêu. Nếu là nút nhấn ở chân
PA0 thì bật led ở chân PC14, và led tắt khi nhấn nút nhấn ở PA1.

You might also like