首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态DMA传输

动态DMA传输
EN

Stack Overflow用户
提问于 2019-12-06 15:27:15
回答 1查看 227关注 0票数 3

我使用下面的代码来生成声音,在while循环中,我想要动态更改它,以便在声音生成过程中创建不同频率的声音。

代码语言:javascript
复制
for(uint16_t i = 0; i < sample_N; i++)
{
    dataI2S[i*2] = i*5000; 
    dataI2S[i*2 + 1] =i*5000; 
} 

HAL_I2S_Transmit_DMA(&hi2s3, (uint16_t *)dataI2S, sample_N*2);

while (1)
{
    ps = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);
    HAL_I2S_Transmit_DMA(&hi2s3, (uint16_t *)dataI2S, sample_N*b);

    b++;
    if (b == 5)
        b = 1;

    if(ps){
        generate();
        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, ps);
    } else {
        stop();
        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, 0);   
    }
}

它只使用第一个sample_N*b值生成声音。它不会动态变化。

如何动态更改HAL_I2S_Transmit_DMA(&hi2s3, (uint16_t *)dataI2S, sample_N*b);

代码语言:javascript
复制
void DMA1_Stream5_IRQHandler(void) {
if(x % 2 == 1)
    HAL_I2S_Transmit_DMA(&hi2s3, (uint16_t *)dataI2S, sample_N*2);
else 
    HAL_I2S_Transmit_DMA(&hi2s3, (uint16_t *)dataI2S2, sample_N2*2);
    x++;
HAL_DMA_IRQHandler(&hdma_spi3_tx);

}

EN

回答 1

Stack Overflow用户

发布于 2019-12-06 15:52:56

当你告诉控制器通过DMA传输数据时,它只会记录你的愿望(指令),并且在HAL_I2S_Transmit_DMA函数中不会传输任何东西。

当控制器(与代码执行并行)传输单个缓冲区时,您的循环将进行多次迭代。

因此,告诉控制器在传输新数据的同时传输新数据可能会产生副作用。

您需要注册中断处理程序,它将告诉您传输已完成。

然后,您需要再次注册您的后续“愿望”,以维持未中断的数据流。

通常,在控制器传输数据时更改缓冲区中的数据是没有意义的。通常我们使用两个缓冲区来传输实际数据:

  • 在buffer1

中准备数据

  • 在buffer2中将transmission
  • prepare数据的数据移交给控制器而控制器从buffer1
  • 传输数据当中断告诉您buffer1传输完成时,您告诉控制器使用buffer2
  • 从bugger2传输数据您再次在buffer1

中准备数据

  • ,依此类推

您可以从中断处理程序设置全局标志并在循环中检查它(并从您的循环启动后续的tx ),或者使用消息队列将来自中断处理程序的消息传递到您的循环中。

代码语言:javascript
复制
static void MX_I2S3_Init(void) {
    ...some code
    hdma_spi3_tx.Instance = DMA1_Stream0;
    HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
}

void DMA1_Stream0_IRQHandler(void) {
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, 1);
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59208702

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档