完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
利用STM32的SPI2作为从设备,想中断接收数据,一直没调通。 现在使这样的,再主函数while(1)循环前,调用一次 HAL_SPI_Receive_IT(&hspi2, (uint8_t *)&spi2RecvBuff[0],2); 主循环里,现在基本清空了。SPI的接收回调函数里,通过串口发送一组数据,然后再调用 HAL_SPI_Receive_IT(&hspi2, (uint8_t *)&spi2RecvBuff[0],2); 想通过这种方法,使SPI2一直处于中断接收使能状态。 结果串口一直没有数据发送过来。用示波器测量SCK和MOSI,是有波形的,和主设备发过来的数据一致。 然后将以上的接收中断函数改成,发送中断函数,使设备不停的发送。 结果测量SCK和MISO,有对应波形,串口也有数据发过来。 是不是调用中断接收函数,还需要做些其他操作? 主函数部分: |
|
相关推荐
34个回答
|
|
我也组数据包,一包传过来,收进去解析检验,正确就进行下一步,出错则要求重发。定长数据包,不满整包的用无效数据补,就不用一个一个去判断了。虽然数据多传了一点,但是DMA速度比中断快。又或者你传包头,从机收到之后解析再决定下次收多少数据。 |
|
|
|
又仔细观察了下串口发送上来的数据,接收回调函数,只执行了一次。没有再循环调用接收中断函数。
|
|
|
|
现在怀疑是没有满足spi2中断接收完成的条件,没有调用回调函数。
|
|
|
|
放到SPI2_IRQHandler(void)函数里,就可以正常再次调用了。
void SPI2_IRQHandler(void) { /* USER CODE BEGIN SPI2_IRQn 0 */ /* USER CODE END SPI2_IRQn 0 */ HAL_SPI_IRQHandler(&hspi2); HAL_SPI_Receive_IT(&hspi2, (uint8_t *)&spi2RecvBuff[0],1); /* USER CODE BEGIN SPI2_IRQn 1 */ /* USER CODE END SPI2_IRQn 1 */ } |
|
|
|
本帖最后由 any012 于 2016-11-24 14:34 编辑
跟踪 HAL_SPI_Receive_IT(&hspi2, (uint8_t *)&spi2RecvBuff[0],1)函数的调用过程,发现是启动后,执行了一次这个函数后,回调函数也被执行了,然后回调函数再调用这个函数时,没有执行到回调函数这里。感觉是不是嵌套了? SPI_Receive_IT function is called. SPI interrupt enable. SPI enable. 1ms时间到 SPI_RxCloseIRQHandler function is called. SPI RX interrupt disable. SPI ERR interrupt disable. spi2 recive over. SPI_Receive_IT function is called. SPI interrupt enable. 1ms时间到 1ms时间到 1ms时间到 ----------------------------------------- 进一步,发现HAL_SPI_Receive_IT(&hspi2, (uint8_t *)&spi2RecvBuff[0],1)函数第二次被调用时,只是使能了SPI中断,没有使能SPI。 __HAL_SPI_ENABLE(hspi)没有被执行。 if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE) { /* Enable SPI peripheral */ __HAL_SPI_ENABLE(hspi); printf("rnSPI enable."); } SPI_CR1_SPE是SPI的使能位,这句话应该是,如果SPI没有使能,使能SPI。 但是检查串口输出的数据,SPI是在调用回调函数前,被关闭了的。 --------------------------------- 刚才看错了,SPI被使能后,就没有被关闭过。 那么,第二次调用HAL_SPI_Receive_IT(&hspi2, (uint8_t *)&spi2RecvBuff[0],1)后,就一直处于等待接收中断状态。 但奇怪为什么没有触发接收中断。SPI中断已设为最高优先级,主设备是每秒给一次信号。 |
|
|
|
本帖最后由 any012 于 2016-11-24 14:48 编辑
HAL_SPI_Receive_IT(&hspi2, (uint8_t *)&spi2RecvBuff[0],1)放在回调函数里: SPI_Receive_IT function is called. SPI interrupt enable. SPI enable. 1ms时间到 SPI_RxCloseIRQHandler function is called. SPI RX interrupt disable. SPI ERR interrupt disable. SPI rx callback. spi2 recive over. SPI_Receive_IT function is called. SPI interrupt enable. 1ms时间到 1ms时间到 1ms时间到 ---------------------------------------- HAL_SPI_Receive_IT(&hspi2, (uint8_t *)&spi2RecvBuff[0],1)放在中断函数里: SPI_RxCloseIRQHandler function is called. SPI RX interrupt disable. SPI ERR interrupt disable. SPI rx callback. spi2 recive over. SPI_Receive_IT function is called. SPI interrupt enable. SPI_Receive_IT function is called. SPI interrupt enable. 1ms时间到 SPI_RxCloseIRQHandler function is called. SPI RX interrupt disable. SPI ERR interrupt disable. SPI rx callback. spi2 recive over. SPI_Receive_IT function is called. SPI interrupt enable. SPI_Receive_IT function is called. SPI interrupt enable. 1ms时间到 SPI_RxCloseIRQHandler function is called. SPI RX interrupt disable. SPI ERR interrupt disable. SPI rx callback. spi2 recive over. SPI_Receive_IT function is called. SPI interrupt enable. SPI_Receive_IT function is called. SPI interrupt enable. 1ms时间到 |
|
|
|
|
|
|
|
在HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)函数里,使中断接收函数指向static void SPI_RxISR(SPI_HandleTypeDef *hspi)函数,并且打开SPI,打开SPI中断,然后该函数结束。
SPI接收中断后,调用static void SPI_RxISR(SPI_HandleTypeDef *hspi)函数。在该函数里,接收够指定字节的数据后,调用SPI_RxCloseIRQHandler(hspi)函数。在该函数里,关闭SPI接收中断,调用接收完成回掉函数。接收回调函数处理完成后,依次结束以上两个函数及中断函数。 回调函数虽然在关闭中断后,但依然在中断函数里内部。 |
|
|
|
现在是将HAL_SPI_Receive_IT(&hspi2, (uint8_t *)&spi2RecvBuff[0],1)放在void SPI2_IRQHandler(void)内。
发现其实进中断2次才调用一次回调函数。 spi2RecvNum: 0 spi2RecvBuff[2]: 3a0c 1ms时间到 spi2 recive over. spi2RecvNum: 3 spi2RecvBuff[3]: 3a0c spi2RecvBuff[4]: 3a0c 1ms时间到 spi2 recive over. spi2RecvNum: 5 spi2RecvBuff[5]: 3a0c spi2RecvBuff[6]: 3a0c 1ms时间到 spi2 recive over. spi2RecvNum: 7 spi2RecvBuff[7]: 3a0c spi2RecvBuff[8]: 3a0c 1ms时间到 spi2 recive over. spi2RecvNum: 9 spi2RecvBuff[9]: 3a0c spi2RecvBuff[10]: 3a0c |
|
|
|
楼主,你自己顶了那么多。我也没时间看那么多。你调用的接收函数原型是HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)。这个跟标准库不一样的是,你调用这个函数,就会一直等待接收完Size个字节。你调用这个函数之后,再去while轮询访问接收寄存器当然读不到数据了。
|
|
|
|
|
|
易元空灭 发表于 2018-8-23 12:13 没有在while(1)里轮询访问接收寄存器,而是在接收完成回调函数里,想再次调用这个函数,结果却不行。现在是放到void SPI2_IRQHandler(void)里了,暂时能用了。但想不明白为什么放到回调函数里却不行,从串口发上来的数看,应该是中断了2次才调用了一次回调函数。可能我设置还是有问题。 |
|
|
|
放到SPI2_IRQHandler
|
|
|
|
|
|
|
|
关注中,也遇到类似的问题,中断始终进不了。都快放弃hal库了
|
|
|
|
用DMA,速度杠杠的,我两路同时发送接收,每路40M bit/s,相当于单路80M bit/s,有没有很变态 |
|
|
|
用DMA,速度杠杠的,我两路同时发送接收,每路40M bit/s,相当于单路80M bit/s,有没有很变态 |
|
|
|
没接触过DMA,也曾考虑过DMA。但有个疑问,我这个是作为接收设备,需要判断帧首,长度的。用DMA的话,只能循环接收吧? |
|
|
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
2027 浏览 0 评论
STM32配合可编程加密芯片SMEC88ST的防抄板加密方案设计
1209 浏览 0 评论
2786 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
2557 浏览 3 评论
5240 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-12 00:13 , Processed in 0.784320 second(s), Total 77, Slave 71 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号