完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
中断知识点
EXTI0 至 EXTI15 用于 GPIO ,通过编程控制可以实现任意一个 GPIO 作为 EXTI 的输入源。 EXTI0 可以通过 AFIO 的外部中断配置寄存器的1 (AFIO_EXTICR1) 的EXTI0[3:0] 位选择配置为 PA0 、 PB0 、 PC0 、 PD0 、 PE0 、 PF0 、 PG0 、 PH0 或者 PI0 ,见图其他 EXTI 线 (EXTI 中断 / 事件线 ) 使用配置都是类似的。 HAL库 GPIO函数库讲解 在正常使用中,除了STM32CubeMX配置之外,我们有时候还需要自己配置一些东西,学习并理解HAL库,也是我们必须要学习的一个地方 首先打开stm32f4xx_hal_gpio.h 发现一共定义有8个函数 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); 功能: GPIO初始化 实例:HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin); 功能:在函数初始化之后的引脚恢复成默认的状态,即各个寄存器复位时的值 实例:HAL_GPIO_Init(GPIOC, GPIO_PIN_4); GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 功能:读取端口下引脚的电平状态、函数返回值为0或1 实例:HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4); void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState); 功能:将引脚变成0或1 实例:HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4,0); void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 功能:翻转引脚的电平状态 实例:HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_4); 常用在LED上 HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 功能:锁住引脚电平,比如说一个管脚的当前状态是1,当引脚发生变化时状态不变 实例:HAL_GPIO_LockPin(GPIOC, GPIO_PIN_4); void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin); 功能: 外部中断服务函数,清除中断标志位 实例:HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4); void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin); 功能: 中断回调函数,可以理解为中断函数具体要响应的动作。 实例:HAL_GPIO_EXTI_Callback(GPIO_PIN_4); HAL库串口通信 串口发送/接收函数 HAL_UART_Transmit();串口发送数据,使用超时管理机制 HAL_UART_Receive();串口接收数据,使用超时管理机制 HAL_UART_Transmit_IT();串口中断模式发送 HAL_UART_Receive_IT();串口中断模式接收 HAL_UART_Transmit_DMA();串口DMA模式发送 HAL_UART_Transmit_DMA();串口DMA模式接收 串口中断函数 HAL_UART_Transmit();串口发送数据,使用超时管理机制 HAL_UART_Receive();串口接收数据,使用超时管理机制 HAL_UART_Transmit_IT();串口中断模式发送 HAL_UART_Receive_IT();串口中断模式接收 HAL_UART_Transmit_DMA();串口DMA模式发送 HAL_UART_Transmit_DMA();串口DMA模式接收 串口查询函数格式 HAL_UART_GetState(); 功能:判断UART的接收是否结束,或者发送数据是否忙碌 举例:while(HAL_UART_GetState(&huart4) == HAL_UART_STATE_BUSY_TX) //检测UART发送结束,观察状态 DMA知识 DMA定义: DMA用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。 DMA传输方式: 内存到内存,外设到外设,内存到外设,外设到内存 DMA函数操作: 串口DMA发送数据: HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 串口DMA接收数据: HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) 串口DMA恢复函数 HAL_UART_DMAResume(&huart1) 外部中断点亮led 采用stm32cube,HAL库编写 1,创建工程 选择芯片 设置GPIOA6为输出,GPIOB1为中断,并命名方便观察 之后设置PB1为上拉电阻,下降沿触发。 设置中断优先级,由于只有一个中断,因此设置最高优先级0, 接下来配置时钟,设置为外部高速 接下来设置时钟参数, 后面即可生成相关程序,将主函数里面的相关部分填写代码 即user code begin user code end里面填写代码 串口DMA恢复函数 HAL_UART_DMAResume(&huart1) 即采用回调函数,修改电平大小 烧录成功后 进行置换接地,即可观察到现象 串口中断通信 创建工程 跟前面的一样,只是改变几个设置 后面进行创建工程即可 打开keil,找到stm32f1xx_hal.c添加头文件和定义代码, #include extern UART_HandleTypeDef huart1; //声明串口 之后在stm32f1xx_hal.c中写入下面两个函数 /** * 函数功能: 重定向c库函数printf到DEBUG_USARTx * 输入参数: 无 * 返 回 值: 无 * 说 明:无 */ int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff); return ch; } /** * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx * 输入参数: 无 * 返 回 值: 无 * 说 明:无 */ int fgetc(FILE *f) { uint8_t ch = 0; HAL_UART_Receive(&huart1, &ch, 1, 0xffff); return ch; } 接下来在main.c里面改写函数 #define RXBUFFERSIZE 256 char RxBuffer[RXBUFFERSIZE]; printf("hello worldn"); HAL_Delay(1000); 可以写入printf函数 需要加入中断函数 并在main.c中添加下列定义: #include #define RXBUFFERSIZE 256 //最大接收字节数 char RxBuffer[RXBUFFERSIZE]; //接收数据 在main()主函数中,调用一次接收中断函数 /* USER CODE BEGIN 2 */ HAL_UART_Receive_IT(&huart1, RxBuffer, 1); /* USER CODE END 2 */ 在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); } 之后微调keil相关设置 之后编译烧录即可 串口DMA收发数据 创建工程 和之前串口创建一样 usart也一样 只需要添加DMA设置即可 打开DMA设置,点击add,选择USART_RX USART_TX 传输速率设置为中速 之后修改速率,模式,和DMA内存自增地址 右侧点击system core 点击DMA 点击add添加MENTOMEN Normal:正常模式 当一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次 DMA指针递增设置 Increment Address:地址指针递增 左侧Src Memory 表示外设地址寄存器 功能:设置传输数据的时候外设地址是不变还是递增。如果设置 为递增,那么下一次传输的时候地址加 Data Width个字节, 右侧Dst Memory 表示内存地址寄存器 功能:设置传输数据时候内存地址是否递增。如果设置 为递增,那么下一次传输的时候地址加 Data Width个字节, 这个Src Memory一样,只不过针对的是内存 后面生成工程即可 测试DMA传输 添加以下代码 main.c /* USER CODE BEGIN Init */ uint8_t Senbuff[] = "HELLO WORLD"; //定义数据发送数组 /* USER CODE END Init */ while循环 while (1) { /* USER CODE END WHILE */ HAL_UART_Transmit_DMA(&huart1, Senbuff, sizeof(Senbuff)); HAL_Delay(1000); /* USER CODE BEGIN 3 */ } 结果 总结 通过本次实验,我更加了解了串口通信和中断程序,收获很多,更加了解stm32的传输方式,DAM更加节省资源,绕开了cpu,我觉得这个方式很好 |
|
|
|
只有小组成员才能发言,加入小组>>
3209 浏览 9 评论
2896 浏览 16 评论
3402 浏览 1 评论
8845 浏览 16 评论
3997 浏览 18 评论
9628浏览 3评论
1006浏览 3评论
521浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
524浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2251浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-10-2 15:49 , Processed in 0.739428 second(s), Total 48, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号