Cách viết hàm xử lý ngắt stm32f4

Nhận viết luận văn đại học, thạc sĩ trọn gói, chất lượng, LH ZALO=>0909232620
Tham khảo dịch vụ, bảng giá tại: https://vietbaitotnghiep.com/dich-vu-viet-thue-luan-van

Download luận văn nghiên cứu khoa học ngành điện tử với đề tài: Thiết kế cài đặt một web server đơn giản trên một board vi xử lý (Microcontroller), cho các bạn làm luận văn tham khảo

Cách viết hàm xử lý ngắt stm32f4

DOWNLOAD ZALO 0917193864 at BẢNG BÁO GIÁ DỊCH VỤ VIẾT BÀI TẠI: LUANVANPANDA.COM

Nhận viết luận văn đại học, thạc sĩ trọn gói, chất lượng, LH ZALO=>0909232620
Tham khảo dịch vụ, bảng giá tại: https://vietbaitotnghiep.com/dich-vu-viet-thue-luan-van

Download luận văn nghiên cứu khoa học ngành điện tử với đề tài: Thiết kế cài đặt một web server đơn giản trên một board vi xử lý (Microcontroller), cho các bạn làm luận văn tham khảo

0% found this document useful (0 votes)

90 views

14 pages

Original Title

14.UART Interrupt(Lập Trình UART Với Ngắt Trên STM32)

Copyright

© © All Rights Reserved

Available Formats

PDF, TXT or read online from Scribd

Share this document

Did you find this document useful?

0% found this document useful (0 votes)

90 views14 pages

14.UART Interrupt (Lập Trình UART Với Ngắt Trên STM32)

Original Title:

14.UART Interrupt(Lập Trình UART Với Ngắt Trên STM32)

Jump to Page

You are on page 1of 14

You're Reading a Free Preview
Pages 6 to 12 are not shown in this preview.

Reward Your Curiosity

Everything you want to read.

Anytime. Anywhere. Any device.

No Commitment. Cancel anytime.

Cách viết hàm xử lý ngắt stm32f4

Hi all, Phần này mình sẽ nói về sử dụng đồng thời ngắt ngoại vi và FreeRTOS.

Để hiểu ngắt ngoại vi ảnh hưởng đến FreeRTOS như thế nào chúng ta sẽ cần tìm hiểu về cơ chế hoạt động của FreeRTOS như thế nào?

Nhân (Kernel) của FreeRTOS hoạt động dựa vào 1 ngắt timer của chip, ngắt này tạo clock của RTOS gọi là Tick, Tùy từng chip mà Tick của FreeRTOS sẽ đặt ở các hàm ngắt khác nhau, ví dụ ở ARM-Cortex M thì Tick sẽ đặt trong hàm ngắt SysTick (timer hệ thống), đối với PIC32 thì Tick sẽ đặt trong hàm ngắt Timer 1, đối với AVR thì mình không rõ nhưng chắc chắn sẽ đặt trong 1 ngắt timer. Chu kỳ ngắt thông thường sẽ là 1Khz, có thể thay đổi được tuy nhiên nếu thay đổi thì hàm vTaskDelay() sẽ chạy khác. Nếu đổi tần số Tick sang 10Khz thì muốn delay 10ms thì phải gọi vTaskDelay(100). Mỗi lần Tick thì FreeRTOS sẽ thực hiện các hoạt động phân quyền chạy Task vụ. Tức là cho phép Task nào chạy, Task nào tạm dừng, Task nào chạy trước, Task nào chạy sau.

Bởi vì nhân RTOS hoạt động dựa vào ngắt timer nên khi trong hệ thống muốn có những ngắt khác phải cẩn thận, vì sẽ ảnh hưởng đến hoạt động của toàn hệ thống. Ví dụ như PIC32 sử dụng ngắt timer1 để chạy RTOS vậy lập trình viên sẽ không được phép khởi tạo lại timer1, và tốt nhất là không nên sử dụng timer1 cho 1 mục đích nào khác nữa. Tương tự với với ARM thì không nên sử dụng ngắt Systick cho việc khác nữa. Đối với những chip bất kỳ thì việc ngắt ngoại vi luôn có ưu tiên. Để khi 2 ngắt cùng xảy ra thì hệ thống biết chạy ngắt nào trước và ngắt nào sau.

Đối với 1 chip có tốc độ chạy thấp ví dụ như PIC16, thì để đảm bảo sự realtime (RTOS chạy ổn) thì không nên có những ngắt liên tục với độ ưu tiên cao hơn ngắt Tick. Còn đối với chip tốc độ cao như STM32F4 thì có nhiều ngắt liên tục với ưu tiên cao hơn ngắt Tick thì không có vấn đề gì. Ở chip F4 mình đã từng thử 4 ngắt timer với tốc độ 200Khz có độ ưu tiên cao hơn ngắt Tick nhưng hệ thống vẫn hoạt động OK. Khi ngắt Tick xảy ra thì trong đấy sẽ gọi 1 hàm để hệ thống không thể xảy ra ngắt nữa gọi là hàm enter_critical_section(). Tại sao vậy? Bởi vì khi Nhân RTOS đang hoạt động nó không muốn có bất kỳ ngắt nào xảy ra làm ảnh hưởng đến hoạt động của nó. Cho đến khi nhân hoạt động xong thì nó mới gọi hàm exit_critical_section() để cho phép các ngắt khác có thể xảy ra.

Sau đây mình sẽ lưu ý thêm 1 chút về ngắt ngoại vi của ARM, Đối với các loại chip khác mình chưa thử RTOS nên mình sẽ chỉ trình bày về ARM, và bởi vì cấu trúc hệ thống ngắt của ARM khá đặc biệt nên quản lý ngắt cũng phức tạp hơn.

Trong ARM có 1 bộ quản lý ngắt gọi là NVIC (Nested vectored interrupt controller). Bộ này cung cấp cho mỗi ngắt 1 thanh ghi chứa giá trị ưu tiên ngắt. Đây là thanh ghi 4bit tức là sẽ có tối đa 16 mức ưu tiên ngắt. Giá trị càng thấp thì mức ưu tiên càng cao, giá trị 0 sẽ là mức ưu tiên lớn nhất. 4bit của thanh ghi ưu tiên ngắt sẽ được chia ra làm 2 thành phần:
+ Ưu tiên ngắt chính (Preempt Priority)
+ Ưu tiên ngắt phụ (Sub Priority)
Chúng ta có thể cài đặt được Ưu tiên ngắt chính sẽ dùng bao nhiêu bits trong 4 bit của thanh ghi ưu tiên ngắt, bằng cách gọi hàm
NVIC_PriorityGroupConfig(OPTION). Có 5 OPTION như sau:
+ NVIC_PriorityGroup_0: 0 bit preempt priority, 4 bit sub priority
+ NVIC_PriorityGroup_1: 1 bit preempt priority, 3 bit sub priority
+ NVIC_PriorityGroup_2: 2 bit preempt priority, 2 bit sub priority
+ NVIC_PriorityGroup_3: 3 bit preempt priority, 1 bit sub priority
+ NVIC_PriorityGroup_4: 4 bit preempt priority, 0 bit sub priority

Khi 2 ngắt xảy ra cùng lúc thì bộ NVIC sẽ dùng ưu tiên ngắt chính để xác định cái nào được ưu tiên chạy trước, nhưng nếu Ưu tiên ngắt chính như nhau thì NVIC sẽ duyệt đến Ưu tiên ngắt phụ để quyết định cái nào chạy trước.

Trong FreeRTOS có 1 define để cài đặt sẽ sử dụng bao nhiêu bits để làm preempt priority.
#define configPRIO_BITS
Do đó trong code tuyệt đối không gọi hàm NVIC_PriorityGroupConfig () khi sử dụng FreeRTOS, nếu có gọi thì gọi với OPTION tương ứng với define trên. Nếu không hệ thống của bạn sẽ treo đến vô tận luôn đó. 😀

Bên trên tôi đã nói tới hàm enter_crital_section() và exit_critical_section(), bên trên tôi có nói rằng khi chạy hàm enter_critical_section() thì trong hệ thống sẽ khổng thể có ngắt nào có thể xảy ra nữa, nhưng thực ra cũng tùy loại chip và tùy vào cài đặt của người dùng. Đối với ARM-CortexM3/4/7 thì 1 số ngắt vẫn có thể xảy ra ngay cả khi đã enter_critical_section() nếu cài đặt mức ưu tiên ngắt <<(dịch trái) 4 mà nhỏ hơn giá trị của thanh ghi Base_pri . Vậy thì phải biết giá trị của thanh ghi Basepri bằng bao nhiêu chứ? Cách tính giá trị Base Pri như sau:
configMAX_SYSCALL_INTERRUPT_PRIORITY =
( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 – configPRIO_BITS) )

Trong đó:
+ configMAX_SYSCALL_INTERRUPT_PRIORITY : Chính là Base pri
+ configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY: Giá trị priority lớn nhất mà các interrupt khác không nên vượt qua. Nếu đây là 1 thì các ngắt khác không nên đặt giá trị ưu tiên ngắt = 0. Trừ khi ngắt đó cần thiết có mức ưu tiên lớn hơn.
+ configPRIO_BITS : Là số bits dùng để mã hóa ưu tiên ngắt chính.

Có 1 số lưu ý khi sử dụng ngắt ngoại vi như sau:
+ Các ngắt có giá trị ưu tiên NVIC > BasePri mới có thể gọi được các hàm (API) của RTOS
+ Không phải API nào của RTOS cũng được phép gọi trong interrupt, chỉ những API có đuôi FromISA mới được phép gọi trong interrupt. Bởi vì đây là các hàm an toàn.
+ Tick RTOS không phải cái quan trọng nhất trong hệ thống, có 1 số cái quan trọng hơn, như USB, truyền thông, nhiều cái chỉ chậm 1 chút thôi sẽ bị hụt mất dữ liệu. Nên Tick RTOS không cần phải có mức ưu tiên cao nhất trừ khi ứng dụng của bạn không có truyền thông và cần đảm bảo độ real time.