我使用下面的代码来生成声音,在while循环中,我想要动态更改它,以便在声音生成过程中创建不同频率的声音。
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);?
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);}
发布于 2019-12-06 15:52:56
当你告诉控制器通过DMA传输数据时,它只会记录你的愿望(指令),并且在HAL_I2S_Transmit_DMA函数中不会传输任何东西。
当控制器(与代码执行并行)传输单个缓冲区时,您的循环将进行多次迭代。
因此,告诉控制器在传输新数据的同时传输新数据可能会产生副作用。
您需要注册中断处理程序,它将告诉您传输已完成。
然后,您需要再次注册您的后续“愿望”,以维持未中断的数据流。
通常,在控制器传输数据时更改缓冲区中的数据是没有意义的。通常我们使用两个缓冲区来传输实际数据:
中准备数据
中准备数据
您可以从中断处理程序设置全局标志并在循环中检查它(并从您的循环启动后续的tx ),或者使用消息队列将来自中断处理程序的消息传递到您的循环中。
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);
}https://stackoverflow.com/questions/59208702
复制相似问题