在使用STM324的I2S全双工模式时发现HAL库可能存在的一个问题,DMA使能循环模式后I2S发送和接收完成的回调不执行。
查找原因发现是HAL库的stm32f4xx_hal_i2s_ex.c文件中I2SEx_TxRxDMACplt函数在判断到开启了DMA循环模式就不在调用完成回调。
/**
* @brief DMA I2S transmit receive process complete callback
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void I2SEx_TxRxDMACplt(DMA_HandleTypeDef *hdma)
{
I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
/* if DMA is not configured in DMA_CIRCULAR mode */
if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
{
if (hi2s->hdmarx == hdma)
{
/* Disable Rx DMA Request */
if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) ||
((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
{
CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2,SPI_CR2_RXDMAEN);
}
else
{
CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN);
}
hi2s->RxXferCount = 0U;
if (hi2s->TxXferCount == 0U)
{
hi2s->State = HAL_I2S_STATE_READY;
HAL_I2SEx_TxRxCpltCallback(hi2s);
}
}
if (hi2s->hdmatx == hdma)
{
/* Disable Tx DMA Request */
if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) ||
((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
{
CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_TXDMAEN);
}
else
{
CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2,SPI_CR2_TXDMAEN);
}
hi2s->TxXferCount = 0U;
if (hi2s->RxXferCount == 0U)
{
hi2s->State = HAL_I2S_STATE_READY;
HAL_I2SEx_TxRxCpltCallback(hi2s);
}
}
}
}
有点不太理解为什么开启了DMA循环模式就不给完成回调,我还在想是不是ST的工程师有什么特别的意图我没有理解。所以我决定看一下F4的半双工模式是不是也是这样操作的,打开stm32f4xx_hal_i2s.c,发送和接收的回调分别是在不同的函数上实现的。很明显是否开启DMA的循环模式并不影响完成回调的执行,也就是说在半双工模式开启DMA的循环模式是可以正常使用传输完成回调。
/**
* @brief DMA I2S transmit process complete callback
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
{
I2S_HandleTypeDef* hi2s = ( I2S_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
{
/* Disable Tx DMA Request */
CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_TXDMAEN);
hi2s->TxXferCount = 0U;
hi2s->State = HAL_I2S_STATE_READY;
}
HAL_I2S_TxCpltCallback(hi2s);
}
/**
* @brief DMA I2S transmit process half complete callback
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
{
I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
HAL_I2S_TxHalfCpltCallback(hi2s);
}
/**
* @brief DMA I2S receive process complete callback
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
{
I2S_HandleTypeDef* hi2s = ( I2S_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
{
/* Disable Rx DMA Request */
CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN);
hi2s->RxXferCount = 0U;
hi2s->State = HAL_I2S_STATE_READY;
}
HAL_I2S_RxCpltCallback(hi2s);
}
/**
* @brief DMA I2S receive process half complete callback
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
{
I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
HAL_I2S_RxHalfCpltCallback(hi2s);
}
此时我已经开始怀疑是不是F4的HAL库存在BUG,为了验证我的想法我决定看一下F3的库是否也是如此。为什么是F3,以为我发现F1和F7都是只有半双工模式,F7这么高端的芯片竟然在I2S的功能上比F4弱,实在是不能理解啊。
F3的HAL库半双工模式和全双工模式是共用同一个回调函数,通过代码我们可以发现F3不会出现使能DMA循环模式就不执行传输完成回调的问题。
/**
* @brief DMA I2S transmit receive process complete callback
* @param hdma DMA handle
* @retval None
*/
static void I2S_TxRxDMACplt(DMA_HandleTypeDef *hdma)
{
I2S_HandleTypeDef* hi2s = ( I2S_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
/* DMA Normal Mode */
if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
{
/* Disable Rx/Tx DMA Request */
if(((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) || ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
{
hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
I2SxEXT(hi2s->Instance)->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
}
else
{
hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
I2SxEXT(hi2s->Instance)->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
}
hi2s->RxXferCount = 0U;
hi2s->TxXferCount = 0U;
hi2s->State = HAL_I2S_STATE_READY;
}
HAL_I2S_TxRxCpltCallback(hi2s);
}
static void I2S_TxRxDMAHalfCplt(DMA_HandleTypeDef *hdma)
{
I2S_HandleTypeDef* hi2s = ( I2S_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
HAL_I2S_TxRxHalfCpltCallback(hi2s);
}
上一篇:STM32Cube-USART
下一篇:stm32f103 keil5 HAL库 UART中断接收
推荐阅读
史海拾趣
对于固态非易失性精密电位器构成的温度测量电路,网友可能关心的问题及其回答如下:
- 固态非易失性精密电位器的工作原理是什么?
- 回答:固态非易失性精密电位器(如X9C102/103/104/503系列)包含有99个电阻单元的电阻阵列。滑动单元的位置由CS、U/D和INC三个输入端控制。滑动端的位置可以被存储在一个非易失性存储器中,因此在下一次上电工作时可以被重新调用。
- 这个电位器在温度测量中是如何应用的?
- 回答:非易失性数控电位器在温度测量中的应用主要是通过其构成的记数式模数转换电路来实现的。这种电路能够将温度信号转换为数字信号,进而进行温度的测量和记录。
- 固态非易失性精密电位器的分辨率是多少?
- 回答:分辨率取决于具体的电位器型号。例如,X9C503(50k Ω)的每个抽头间的阻值为505 Ω,这意味着其分辨率等于最大的电阻值被99除。
- 这个电位器的工作电压范围是多少?
- 回答:工作电压范围通常为VCC=3V至5.5V。
- 固态非易失性精密电位器能否在长时间内保存数据?
- 回答:是的,所有的Xicor非易失性存储器都设计成并经过测试能够用于持久地保存数据的应用场合。滑动端位置数据可保存100年。
- 这个电位器在温度测量中有什么特点或优势?
- 回答:其特点包括低功耗、高分辨率、非易失性存储、长时间数据保存等。这些特点使得它在温度测量中具有高精度、高可靠性和长寿命的优势。
- 如何选择合适的固态非易失性精密电位器进行温度测量?
- 回答:在选择电位器时,需要考虑其工作电压、电阻范围、分辨率、功耗以及数据保存能力等参数。同时,还需考虑电路设计的具体需求和限制条件。
以上回答基于参考文章中的相关信息进行整理和总结,旨在解答网友可能关心的问题。
随着产品线的不断丰富和市场的扩大,CML逐渐意识到品质管理的重要性。公司开始引入先进的质量管理体系,对产品的研发、生产、销售等各个环节进行严格把控。通过持续改进和优化流程,CML成功提升了产品的品质和可靠性,赢得了客户的广泛认可。同时,公司还建立了完善的售后服务体系,为客户提供及时、专业的技术支持和服务,进一步提升了客户满意度。
在电子行业的激烈竞争中,Crosspoint Solutions公司凭借一项革命性的技术创新脱颖而出。公司研发出一款高度集成的交叉点开关芯片,该芯片在数据传输速度和稳定性上均达到了行业领先水平。这一创新迅速吸引了各大电子设备制造商的注意,公司因此获得了大量订单,市场份额迅速扩大。
在技术创新的基础上,Bytes公司积极拓展市场。公司通过精准的市场定位和营销策略,成功打开了多个国家和地区的市场。同时,Bytes公司注重品牌建设,通过优质的产品和服务赢得了消费者的信任和好评。公司还积极参与国际展览和交流活动,提升品牌知名度和影响力。
作为一家有社会责任感的企业,柯爱亚积极参与各种公益活动。公司不仅捐款捐物支持灾区重建、教育事业等公益事业,还组织员工参与志愿者活动,为社会做出了积极贡献。这些行为展现了柯爱亚作为一家优秀企业的社会担当和良好形象。
请注意,以上故事框架仅供参考,具体内容需要根据柯爱亚公司的实际发展历程进行编写。
自上世纪80年代起,丹纳赫集团通过一系列的战略并购,逐渐扩大其在电子行业的影响力。这些并购不仅为丹纳赫集团带来了先进的技术和产品,还增强了其在全球市场的竞争力。其中,对Leica显微系统公司的收购标志着丹纳赫集团正式涉足生命科学业务,为其在电子显微镜和生命科学仪器领域的发展奠定了基础。
经过AC→DC→AC变换的逆变电源称为变频电源,它有别于用于电机调速用的变频调速控制器,也有别于普通交流稳压电源。变频电源的主要功用是将现有交流电网电源变换成所需频率的稳定的纯净的正弦波电源。理想的交流电源的特点是频率稳定、电压稳定、内 ...… 查看全部问答∨ |
摘要:本文主要对无线数字城市视频监控提出综合的监控方案,方案中融合了卫星、4G、CDMA、智能手机终端、指挥中心等各项技术,是适应新形式下城市新发展的无线移动视频监控方案。 关键词:无线移动视频监控、卫星、4G、CDMA、智能手机终端、 ...… 查看全部问答∨ |
各位老师 我定制Wince6.0 Attache Device之后 出现黑屏 怎么办啊 并且出现了 下面这些Warning 是什么原因啊 我正在做一项国家大学生创新性实验项目 用Wince做 wince对我来说都是新的 急啊 老师们帮帮我吧 Pass 1... Warnin ...… 查看全部问答∨ |
|
自己编的一个linux驱动,我原来的工程目录是这样的:工程总目录下有一个include文件夹,所有的.c源文件,makefile文件,还有一个总的x.h头文件,x.h中include了include文件夹中所有的头文件和一些内核的头文件。include文件夹里有几个子文件夹,按 ...… 查看全部问答∨ |
|
TE2410型ARM9开发板是由慧通科技自主研发的一款嵌入式开发平台,基于三星公司的ARM处理器S3C2410A,开发板走线经过精心优化,性能稳定可靠,具有高性能、低功耗、接口丰富、体积小、集成度高和可配置性强等优良特性,可以满足客户 ...… 查看全部问答∨ |
|
STM8的D5、D6口上电时初始化为UART,运行当中想切换成通用GPIO,怎么切换,用GPIO_Init重新初始化无效,找了一下资料没有头绪,请高手指点。… 查看全部问答∨ |