MCU:STM32F103ZET6
IDE: MDK-ARM V5 +STM32CubeMX5.0.0
串口调试助手:SSCOM3.2
功能描述:通过KEY_UP按键控制DMA串口1数据的传送。
需要配置DMA,串口USART1,使能按键中断,LED提示灯。
在MCU管脚图中找到PC0和PC1管脚(查原理图对应的管脚号),将管脚设置为GPIO_Output输出模式,此时在System Core的GPIO中,会出现对应端口,点击端口将GPIO output level设置为low,将User Label定义为LED。
选择PA0的端口为GPIO_EXTI0:
KEY_UP应为上升沿触发,并外接下拉电阻,点击端口将GPIO mode设置为External Interrupt Mode with Rising edge trigger detection,将GPIO Pull-up/Pull-down配置为Pull-down,将User Label定义为KEY_UP。
*TIPS:在将端口映射到EXTI线上后,SYS会出现以下警告:表示红色部分的模式不可使用,且因为PA0本身对应的是系统唤醒功能,因此System Wake-UP的功能也无法被选中。
接着在GPIO-Configuration中使能四个GPIO的中断(之前就是忘记了这个):
1. 配置DMA参数:
经过第二步后,PA9和PA10被配置为了USART1_RX/USART1_TX:
按照图中数字顺序配置DMA,点击Add,添加USARTT1_TX, Channel会自动选择,Direction默认选择的是存储器到外设,Mode不使用循环,设置为Normal即可;外设地址无增量,存储器地址有增量;Data Width根据需要将存储器和外设的宽度都设置为字节。
配置时钟为72 Mhz。
Tips:最好把Linker Settings中的Minimum Heap Size设置为0x600。
最后点Generate Code生成代码,并选择“Open Project”:
配置思路:首先在一个数组中定义要发送的内容;让LED1不断闪烁,表示系统正在运行;编写中断回调函数,当按键按下时发送数据到外设(USART1)中,并改变LED2状态表示进入中断。
此处与笔记2的分析过程相同:
************************************************************************************************************************************************
在生成的stm32f1xx_it.c中是系统中断的相关函数,找到四个外部中断的中断服务函数:
void EXTI0_IRQHandler(void)
{
/* USER CODE BEGIN EXTI0_IRQn 0 */
/* USER CODE END EXTI0_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
/* USER CODE BEGIN EXTI0_IRQn 1 */
/* USER CODE END EXTI0_IRQn 1 */
}
进入“HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0)”函数后发现定义如下:
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
/* EXTI line interrupt detected */
if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
HAL_GPIO_EXTI_Callback(GPIO_Pin);
}
}
服务函数中第一步对中断口清零,随后进入回调函数“HAL_GPIO_EXTI_Callback”:
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(GPIO_Pin);
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_GPIO_EXTI_Callback could be implemented in the user file
*/
}
回调函数中没有定义任何操作,因此将我们要实现的功能编写在回调函数中。
************************************************************************************************************************************************
/* USER CODE BEGIN PV */
uint8_t serialMsg[] = "DMA has been successfully received! \r\n";
/* USER CODE END PV */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_GPIO_TogglePin(GPIOC,LED1_Pin);
HAL_Delay(200);
/* USER CODE END WHILE */
/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin==UP_Pin)
{
for(long i=1;i<72000;i++){}; //软件消抖
if(HAL_GPIO_ReadPin(UP_GPIO_Port,UP_Pin)==1) //按键是否按下
{
HAL_GPIO_TogglePin(GPIOC,LED2_Pin);
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)serialMsg, sizeof(serialMsg));
HAL_Delay(1000);
}
}
}
/* USER CODE END 4 */
至此,编译后无错并下载到开发板中,就完成了通过STM32CubeMX调用HAL库实现按键控制DMA串口发送的效果程序。
实验现象:正常运行后,按下KEY_UP后DMA发送数组至串口: