C 未使用STM32F469I发现执行音频传输回调

C 未使用STM32F469I发现执行音频传输回调,c,eclipse,arm,stm32f4discovery,stm32f4,C,Eclipse,Arm,Stm32f4discovery,Stm32f4,我是嵌入式编程新手,目前正在与STM32F469I发现板合作一个项目。我将eclipse与ARM工具链和提供的驱动程序一起使用。我一直在播放一个二进制音频文件,该文件在芯片中的特定地址闪现。我已经非常简单地将我的代码基于一些示例文件,尽管由于我只是想让它工作,所以我的代码已经大大减少了 目前,代码一直工作到它播放缓冲区的位置,但随后它似乎被卡住了。缓冲区正在循环播放(我已经更改了缓冲区的大小以确认这一点),您可以听到它,但仅此而已。传输中断回调永远不会执行,因此缓冲区不会重新填充,也永远不会播放

我是嵌入式编程新手,目前正在与STM32F469I发现板合作一个项目。我将eclipse与ARM工具链和提供的驱动程序一起使用。我一直在播放一个二进制音频文件,该文件在芯片中的特定地址闪现。我已经非常简单地将我的代码基于一些示例文件,尽管由于我只是想让它工作,所以我的代码已经大大减少了

目前,代码一直工作到它播放缓冲区的位置,但随后它似乎被卡住了。缓冲区正在循环播放(我已经更改了缓冲区的大小以确认这一点),您可以听到它,但仅此而已。传输中断回调永远不会执行,因此缓冲区不会重新填充,也永远不会播放完整的样本

我曾尝试使用外部中断来重新填充缓冲区,但当我尝试此操作时,它会卡住。我也试着通过打开LED来调试它,但这已经证实了它在播放示例后很快就会卡住。无限while循环从不执行,传输中断也从不执行

我的问题是-为什么它被卡住了,为什么中断没有被触发

任何帮助都将不胜感激

#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的用途。