如何编写程序来录制声音并将其写入SD卡?

时间:2017-09-25 12:17:26

标签: c eclipse multithreading stm32 fatfs

我正在使用STM32L476G_EVAL板和Eclipse(C语言)。我需要编写一个程序,它可以录制声音并将获得的声音样本写入SD卡。我有两个独立的代码,一个用于记录和再现使用DFSDM HAL API的声音,另一个用于在RTOS模式下将矢量写入SD卡。我用两个线程制作了一个新的源代码,一个用于录制声音,另一个用于写入SD卡。问题在于,由于某种原因,线程不起作用,它在对SD卡的第一次写入过程后停止。我猜测它与fatfs和线程有关,因为我尝试使用fatfs和更简单的功能(LED切换)进行多线程处理,但它也无法正常工作。可能我错过了某种信息,因为我在这个领域很新。任何形式的帮助都非常感谢。

#define SDMMC1              ((SDMMC_TypeDef *) SDMMC1_BASE)

#include "main.h"
#include "main1.h"
#include "main2.h"
#include "cmsis_os.h"
#include "ff.h"
#include "pthread.h"

/** @addtogroup STM32L4xx_HAL_Examples
  * @{
  */

/** @addtogroup DFSDM_AudioRecord
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
#define SaturaLH(N, L, H) (((N)<(L))?(L):(((N)>(H))?(H):(N)))
#define SizeBuff 2048 //macro variable for the size of the buffers
/* Private variables ---------------------------------------------------------*/
DFSDM_Channel_HandleTypeDef  DfsdmLeftChannelHandle;
DFSDM_Channel_HandleTypeDef  DfsdmRightChannelHandle;
DFSDM_Filter_HandleTypeDef   DfsdmLeftFilterHandle;
DFSDM_Filter_HandleTypeDef   DfsdmRightFilterHandle;
DMA_HandleTypeDef            hLeftDma;
DMA_HandleTypeDef            hRightDma;
SAI_HandleTypeDef            SaiHandle;
DMA_HandleTypeDef            hSaiDma;

FATFS SDFatFs;  /* File system object for SD card logical drive */
FIL MyFile;     /* File object */
char SDPath[4]; /* SD card logical drive path */

AUDIO_DrvTypeDef            *audio_drv;
int32_t                      LeftRecBuff[2048];
int32_t                      RightRecBuff[2048];
int16_t                      PlayBuff[4096];
uint32_t                     DmaLeftRecHalfBuffCplt  = 0;
uint32_t                     DmaLeftRecBuffCplt      = 0;
uint32_t                     DmaRightRecHalfBuffCplt = 0;
uint32_t                     DmaRightRecBuffCplt     = 0;
uint32_t                     PlaybackStarted         = 0;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void DFSDM_Init(void);
static void Playback_Init(void);
static void SD_Thread(void const *argument);
static void Audio_Thread(void const *argument);

osThreadId AudioThreadHandle, SDThreadHandle;

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  /* STM32L4xx HAL library initialization:
       - Configure the Flash prefetch
       - Systick timer is configured by default as source of time base, but user 
         can eventually implement his proper time base source (a general purpose 
         timer for example or other time source), keeping in mind that Time base 
         duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and 
         handled in milliseconds basis.
       - Set NVIC Group Priority to 4
       - Low Level Initialization
     */
  HAL_Init();

  /* Configure the system clock to have a frequency of 80 MHz */
  SystemClock_Config();

  /* Configure LED1 */
  BSP_LED_Init(LED1);
  BSP_LED_Init(LED3);
  /* Initialize DFSDM channels and filter for record */
  DFSDM_Init();

  /* Initialize playback */
  Playback_Init();

  /* Start DFSDM conversions */
  if(HAL_OK != HAL_DFSDM_FilterRegularStart_DMA(&DfsdmRightFilterHandle, RightRecBuff, SizeBuff))
  {
    Error_Handler();
  }
  if(HAL_OK != HAL_DFSDM_FilterRegularStart_DMA(&DfsdmLeftFilterHandle, LeftRecBuff, SizeBuff))
  {
    Error_Handler();
  }

  osThreadDef(Audio1, Audio_Thread, osPriorityHigh, 0, configMINIMAL_STACK_SIZE);

   /* Thread 2 definition */
   osThreadDef(SD1, SD_Thread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE);

   /* Start thread 1 */
   AudioThreadHandle = osThreadCreate(osThread(Audio1), NULL);

   /* Start thread 2 */
   SDThreadHandle = osThreadCreate(osThread(SD1), NULL);

   /* Start scheduler */
   osKernelStart();
   for(;;);


}

static void SD_Thread(void const *argument)
{

  uint32_t i, byteswritten;                     // File write/read counts /

  BSP_LED_On(LED3);
  //##-1- Link the micro SD disk I/O driver ##################################/
  if(FATFS_LinkDriver(&SD_Driver, SDPath) == 0)
  {
    //##-2- Register the file system object to the FatFs module ##############/
    if(f_mount(&SDFatFs, (TCHAR const*)SDPath, 0) != FR_OK)
    {
      // FatFs Initialization Error
      Error_Handler();
    }
    else
    {
      //##-3- Create a FAT file system (format) on the logical drive #########/
      // WARNING: Formatting the uSD card will delete all content on the device /
      if(f_mkfs((TCHAR const*)SDPath, 0, 0) != FR_OK)
      {
        // FatFs Format Error /
        Error_Handler();
      }
      else
      {
        //##-4- Create and Open a new text file object with write access #####/
        if(f_open(&MyFile, "STM32.TXT", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
        {
          // 'STM32.TXT' file Open for write Error /
          Error_Handler();
        }
        else
        {
            BSP_LED_On(LED1);
          //##-5- Write data to the text file ################################/
            for(i=0; i<2*SizeBuff; i++ )
                f_printf(&MyFile,"%d ", PlayBuff[i]);
            f_close(&MyFile);
        }
      }
    }
  }
}


static void Audio_Thread(void const *argument)
{
    uint32_t i, count;
    BSP_LED_On(LED1);
    while(1)
      {
        if((DmaLeftRecHalfBuffCplt == 1) && (DmaRightRecHalfBuffCplt == 1))
        {
          /* Store values on Play buff */
          for(i = 0; i < SizeBuff/2; i++)
          {
            PlayBuff[2*i]     = SaturaLH((LeftRecBuff[i] >> 8), -32768, 32767);
            PlayBuff[(2*i)+1] = SaturaLH((RightRecBuff[i] >> 8), -32768, 32767);
          }
          if(PlaybackStarted == 0)
          {
            if(0 != audio_drv->Play(AUDIO_I2C_ADDRESS, (uint16_t *) &PlayBuff[0], 4096))
            {
              Error_Handler();
            }
            if(HAL_OK != HAL_SAI_Transmit_DMA(&SaiHandle, (uint8_t *) &PlayBuff[0], 4096))
            {
              Error_Handler();
            }
            PlaybackStarted = 1;
          }
          DmaLeftRecHalfBuffCplt  = 0;
          DmaRightRecHalfBuffCplt = 0;
        }
        if((DmaLeftRecBuffCplt == 1) && (DmaRightRecBuffCplt == 1))
        {
          /* Store values on Play buff */
          for(i = SizeBuff/2; i < SizeBuff; i++)
          {
            PlayBuff[2*i]     = SaturaLH((LeftRecBuff[i] >> 8), -32768, 32767);
            PlayBuff[(2*i)+1] = SaturaLH((RightRecBuff[i] >> 8), -32768, 32767);
          }
          DmaLeftRecBuffCplt  = 0;
          DmaRightRecBuffCplt = 0;  
          osThreadResume(SDThreadHandle);
          osThreadSuspend(NULL);
         }
        }
}

0 个答案:

没有答案