stm32 interrupt mode and DMA mode complete serial communication

Keywords: Single-Chip Microcomputer stm32

Interrupt knowledge point


EXTI0 to EXTI15 are used for GPIO. Any GPIO can be used as the input source of EXTI through programming control. EXTI0 can be selected and configured as PA0, PB0, PC0, PD0, PE0, PF0, PG0, PH0 or PI0 through the EXTI0[3:0] bit of 1 (AFIO_EXTICR1) of AFIO's external interrupt configuration register. See figure. The use configuration of other EXTI lines (EXTI interrupt / event lines) is similar.

Explanation of HAL library and GPIO function library

In normal use, in addition to STM32CubeMX configuration, we sometimes need to configure some things ourselves. Learning and understanding HAL library is also a place we must learn

Open stm32f4xx first_ hal_ GPIO. H found a total of 8 functions defined

void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);

Function: GPIO initialization

example: HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);

Function: after function initialization, the pin returns to the default state, that is, the value when each register is reset

example: HAL_GPIO_Init(GPIOC, GPIO_PIN_4);
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

Function: read the level status of the pin under the port and the return value of the function is 0 or 1

example: HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4);
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);

Function: change the pin to 0 or 1

example: HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4,0);
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

Function: flip the level state of the pin

example: HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_4);    Commonly used in LED upper
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

Function: lock the pin level. For example, the current state of a pin is 1. When the pin changes, the state remains unchanged

example: HAL_GPIO_LockPin(GPIOC, GPIO_PIN_4);    
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);

Function: external interrupt service function to clear the interrupt flag bit

example: HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);    
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);

Function: interrupt callback function, which can be understood as the specific action to be responded by the interrupt function.

example: HAL_GPIO_EXTI_Callback(GPIO_PIN_4);    

HAL library serial communication

Serial port send / receive function

HAL_UART_Transmit();Serial port sends data, using timeout management mechanism 
HAL_UART_Receive();The serial port receives data and uses the timeout management mechanism
HAL_UART_Transmit_IT();Serial port interrupt mode transmission  
HAL_UART_Receive_IT();Serial port interrupt mode reception
HAL_UART_Transmit_DMA();Serial port DMA Mode send
HAL_UART_Transmit_DMA();Serial port DMA Mode reception

Serial port interrupt function

HAL_UART_IRQHandler(UART_HandleTypeDef *huart);  //Serial port interrupt processing function
HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);  //Serial port sending interrupt callback function
HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);  //Serial port sends half interrupt callback function (less used)
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);  //Serial port receive interrupt callback function
HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);//The serial port receives half of the callback function (less used)
HAL_UART_ErrorCallback();Serial port receiving error function

Serial port query function format

HAL_UART_GetState(); 
Function: Judgment UART Whether the reception of is over, or whether the sending of data is busy

give an example: while(HAL_UART_GetState(&huart4) == HAL_UART_STATE_BUSY_TX)   //Detect the end of UART transmission and observe the status

DMA knowledge

DMA definition:
DMA is used to provide high-speed data transmission between peripherals and memory or between memory and memory. Without CPU intervention, DMA data can be moved quickly. This saves CPU resources for other operations.
DMA transmission mode:
Memory to memory, peripherals to peripherals, memory to peripherals, peripherals to memory
DMA function operation:

Serial port DMA Send data:

HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
Serial port DMA Receive data:

HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
Serial port DMA Recovery function

HAL_UART_DMAResume(&huart1)

External interrupt light led

stm32cube and HAL library are adopted
1. Create project
Select chip

Set GPIOA6 as output and GPIOB1 as interrupt, and name it for easy observation


Then set PB1 as the pull-up resistance and trigger the falling edge.

Set interrupt priority. Since there is only one interrupt, set the highest priority 0,

Next, configure the clock and set it to external high speed

Next, set the clock parameters,

Then you can generate relevant programs and fill in the code of the relevant part of the main function
user code begin
Fill in the user code end

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{  
{HAL_GPIO_TogglePin(led1_GPIO_Port,led1_Pin);
}
}

That is, the callback function is used to modify the level

After burning successfully
The phenomenon can be observed by replacement grounding

Serial port interrupt communication

Create project
As before, just change a few settings




You can create the project later
Open keil and find stm32f1xx_hal.c add header file and definition code,

#include <stdio.h>
extern UART_HandleTypeDef huart1;   //Declaration serial port

Then in stm32f1xx_ Write the following two functions in Hal. C

/**
  * Function function: redirect c library function printf to DEBUG_USARTx
  * Input parameters: None
  * Return value: None
  * Description: None
  */
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}
 
/**
  * Function function: redirect c library functions getchar and scanf to DEBUG_USARTx
  * Input parameters: None
  * Return value: None
  * Description: None
  */
int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}


Next, rewrite the function in main.c

 #define RXBUFFERSIZE  256
char RxBuffer[RXBUFFERSIZE]; 
	printf("hello world\n");
			HAL_Delay(1000);

The printf function can be written


Interrupt function needs to be added
And add the following definitions in main.c:

#include <string.h>
 
#Define rxbuffersize 256 / / maximum number of bytes received
char RxBuffer[RXBUFFERSIZE];   //receive data 

In the main() main function, the call interrupt function is called once.

/* USER CODE BEGIN 2 */
	HAL_UART_Receive_IT(&huart1, RxBuffer, 1);
/* USER CODE END 2 */

Add interrupt callback function under main.c

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 
{
	if(huart->Instance==USART1)
	{	
		HAL_UART_Transmit(&huart1,RxBuffer,1,0xff);
	}
	HAL_UART_Receive_IT(&huart1, RxBuffer, 1); 
}

Then fine tune keil related settings


Then compile and burn

Serial port DMA sending and receiving data

Create project
Same as the serial port creation before
So is usart
Just add DMA settings
Open DMA settings, click add and select USART_RX USART_TX transmission rate is set to medium speed

Then modify the rate, mode, and DMA memory auto increment address

Click system core on the right and click DMA
Click Add to add menomen

Normal: normal mode
After one DMA data transmission, stop DMA transmission, that is, only one transmission
DMA pointer increment setting
Increment Address: the address pointer is incremented
Src Memory on the left represents the peripheral address register
Function: set whether the peripheral address remains unchanged or increases when transmitting data. If it is set to increment, add Data Width bytes to the address in the next transmission,
Dst Memory on the right represents the memory address register
Function: set whether the memory address is incremented when transmitting data. If it is set to increment, add Data Width bytes to the address in the next transmission,
This is the same as Src Memory, except for memory
The project can be generated later

Test DMA transmission

Add the following code
main.c

 /* USER CODE BEGIN Init */
	uint8_t Senbuff[] = "HELLO WORLD";  //Define data sending array
  /* USER CODE END Init */

while Loop

  while (1)
  {
    /* USER CODE END WHILE */
			HAL_UART_Transmit_DMA(&huart1, Senbuff, sizeof(Senbuff));
	        HAL_Delay(1000);
    /* USER CODE BEGIN 3 */
  }

result

summary

Through this experiment, I learned more about the serial communication and interrupt program, gained a lot, and learned more about the transmission mode of stm32. The DAM saves more resources and bypasses the cpu. I think this mode is very good

reference

On the code understanding of serial port in HAL Library

Posted by php_tom on Fri, 05 Nov 2021 23:08:26 -0700