Stm32f4 xử lý tín hiệu số

Stm32f4 xử lý tín hiệu số

Kit STM32F407 Discovery với vi điều khiển hiệu suất cao STM32F407VGT6, cho phép người dùng dễ dàng phát triển các ứng dụng xử lý tín hiệu số (hình ảnh, video…). Nó bao gồm một công cụ ST-LINK tích hợp sẵn trên bảng mạch giúp nạp chương trình, gỡ lỗi nhanh chóng.

Hiện nay, Kit STM32F407 Discovery là loại kit được sử dụng rất nhiều ở các trường đại học, cao đẳng trong giảng dạy vi điều khiển ARM.

Thông số kỹ thuật của Kit STM32F407 

  • Vi điều khiển 32-bit ARM Cortex®-M4 STM32F407VGT6 với lõi FPU hỗ trợ xử lý tính toán dấu phẩy động, 1-MB bộ nhớ Flash, 192 Kbyte RAM.
  • On-board ST-LINK/V2 trên STM32F4-DISCOVERY giúp nạp chương trình, gỡ lỗi.
  • Nguồn điện cung cấp cho bảng mạch: thông qua cổng USB hoặc từ một nguồn cung cấp điện áp 5V bên ngoài.
  • Từ bảng mạch, có thể cấp nguồn 3,3 V và 5 V cho các ứng dụng.
  • Cảm biến chuyển động LIS302DL, ST MEMS 3 trục gia tốc.
  • Cảm biến âm thanh MP45DT02 ST-MEMS, mic cảm biến âm thanh vô hướng kỹ thuật số.
  • Bộ chuyển đổi DAC âm thanh CS43L22.
  • Tám đèn LED:
    + LD1 (đỏ / xanh lá cây) để giao tiếp USB
    + LD2 (màu đỏ) báo hiệu nguồn 3,3 V on
    + Bốn đèn LED màu: LD3 (màu cam), LD4 (màu xanh lá cây), LD5 (màu
    đỏ) và LD6 (màu xanh dương).
    + Hai USB OTG LED LD7 (màu xanh lá cây) VBUS và LD8 (màu đỏ).
  • Hai nút bấm (nút bấm User màu xanh, nút bấm Reset màu đen).
  • OTG FS USB với cổng nối micro-AB.
  • Header mở rộng cho tất cả LQFP100 I/O.
  • Phần mềm miễn phí bao gồm một loạt các ví dụ, sử dụng thư viện chuẩn của ST.

Phần mềm lập trình

Stm32f4 xử lý tín hiệu số

Các phần mềm được sử dụng để lập trình cho STM32F407 bao gồm:

  1. Atollic
  2. Keil
  3. STM32 Cube MX
  4. LabVIEW
  5. MATLAB

Tài liệu hướng dẫn sử dụng

Trước khi sử dụng Kit thì các bạn cần phải download 2 tài liệu theo đường link dưới đây:

  1. User Manual: 

https://drive.google.com/file/d/1BPcOV2SJvXbLgNK1jd8iUAs-gfwwZk2a/view?usp=sharing

  1. Reference Manual: 

https://drive.google.com/file/d/16CNoMZ1NxHB5CJOADaLeQS_Z1ipod_DZ/view?usp=sharing

Stm32f4 xử lý tín hiệu số

Trên vi điều khiển STM32F407VG có một bộ điều khiển ngắt/sự kiện ngoại gọi tắt là EXTI (External interrupt/event controller). EXTI bao gồm 23 bộ phát hiện sự kiện, từ đó khởi tạo nên các yêu cầu ngắt. Mỗi đường đầu vào có thể được cấu hình độc lập để lựa chọn kiểu là interrupt hay event và trigger event tương ứng (rising, falling hoặc cả 2). Mỗi đường ngắt cũng có thể được che một cách độc lập.

EXTI được kết nối với bộ xử lý ngắt lồng nhau NVIC như sau:

Stm32f4 xử lý tín hiệu số
Bộ xử lý ngắt lồng nhau NVIC

NVIC (Nested Vector Interrupt Controller) là khối quản lý ngắt trên các dòng vi điều khiển dựa trên lõi ARM Cortex M4. Khi có một sự kiện và sự kiện đó được cấu hình ngắt, thì tất cả ngắt sẽ được đưa vào khối NVIC, và dựa trên nhiều yếu tố mà NVIC sẽ quyết định xem ngắt nào sẽ được thực thi để đưa CPU vào Interrupt Service Routine.

Bộ điều khiển ngắt ngoại EXTI xử lý tất cả các tín hiệu yêu cầu ngắt đến từ tất cả các chân của vi điều khiển. Ngoài ra nó còn xử lý các yêu cầu ngắt đến từ các nguồn khác. Các yêu cầu ngắt được phân thành 23 đường ngắt khác nhau, trong đó các yêu cầu đến từ chân 0 của tất cả các port được xử lý trên line 0, các yêu cầu đến từ chân 1 của tất cả các port được xử lý trên line 1 v.v.. như mô tả ở hình dưới.

Stm32f4 xử lý tín hiệu số
Các đường ngắt khác nhau trên STM32F4 Discovery

7 đường ngắt EXTI còn lại được nối như sau:

• EXTI line 16 được nối vào PVD output

• EXTI line 17 được nối vào RTC Alarm event

• EXTI line 18 được nối vào USB OTG FS Wakeup event

• EXTI line 19 được nối vào Ethernet Wakeup event

• EXTI line 20 được nối vào USB OTG HS (configured in FS) Wakeup event

• EXTI line 21 được nối vào RTC Tamper and TimeStamp events

• EXTI line 22 được nối vào RTC Wakeup event

Yêu cầu ngắt trên line n với n nhận giá trị từ 0 đến 4 được xử lý trong chương trình con xử lý ngắt có tên:

void EXTIn_IRQHandler(void)

Các yêu cầu ngắt trên các line từ 5 đến 9 được xử lý chung trong chương trình con xử lý ngắt: void EXTI9_5_IRQHandler(void).

Các yêu cầu ngắt trên các line từ 10 đến 15 được xử lý chung trong chương trình con xử lý ngắt:

void EXTI15_10_IRQHandler(void).

Tín hiệu ngắt có thể được phân ra thành FALLING, RISING hoặc cả 2, tùy thuộc vào sự thay đổi mức hiệu điện thế.

Các ngắt có thể có độ ưu tiên khác nhau. Khi một ngắt có độ ưu tiên cao hơn đang được xử lý thì các ngắt khác phải chờ. Ta gọi các ngắt đang chờ là PENDING INTERRUPT.

IrqHandlerDescription
EXTI0_IRQn EXTI0_IRQHandler Handler for pins connected to line 0
EXTI1_IRQn EXTI1_IRQHandler Handler for pins connected to line 1
EXTI2_IRQn EXTI2_IRQHandler Handler for pins connected to line 2
EXTI3_IRQn EXTI3_IRQHandler Handler for pins connected to line 3
EXTI4_IRQn EXTI4_IRQHandler Handler for pins connected to line 4
EXTI9_5_IRQn EXTI9_5_IRQHandler Handler for pins connected to line 5 to 9
EXTI15_10_IRQn EXTI15_10_IRQHandler Handler for pins connected to line 10 to 15
Các chương trình con xử lý ngắt trên STM32F4 Discovery

Mức ưu tiên ngắt

NVIC trên chip ARM được dùng cho STM32F4 hỗ trợ cài đặt 16 mức độ ưu tiên của các ngắt:

Stm32f4 xử lý tín hiệu số
Chế độ chọn nhóm ngắt NVIC

Số n quyết định có bao nhiêu mức cấu hình ngắt cho Mức độ ưu tiên (Preemption Priority) và Sub-priority.

Quy tắc hoạt động của mức độ ưu tiên ngắt như sau:

1. Khi cả hai ngắt có cùng mức độ ưu tiên

Ngắt nào xảy ra trước sẽ được thực thi trước.

2. Hai ngắt khác Mức độ ưu tiên (Preemption Priority)

Mức độ ưu tiên quyết định ngắt A có được phép thực thi khi ngắt B đang hoạt động hay không.
Nếu ngắt A có Mức độ ưu tiên lớn hơn B, thì nó sẽ được NVIC ưu tiên hơn so với ngắt B trong mọi trường hợp, nghĩa là ngắt B đang hoạt động, nhưng ngắt A yêu cầu thực thi thì NVIC sẽ cho phép dừng ngắt B, thực thi ngắt A trước và sau đó về thực thi tiếp ngắt B.

3. Hai ngắt khác Sub-priority

Khi có một ngắt A đang được thực thi (với Mức độ ưu tiên lớn hơn B, C), cùng lúc đó hai ngắt B và C có cờ báo cần thực thi, thì sub-priority sẽ quyết định 2 ngắt đang chờ này cái nào sẽ được thực thi trước

Để lập trình sử dụng ngắt ngoại, ta phải include các file sau từ thư viện CMSIS: stm32f4xx_syscfg.h, stm32f4xx_exti.h và misc.h. Việc cấu hình phải gồm 3 bước:

  • Bật syscfg clock và kết nối tới line yêu cầu ngắt
  • Cấu hình cho exti
  • Cấu hình cho NVIC

Để hiểu các dùng ngắt ngoại ta xem ví dụ sau:

Ví dụ 1:

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "stm32f4xx_syscfg.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_exti.h"
#include "misc.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void EXTILine0_Config(void);
void LEDInit(void);
/* Private functions ---------------------------------------------------------*/

/**
  * @brief  EXTI Example program
  * @param  None
  * @retval None
  */
void main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured,
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f4xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
        system_stm32f4xx.c file
     */

  /* Initialize LED4 mounted on STM32F4-Discovery board */
  LEDInit();

  /* Configure EXTI Line0 (connected to PA0 pin) in interrupt mode */
  EXTILine0_Config();

  /* Generate software interrupt: simulate a rising edge applied on EXTI0 line */
  EXTI_GenerateSWInterrupt(EXTI_Line0);

  while (1)
  {
  }
}

/**
  * @brief  Configures LED GPIO.
  * @param  None
  * @retval None
  */
void LEDInit()
{
  GPIO_InitTypeDef  GPIO_InitStructure;

  /* Enable the GPIO_LED Clock */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

  /* Configure the GPIO_LED pin */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
}

/**
  * @brief  Configures EXTI Line0 (connected to PA0 pin) in interrupt mode
  * @param  None
  * @retval None
  */
void EXTILine0_Config(void)
{

  GPIO_InitTypeDef   GPIO_InitStructure;
  EXTI_InitTypeDef   EXTI_InitStructure;
  NVIC_InitTypeDef   NVIC_InitStructure;

  /* Enable GPIOA clock */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  /* Enable SYSCFG clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

  /* Configure PA0 pin as input floating */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Connect EXTI Line0 to PA0 pin */
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

  /* Configure EXTI Line0 */
  EXTI_InitStructure.EXTI_Line = EXTI_Line0;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

  /* Enable and set EXTI Line0 Interrupt to the lowest priority */
  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

/**
  * @brief  This function handles External line 0 interrupt request.
  * @param  None
  * @retval None
  */
void EXTI0_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line0) != RESET)
  {
    /* Toggle LED1 */
    GPIO_ToggleBits(GPIOD, GPIO_Pin_12);

    /* Clear the EXTI line 0 pending bit */
    EXTI_ClearITPendingBit(EXTI_Line0);
  }
}

Ví dụ 2:

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "stm32f4xx_syscfg.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_exti.h"
#include "misc.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void EXTILine7_Config(void);
void LEDInit(void);
/* Private functions ---------------------------------------------------------*/

/**
 * @brief  EXTI Example program
 * @param  None
 * @retval None
 */
void main(void)
{
	/*!< At this stage the microcontroller clock setting is already configured,
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f4xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
        system_stm32f4xx.c file
	 */

	/* Initialize LED4 mounted on STM32F4-Discovery board */
	LEDInit();

	/* Configure EXTI Line0 (connected to PA0 pin) in interrupt mode */
	EXTILine7_Config();

	/* Generate software interrupt: simulate a rising edge applied on EXTI0 line */
	EXTI_GenerateSWInterrupt(EXTI_Line7);

	while (1)
	{
	}
}

/**
 * @brief  Configures LED GPIO.
 * @param  None
 * @retval None
 */
void LEDInit()
{
	GPIO_InitTypeDef  GPIO_InitStructure;

	/* Enable the GPIO_LED Clock */
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

	/* Configure the GPIO_LED pin */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOD, &GPIO_InitStructure);
}

/**
 * @brief  Configures EXTI Line0 (connected to PA0 pin) in interrupt mode
 * @param  None
 * @retval None
 */
void EXTILine7_Config(void)
{

	GPIO_InitTypeDef   GPIO_InitStructure;
	EXTI_InitTypeDef   EXTI_InitStructure;
	NVIC_InitTypeDef   NVIC_InitStructure;

	/* Enable GPIOA clock */
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
	/* Enable SYSCFG clock */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

	/* Configure PA0 pin as input floating */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	/* Connect EXTI Line0 to PA0 pin */
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource7);

	/* Configure EXTI Line0 */
	EXTI_InitStructure.EXTI_Line = EXTI_Line7;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);

	/* Enable and set EXTI Line0 Interrupt to the lowest priority */
	NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

/**
 * @brief  This function handles External line 0 interrupt request.
 * @param  None
 * @retval None
 */
void EXTI9_5_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line7) != RESET)
	{
		/* Toggle LED1 */
		GPIO_ToggleBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);

		/* Clear the EXTI line 0 pending bit */
		EXTI_ClearITPendingBit(EXTI_Line7);
	}
}