完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1.外部中断
1.1 中断概念 中断其实就是机器收到信号后,放下正在处理的任务,来处理你设定好的中断函数。而外部中断则是外部信号引起的中断,如高电平、低电平、上升沿、下降沿等。 1.2 STM32F4外部中断 STM32F4 的每个 IO 都可以作为外部中断的中断输入口。 STM32F407 的中断控制器支持 23个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。 STM32F407 的 23 个外部中断为: EXTI 线 0~15:对应外部 IO 口的输入中断。 EXTI 线 16:连接到 PVD 输出。 EXTI 线 17:连接到 RTC 闹钟事件。 EXTI 线 18:连接到 USB OTG FS 唤醒事件。 EXTI 线 19:连接到以太网唤醒事件。 EXTI 线 20:连接到 USB OTG HS(在 FS 中配置)唤醒事件。 EXTI 线 21:连接到 RTC 入侵和时间戳事件。 EXTI 线 22:连接到 RTC 唤醒事件。 从上面可以看出, STM32F4 供 IO 口使用的中断线只有 16 个,但是 STM32F4 的 IO 口却远远不止 16 个,那么 STM32F4 是怎么把 16 个中断线和 IO 口一一对应起来的呢?于是 STM32就这样设计, GPIO 的管教GPIOx.0~GPIOx.15(x=A,B,C,D,E, F,G,H,I)分别对应中断线 0~15。这样每个中断线对应了最多 9 个 IO 口,以线 0 为例:它对应了 GPIOA.0、 GPIOB.0、 GPIOC.0、GPIOD.0、 GPIOE.0、 GPIOF.0、 GPIOG.0,GPIOH.0,GPIOI.0。而中断线每次只能连接到 1 个 IO口上,这样就需要通过配置来决定对应的中断线配置到哪个 GPIO 上了。下面我们看看 GPIO 跟中断线的映射关系图: 1.3 配置工程和编写代码 时钟树的配置不罗嗦了。 我们要实现当按下按键KEY0时,实现灯的亮灭。将PE4设置为外部中断模式。 1) 设置 IO 口模式,触发条件,设置 IO 口与中断线的映射关系。 2) 配置中断优先级(NVIC),并使能中断。 不要忘记设置NVIC选择卡。 配置完成后,就可以生成工程了。 3) 编写中断处理回调函数 HAL_GPIO_EXTI_Callback uint16_t A=0; void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==GPIO_PIN_SET) { A=2; HAL_GPIO_WritePin(GPIOF,GPIO_PIN_10,GPIO_PIN_SET); } else if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==GPIO_PIN_RESET) { A=3; HAL_GPIO_WritePin(GPIOF,GPIO_PIN_10,GPIO_PIN_RESET); } } 1.4 代码分享 2.阻塞式串口收发 2.1 串口通信概念 串口通信是一种通信协议,通信协议就是通信双方在数据传输过程中共同遵守的协定,数据的发送方按照某种协议把数据调制成可以被传输的信号,接收方就可以使用相同的协议,从信号中解析出数据。 2.2 USB转TTL模块接线 这里我们选择串口2。并用USB转TTL接口来与电脑进行通信。 连线如下: [tr]USE TO TTLSTM32[/tr]
VCC不接,3.3和5V只需接一个即可。 打开串口2,找到RX,TX对应的引脚。 2.3 配置串口参数检查、串口引脚信息是否错误 检查GPIO Settiings,是否为对应的引脚。 生成代码。 2.4代码编写及现象观察 在while中加入如下代码: HAL_UART_Transmit(&huart2,(uint8_t*)"Hello! ",12,0xFFFF); //通道句柄,传输信息,传输字长,传输时间 HAL_Delay(1000); 打开串口调试助手,注意波特率要设置一致,我都选择115200bit/s。 2.5重写printf和sancf函数及可能遇到的问题 重写pintf函数: int fputc(int c,FILE *stream) { uint8_t ch[1]={c}; HAL_UART_Transmit(&huart2,ch,1,0xFFFF); return c; } while (1) { printf("Hello %drn",123); HAL_Delay(1000); } 重写scanff函数: int fgetc(FILE *stream) { uint8_t ch[1]; HAL_UART_Receive(&huart2,ch,1,0xFFFF); return ch[0]; } while (1) { int val=0; scanf("%d",&val); printf("%dn",val); } 如果程序死在了printf上,可以使用 use MicroLIB(微库),在魔术棒 / Targer 选项页中勾选use MicroLIB。 3.中断式串口收发 3.1 在cube中开启中断。 进入NVIC选项卡,使能中断,调整优先级,生成代码。 3.2 代码编写 uint8_t Buffer[5]; void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { } HAL_UART_Transmit_IT(&huart2,buf,3); void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { HAL_UART_Transmit_IT(&huart2,buf,3);//把接收到的数据发送回去 HAL_UART_Receive_IT(&huart2,buf,3);//再开启下一次的接收 } HAL_UART_Receive_IT(&huart2,buf,3); 每发送和接收一个字节都会进入中断。 3.3 总结:使用中断方式收发的流程 1.调用函数开启一次中断收发的流程。 2.每发送或接收到一个字节会进入中断,由HAL进行处理,用户程序无需参与。 3.传输完指定数量的字节后HAL调用发送或接收完成回调函数。 4.DMA串口收发 4.1DMA的概念 DirectMemoryAccess(存储器直接访问)是指一种高速的数据传输操作,允许在外部设备和存储器之间直接读写数据,既不通过CPU,也不需要CPU干预。整个数据传输操作在一个称为“DMA控制器”的控制下进行。CPU除了在数据传输开始和结束时做一点处理外,在传输过程中还可以进行其他的工作。这样,在大部分时间里,CPU和输入输出都处于并行操作,因此使整个计算机系统的效率大大提高。 4.2在cube中开启DMA 4.3代码编写 uint8_t Buffer[5]; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { HAL_UART_Transmit_DMA(&huart2,buf,3); HAL_UART_Receive_DMA(&huart2,buf,3); } HAL_UART_Receive_DMA(&huart2,buf,3); 但当我们发送不定长字符时,会遇到数据溢出或者数据长度不够无法返回的错误。因此我们选择不定长输入的空闲中断代码。 /* USER CODE BEGIN 2 */ HAL_UART_Receive_DMA(&huart2, buffer,3); __HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE); /* USER CODE END 2 */ 并在串口中断函数中,编写空闲中断代码。 extern uint8_t Buffer[5]; void USART1_ IRQHandler(void) /* USER CODE BEGIN USART1_ IRQn日*/ if(_HAL_UART_GET_FLAG(&huart2,UART_ FLAG_ IDLE) != RESET)//触发空闲中断 { _HAL_UART_CLEAR_IDLEFLAG(&huart2);//清除空闲中断标志位 HAL_UART_DMAStop(&huart2);//停止发送 uint8_t len=3-_HAL_DMA_GET_COUNTER(huart2.hdmarx);//计算接收到了多少字节 HAL_UART_Transmit_DMA(&huart2,buffer,len);// 把接收到的数据发送出去 HAL_UART_Receive_DMA(&huart2,buffer,3);//开启DMA,准备下次接收 } /* USER CODE END USART1_ IRQn日*/ |
|
|
|
只有小组成员才能发言,加入小组>>
3310 浏览 9 评论
2991 浏览 16 评论
3492 浏览 1 评论
9057 浏览 16 评论
4086 浏览 18 评论
1175浏览 3评论
603浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
596浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2333浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1894浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 12:58 , Processed in 1.295474 second(s), Total 78, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号