Ngắt ngoài EXTI trên STM32F103C8T6

Ngắt ngoài trên STM32F103C8T6
Ngắt ngoài trên STM32F103C8T6

A, Giới Thiệu

Trong bài viết này mình sẽ giới thiệu cho các bạn cách cấu hình và lập trình một ngắt ngoài (external interrupts EXTI). Trước tiên chúng ta sẽ đi tìm hiểu NVIC là gì !

NVIC – Nested vectored interrupt controllerĐúng như tên gọi, bộ NVIC được phát triển nhằm hỗ trợ các ngắt xảy ra đồng thời, đang xử lý ngắt này thì có tín hiệu ngắt khác… Các ngắt cao có độ ưu tiên cao hơn sẽ được xử lý trướcViệc lập trình sử dụng ngắt là một kĩ năng quan trọng khi các bạn lập trìnhh vi điều khiển, nếu không có ngắt thì chương trình sẽ thực hiện theo một trình tự từ trên xuống dưới, ngắt giúp chương trình xử lý theo sự việc, đáp ứng được các sự kiện như sự thay đổi mức logic từ 1 chân vi điều khiển (ngắt ngoài).

 Tính năng chính của NVIC:

  • 68 vector ngắt (không bao gồm 16 ngắt của core)
  • Có thể lập trình 16 mức độ ưu tiên
  • Xử lý Các ngắt (interrupt) và ngoại lệ (exception) nhanh, Độ trễ thấp
  • Có quản lí năng lượng cho vector ngắt.
  • Có các thanh ghi điều khiển quá trình ngắt.

Ngắt ngoài EXTI là một phần của bộ NVIC. EXTI – Interrupt/Event controller Có thể lập trình là chọn loại sự kiện hoặc ngắt trên cạnh lên, cạnh xuống hay cả hai.

EXTI được tạo ra từ 2 nguồn :

+ Trên các chân ngoại vi GPIO thông thường

+ Trên các ứng dụng như : PVD, RTC, USB, Ethernet.

Tính năng chính của EXTI- Interrupt/Even controller:

  • Kích hoạt độc lập và mask trên các interrupt/event line
  • mỗi interrupt line đều có các bit trạng thái dành riêng cho từng line
  • Phát hiện ra các tín hiệu ngoài với độ rộng xung nhỏ hơn APB2 clock period.
  • Có tới 20 yêu cầu Interrupt/Even mềm

1, Sơ đồ khối của EXTI-Interrupt/Even controller

Ngắt ngoài trên STM32F103C8T6

112 chân pin GPIO được ánh xạ với 16 external interrupt/event lines

Ngắt ngoài trên STM32F103C8T6

Ở đây chúng ta thấy Các nhóm PXY được gom chung thành 1 line EXTI:

Với X : A,B,C,D,E,FG và y\Y : [1,16]

Ví dụ như là PA1, PB1, PC1, PD1, PE1, PF1, PG1 : được gom thành EXTI1 line qua một bộ chọn –> nếu ta đã cấu hình PA1 làm chân ngắt thì tất cả các chân 1 ở các PORT khác không được khai báo làm chân ngắt.

2, Bảng Vector Ngắt EXTI tương ưng trong bảng NVIC

Ngắt ngoài trên STM32F103C8T6

 

Cấu hình vector ngắt ở đây là

Pin Px0 -> Px4 tương ứng sẽ có 1 line ngắt riêng từ EXTI0_IRQ -> EXTI4_IRQ;

Pin Px5 -> Px9 chỉ có 1 line ngắt là EXTI9_5_IRQn;

chân Px10 -> Px15 chỉ có 1 line ngắt là EXTI15_10_IRQn. Px ở đây là chung cho tất cả các Port từ PortA -> Port G. Vd PortA, PortB….

3, Bảng mức độ ưu tiên ngắt NVIC:

pirority

Cấu hình mức độ ưu tiên xảy ra khi có nhiều ngắt, NVIC_IRQChannelPreemptionPriority + NVIC_IRQChannelSubPriority. Đây là 2 mức ưu tiên với tổng số bit là 4 tương ứng với 16 giá trị. Bảng ở trên tương ứng với các giá trị. NVIC_IRQChannelPreemptionPriority có giá trị càng cao thì mức ưu tiên càng thấp và ngược lại với NVIC_IRQChannelSubPriority.

4, Một số thanh ghi quan trọng

1.EXTI_IMR – Interrupt mask register: Thanh ghi này cài đặt cho phép có yêu cầu ngắt trên Line tương ứng. (cho phép ngắt)

Ngắt ngoài trên STM32F103C8T6

2. EXTI_RTSR – Rising trigger selection register: Thanh ghi này được sử dụng để cấu hình chọn sườn lên làm tín hiệu kích hoạt ngắt.

Ngắt ngoài trên STM32F103C8T6

3. EXTI_FTSR – Falling trigger selection register: Thanh ghi này được sử dụng để cấu hình chọn sườn xuống làm tín hiệu kích hoạt ngắt

Ngắt ngoài trên STM32F103C8T6

4. EXTI_SWIER – Software interrupt even register: Thanh ghi này cho phép kích hoạt Line ngắt tương tứng bằng phần mềm và đồng thờ thanh ghi này cho phép mô phỏng ngắt ngoài xảy ra trên chân đã được cấu hình(thay vị tác động bằng cạnh lên/xuống trên chân vi điều khiển ta có thể sử dụng nó để giả lập tác động từ bên ngoài bằng việc set hoặc reset bit tương ứng).

Ngắt ngoài trên STM32F103C8T6

5. EXTI_PR – Pending register:  Đây là thanh ghi chờ xử lý ngắt, khi có yêu cầu ngắt được tạo ra trên một Line ngắt thì bit tương tứng của thanh ghi này được bật lên cho đến khi ngắt này được xử lý. Nhiều trường— hợp có sự thay đổi sườn tín hiệu tạo ra yêu cầu ngắt nhưng ngắt không được thực thi như: độ ưu tiên thấp, chưa cho phép ngắt toàn cục.

Ngắt ngoài trên STM32F103C8T6

B, DEV CODE

Ví dụ : Cấu hình ngắt ngoài trên chân PA1, tạo một ngắt khi phát hiện một cạnh lên (Falling edges), trong trình phục vụ ngắt, led PC13 sẽ đảo trạng thái mỗi khi một ngắt được tạo ra.

Cấu hình Chân ngắt PA1 và Led PC13

void NVIC_Configuration(){
     GPIO_InitTypeDef GPIO_InitStructure;
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA, ENABLE);
	
     GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_13; /*init Led PC13*/
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
     GPIO_Init(GPIOC,&GPIO_InitStructure);
	
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ; /*init button PA1*/
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
     GPIO_Init(GPIOA, &GPIO_InitStructure);	

     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1); /*mapping*/
}

Cấu hình mức độ ưu tiên ngắt

void NVIC_Configuration(){
     NVIC_InitTypeDef NVIC-InitStructure;

     /*chọn 1 bit cho preemption priority*/
     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
     NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQChannel;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructure);
}

Cấu hình ngắt Ngoài trên chân PA1

void EXTI_setup()[
     // Enable AFIO for EXT1 module
     EXTI_InitTypeDef EXTI_InitStructure;
     // Configure EXT1 line 1 to generate an interrupt on falling edge
     EXTI_ClearITPendingBit(EXTI_Line1); /*clear the EXTI1 line interrupt pending bit*/
     EXTI_InitStructure.EXTI_Line = EXTI_Line1;
     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
     EXTI_Init(&EXTI_InitStructure);
}

Trình phục vụ ngắt ISR

void EXT1_IRQHandler(void){
  if(EXTI_GetITStatus(EXTI_Line1) != RESET){
     GPIO_WriteBit(GPIOC, GPIO_Pin_6,(BitAction)(1- GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_6)));
      /*toggle bit PC13*/
     EXTI_ClearITPendingBit(EXTI_Line0);
  }
}

Link tải source code tại đây

Chúc các bạn thành công!