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