硬件平台 | NUCLEO-F746ZG |
软件平台 | STM32CubeMX&MDK-ARM |
软件功能 | 串口DMA方式接收和发送、按键外部中断响应、LED灯 |
第一步:STM32CubeMX配置底层并生成工程代码
点击"New Project",在弹出界面点击"Board Selector",输入"nucleo-F746zg",窗口右侧显示筛选结果,双击;弹出对话框询问是否按照默认模式初始化所有外设,点击“Yes”;
进入图形化配置界面,关闭ETH和USB-OTG外设并将相关引脚设置为Reset State,设置PB3引脚为Reset State;引脚配置结果如下图所示
点击“Clock Configuration”进入时钟配置界面,设置参数时系统时钟频率为216MHz、APB1时钟频率为54MHz、APB2时钟频率为108MHz;
点击“Configuration”进入配置界面,双击"DMA",在DMA1中点击“Add”,添加USART3_RX、USART3_TX,其他参数保持默认,点击“Ok”完成DMA配置并关闭该窗口;
点击“NVIC”,使能USART3中断和外部中断并设置各中断优先级如下图示,点击“Ok”完成NVIC配置并关闭该窗口;
USART3配置保持默认即可;
点击标题栏“Project”->“Generate Code”,弹出工程设置对话框输入工程名和保存路径,选择IDE环境;
点击工程设置对话框的“Code Generator”,勾选图中所示选项,可以将每个外设的初始化代码放到相应的文件中,便于维护,完成工程设置,点击“Ok”即可生成工程代码
第二步:在MDK-ARM中添加用户代码
在gpio.c文件中用户代码段添加按键外部中断回调函数
/* USER CODE BEGIN 2 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == USER_Btn_Pin)
{
HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);
}
}
/* USER CODE END 2 */
在usart.c文件用户代码段添加如下代码,使能USART3的IDLE中断、DMA接收以及IDLE中断回调函数,并在usart.h中添加申明
/* USER CODE BEGIN 1 */
uint16_t usart3_rx_len;
uint8_t usart3rx_buf[50];
void USER_UART_Init(void)
{
/*使能串口空闲中断*/
__HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);
HAL_UART_Receive_DMA(&huart3,usart3rx_buf,50);
}
void UART_IDLE_Callback(UART_HandleTypeDef *huart)
{
uint32_t tmp1, tmp2;
tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE);
tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_IDLE);
if((tmp1 != RESET) && (tmp2 != RESET))
{
__HAL_UART_CLEAR_IDLEFLAG(huart);
/* set uart state ready*/
huart->gState = HAL_UART_STATE_READY;
/* Disable the rx DMA peripheral */
__HAL_DMA_DISABLE(huart->hdmarx);
/*Clear the DMA Stream pending flags.*/
__HAL_DMA_CLEAR_FLAG(huart->hdmarx,__HAL_DMA_GET_TC_FLAG_INDEX(huart->hdmarx));
/* Process Unlocked */
__HAL_UNLOCK(huart->hdmarx);
if(huart->Instance == USART3)
{
/* get rx data len */
usart3_rx_len = 50 - huart->hdmarx->Instance->NDTR;
HAL_UART_Receive_DMA(huart,usart3rx_buf,50);
}
}
}
/* USER CODE END 1 */
/* USER CODE BEGIN Prototypes */
extern uint16_t usart3_rx_len;
extern uint8_t usart3rx_buf[50];
void USER_UART_Init(void);
void UART_IDLE_Callback(UART_HandleTypeDef *huart);
/* USER CODE END Prototypes */
在main.c文件中添加如下代码
/* USER CODE BEGIN 2 */
USER_UART_Init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(LD1_GPIO_Port,LD1_Pin);
HAL_Delay(100);
if(usart3_rx_len)
{
HAL_UART_Transmit_DMA(&huart3,usart3rx_buf,usart3_rx_len);
usart3_rx_len = 0;
}
}
/* USER CODE END 3 */
在stm32f7xx_it.c文件中USART3中断服务程序中添加IDLE中断回调函数
/**
* @brief This function handles USART3 global interrupt.
*/
void USART3_IRQHandler(void)
{
/* USER CODE BEGIN USART3_IRQn 0 */
UART_IDLE_Callback(&huart3);
/* USER CODE END USART3_IRQn 0 */
HAL_UART_IRQHandler(&huart3);
/* USER CODE BEGIN USART3_IRQn 1 */
/* USER CODE END USART3_IRQn 1 */
}
编译工程并下载程序
第三步:实验现象
现象1:LED1不停的闪烁;
现象2:通过按用户按键可控制LED2亮灭;
现象3:打开串口调试助手,发送数据,调试助手可以接收到发送给单片机的数据,如下图示
转载请注明作者和出处:https://blog.csdn.net/gefeng3