C 未使用STM32F469I发现执行音频传输回调
我是嵌入式编程新手,目前正在与STM32F469I发现板合作一个项目。我将eclipse与ARM工具链和提供的驱动程序一起使用。我一直在播放一个二进制音频文件,该文件在芯片中的特定地址闪现。我已经非常简单地将我的代码基于一些示例文件,尽管由于我只是想让它工作,所以我的代码已经大大减少了 目前,代码一直工作到它播放缓冲区的位置,但随后它似乎被卡住了。缓冲区正在循环播放(我已经更改了缓冲区的大小以确认这一点),您可以听到它,但仅此而已。传输中断回调永远不会执行,因此缓冲区不会重新填充,也永远不会播放完整的样本 我曾尝试使用外部中断来重新填充缓冲区,但当我尝试此操作时,它会卡住。我也试着通过打开LED来调试它,但这已经证实了它在播放示例后很快就会卡住。无限while循环从不执行,传输中断也从不执行 我的问题是-为什么它被卡住了,为什么中断没有被触发 任何帮助都将不胜感激C 未使用STM32F469I发现执行音频传输回调,c,eclipse,arm,stm32f4discovery,stm32f4,C,Eclipse,Arm,Stm32f4discovery,Stm32f4,我是嵌入式编程新手,目前正在与STM32F469I发现板合作一个项目。我将eclipse与ARM工具链和提供的驱动程序一起使用。我一直在播放一个二进制音频文件,该文件在芯片中的特定地址闪现。我已经非常简单地将我的代码基于一些示例文件,尽管由于我只是想让它工作,所以我的代码已经大大减少了 目前,代码一直工作到它播放缓冲区的位置,但随后它似乎被卡住了。缓冲区正在循环播放(我已经更改了缓冲区的大小以确认这一点),您可以听到它,但仅此而已。传输中断回调永远不会执行,因此缓冲区不会重新填充,也永远不会播放
#include "main.h"
static void SystemClock_Config(void);
#define AUDIO_FILE_ADDRESS 0x08010000
#define AUDIO_FILE_SIZE (180*1024)
#define PLAY_HEADER 0x2C
#define PBSIZE 4096
uint16_t PlayBuff[PBSIZE];
int OFFSET = 0;
int TransferState = 0;
int CycleCount1 = 1;
int CycleCount2 = 1;
int main(void)
{
uint32_t PlaybackPosition = PBSIZE + PLAY_HEADER;
HAL_Init();
/* Configure the system clock to 180 MHz */
SystemClock_Config();
// Fill the buffer first time round
for(int i=0; i <= PBSIZE; i++)
{
PlayBuff[i]=*((__IO uint16_t *)(AUDIO_FILE_ADDRESS + PLAY_HEADER + i));
}
BSP_AUDIO_OUT_Init(2,50,AUDIO_FREQUENCY_16K );
BSP_AUDIO_OUT_Play(PlayBuff,PBSIZE);
while(1){
if(TransferState==1){
// refill the first part of the buffer
TransferState=0;
OFFSET = CycleCount1*PBSIZE;
for(int i=0; i <= PBSIZE/2; i++){
PlayBuff[i]=*((__IO uint16_t *)(AUDIO_FILE_ADDRESS + PLAY_HEADER + OFFSET));
}
CycleCount1++;
}
if(TransferState==2){
// refill the second part of the buffer
OFFSET = CycleCount2*PBSIZE+PBSIZE;
TransferState=0;
for(int i=PBSIZE/2; i <= PBSIZE; i++){
PlayBuff[i]=*((__IO uint16_t *)(AUDIO_FILE_ADDRESS + PLAY_HEADER + OFFSET));
}
CycleCount2++;
}
}
}
void BSP_AUDIO_OUT_TransferComplete_CallBack(void)
{
TransferState=2;
}
void BSP_AUDIO_OUT_HalfTransfer_CallBack(void){
TransferState=1;
}
#包括“main.h”
静态无效系统时钟配置(无效);
#定义音频文件地址0x08010000
#定义音频文件大小(180*1024)
#定义播放头0x2C
#定义PBSIZE 4096
uint16_t PlayBuff[PBSIZE];
整数偏移=0;
int TransferState=0;
int CycleCount1=1;
int CycleCount2=1;
内部主(空)
{
uint32\u t回放位置=PBSIZE+播放标题;
HAL_Init();
/*将系统时钟配置为180 MHz*/
SystemClock_Config();
//第一次填充缓冲区
对于(int i=0;i我不熟悉特定的电路板,从我所看到的情况来看,您可能需要将TransferState定义为volatile
volatile int TransferState=0;
这在嵌入式和多线程开发中非常常见。编译器可以优化寄存器中的变量TransferState,这样它就不会从不同的上下文(回调)中实际看到更新。Volatile阻止它这样做。我发现了问题。我没有在stm32f4xx_It.c中设置DMA中断
void DMA2_Stream3_IRQHandler(void)
{
HAL_DMA_IRQHandler(haudio_out_sai.hdmatx);
}
我还发现,当使用BSP\u AUDIO\u OUT\u Play()
时,声音是错误的,下面有一些低沉的声音
使用以下方法可以正确地工作
#include "main.h"
static void SystemClock_Config(void);
#define AUDIO_FILE_ADDRESS 0x08010000
#define PLAY_HEADER 0x17569
#define PBSIZE 4096
uint16_t PlayBuff[PBSIZE];
int main(void)
{
BSP_LED_Init(LED1);
HAL_Init();
/* Configure the system clock to 180 MHz */
SystemClock_Config();
// Fill the buffer first time round
for(int i=0; i <= PBSIZE; i++)
{
PlayBuff[i]=*((__IO uint16_t *)(AUDIO_FILE_ADDRESS + PLAY_HEADER + i));
}
BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE ,50,AUDIO_FREQUENCY_44K );
BSP_LED_On(LED1);
BSP_AUDIO_OUT_Play(PlayBuff,PBSIZE);
HAL_Delay(1000);
BSP_LED_Off(LED1);
}
/* Start the playback */
if(0 != audio_drv->Play(AUDIO_I2C_ADDRESS, NULL, 0))
{
Error_Handler();
}
if(HAL_OK != HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t *) PlayBuff, PLAY_BUFF_SIZE))
{
Error_Handler();
}
代码看起来很模糊,需要维护。如果不是现在,在添加更多代码时,这些定义和强制转换都会带来麻烦。作为初学者,你不应该尝试运行,而应该先学会蹲着,然后再走路。你似乎在复制示例代码,但并不真正理解它。这会带来灾难。是的,这并不完全是错误的很清楚,是的,目前一切都有点混乱。我成功地使用了其他功能,如外部中断、ADC、systick定时器,使用了LCD上的STemWin GUI界面,但我正在努力解决这个问题。我对它的理解不是我乐意承认的最好的理解。我对它的理解是,你创建了一个缓冲区和f将音频bin文件的前4096加载到特定地址。然后播放它并进入无限循环。中断应该在播放缓冲区的中途触发,但不会。使用调试器进行调试!附带说明:摆脱STlib HAL垃圾。它只会使代码膨胀,增加完全不必要的复杂性没有好处,会降低代码速度。请改为直接编写访问硬件寄存器的驱动程序。volatile
这样的驱动程序不足以进行多线程通信。这就是atomics的用途。