Professional Documents
Culture Documents
02 Huong Dan Thuc Hanh Ngat
02 Huong Dan Thuc Hanh Ngat
- Các hàm điều khiển hoạt động ngắt trong API HAL
• HAL_NVIC_SetPriorityGrouping - Hàm thiết lập nhóm ưu tiên
• HAL_NVIC_SetPriority - Hàm thiết lập mức ưu tiên
• HAL_NVIC_EnableIRQ
- Hàm cho phép ngắt
• HAL_NVIC_DisableIRQ
• HAL_NVIC_GetPriorityGrouping
• HAL_NVIC_GetPriority
• HAL_NVIC_SetPendingIRQ
• HAL_NVIC_GetPendingIRQ
• HAL_NVIC_ClearPendingIRQ
• HAL_NVIC_GetActive
• HAL_EXTI_SetConfigLine
• HAL_EXTI_GetConfigLine
• HAL_EXTI_ClearConfigLine
• HAL_EXTI_RegisterCallback
• HAL_EXTI_GetHandle
- Cho phép GPIO – AFIO tương ứng hoạt động bằng hàm:
__HAL_RCC_GPIOx_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Bước 4. Cấu hình NVIC:
- Bật kênh ngắt trong NVIC: HAL_NVIC_EnableIRQ(EXTI0_IRQn);
- Cấu hình mức độ ưu tiên: HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
- Cấu hình nhóm ưu tiên:
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
Bước 5. Chờ khi có ngắt.
- Chờ ngắt trong chương trình chính.
- Viết chương trình con phục vụ ngắt, trong file “stm32f1xx_it.c” hoặc trong “main.c”
PA0
Bước 2. Lựa chọn nguyên nhân gây ra ngắt ngoài
Lựa chọn chân chiều vào, chiều ra, mode. Thiết lập các thông số trên STM32CubeMX
như trong hướng dẫn lập trình với GPIO
while (1)
{}
}
static void MX_GPIO_Init(void)
{ GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
HAL_NVIC_SetPriority(EXTI0_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
}
//= Chương trình con phục vụ ngắt
void EXTI0_IRQHandler(void)
{
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0)//Khi có ngắt
{
}
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}
2.4 Ví dụ
Ví dụ 1. Viết chương trình điều khiển LED1 nhấp nháy liên tục, khi nhấn nút PB1
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType =
RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue =
RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{Error_Handler();}
RCC_ClkInitStruct.ClockType =
RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct,
FLASH_LATENCY_0) != HAL_OK){Error_Handler();}
}
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10|GPIO_PIN_15,
GPIO_PIN_RESET);
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI0_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
}
void EXTI0_IRQHandler(void){
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0){
for(int i=0;i<10;i++){
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15, GPIO_PIN_SET);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15, GPIO_PIN_RESET);
HAL_Delay(500);
}
}
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}
Ví dụ 2. Lập trình đếm sản phNm sử dụng ngắt ngoài EXTI0, số sản phNm được
hiển thị trên 1 led 7 thanh.
#include "main.h"
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
int dem;
char ma_led[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
0x82,0xf8,0x80,0x90};
void hienthi(unsigned char dulieu)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,dulieu&0x01);//a
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9, (dulieu>>1)&0x01);//b
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,(dulieu>>2)&0x01);//c
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_11,(dulieu>>3)&0x01);//d
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,(dulieu>>4)&0x01);//e
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,(dulieu>>5)&0x01);//f
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,(dulieu>>6)&0x01);//g
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,(dulieu>>7)&0x01);//dp
}
int main(void)
{
HAL_Init(); SystemClock_Config(); MX_GPIO_Init();
while (1)
{
hienthi(ma_led[dem]); HAL_Delay(500);
}
}
- Chương trình con viết trong file “stm32f1xx_it.c”
extern int dem; //Khai báo biến bên ngoài
void EXTI0_IRQHandler(void)
{
if(HAL_GPIO_ReadPin(GPIOA,PB1_Pin)==0)
{
dem=dem+1;//dem++
}
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}
Chú ý: Các hàm khởi tạo, thiết lập chiều dữ liệu giống như ví dụ 1
Ví dụ 3. Viết chương trình điều khiển LED1 nhấp nháy liên tục. Khi nhấn nút PB1
LED1 tắt, LED2 nhấp nháy 5 lần. Khi nhấn PB2 LED1 tắt, LED3 nhấp nháy 10
lần. Thiết lập ngắt với nút PB1 ưu tiên cao, ngắt với nút PB2 ưu tiên thấp.
#include "main.h"
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
#include "main.h"
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
int main(void){
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET);
HAL_Delay(200);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET);
HAL_Delay(200);
}}
- Thiết lập ưu tiên ngắt:
HAL_NVIC_SetPriority(EXTI0_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
HAL_NVIC_SetPriority(EXTI1_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI1_IRQn);
- Chương trình con viết trong file “stm32f1xx_it.c”
void EXTI0_IRQHandler(void){
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)==0){
for(int i=0;i<5;i++){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET);
HAL_Delay(1000);}}
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}
void EXTI1_IRQHandler(void){
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1)==0){
for(int i=0;i<10;i++){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
HAL_Delay(1000);}}
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
}
2.5. Bài tập.
1. Viết chương trình sử dụng ngắt ngoài EXTI1 điều khiển 8 LED theo quy luật.
Khi nhấn KEY1 một lần LED1 sáng các LED khác tắt, nhấn KEY1 2 lần LED1,
LED2 sáng các LED khác tắt… Nhấn KEY1 8 lần cả 8 LED đều sáng.
2. Viết chương trình sử dụng ngắt ngoài EXTI0 điều khiển đếm số lần nhấn KEY1
và hiển thị số lần nhấn trên 4 LED (LED1- LED4) dưới dạng số nhị phân (Giả
thiết: số lần nhấn <=15).
3. Lập trình đếm sản phNm sử dụng ngắt ngoài EXTI1, số sản phNm được
hiển thị trên 2 led 7 thanh.
4. Lập trình đếm sản phNm sử dụng ngắt ngoài EXTI2, số sản phNm được
hiển thị trên 4 led 7 thanh.
5. Lập trình sử dụng ngắt ngoài EXTI0, EXTI1 theo yêu cầu:
- Điều khiển LED1 nhấp nháy liên tục.
- Khi nhấn nút kết nối với chân EXTI0 – LED1 tắt. LED 7 thanh (7SEG1)
hiển thị từ 0 đến 5.
- Khi nhấn nút kết nối với chân EXTI1 – LED1 tắt. LED 7 thanh (7SEG2)
hiển thị từ 0 đến 8.
- Thiết lập ngắt EXTI0 ưu tiên cao hơn ngắt EXTI1.
6. Lập trình sử dụng ngắt ngoài mô phỏng bãi đỗ xe: Cảm biến vào CB1 nối với
chân PB0 ; Cảm biến ra CB2 nối với chân PB1.
-Hiển thị số xe vào, số xe ra, số xe có trong bãi lên LCD 16x2 theo yêu cầu
như sau:
7. Lập trình sử dụng ngắt ngoài mô phỏng bãi đỗ xe: Cảm biến vào CB1 nối với chân
PB0 ; Cảm biến ra CB2 nối với chân PB1.
-Hiển thị số xe vào, số xe ra, số xe có trong bãi lên 6 Led 7 thanh theo yêu
cầu như sau:
+ Số xe vào hiển thị trên 2 LED hàng Chục, hàng Đơn vị.
+ Số xe ra hiển thị trên 2 LED hàng Trăm nghìn, hàng Chục nghìn.
+ Số xe có trong bãi hiển thị trên 2 LED hàng Nghìn, hàng Trăm.