社区导航

 
查看: 2570|回复: 2

[原创] 心仪M7--STM32F769I-DISCO评测-SAI(四)

[复制链接]

123

TA的帖子

2

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2017-1-4 22:59:18 | 显示全部楼层 |阅读模式
本帖最后由 okwh 于 2017-1-5 13:48 编辑

本篇是此系列的最后一篇,重点是SAI(Serial audio interface).

前奏介绍
     众所周知,声频、视频是人机界面的核心部分,有了它们,计算机的人性化、亲和感才会大大提升。从某个角度看,视频数据的处理表达已经变得容易多了,而声频数据表达要求的时间精确均匀的数据流,总是让人甚感棘手。嵌入处理器支持使用DAM的SAI接口使得声频在嵌入系统的CPU占用大大降低。
简单地看,SAI就像是连两个更全面的I2S总线构成(顺便说一句,各种串行通讯方式已经成为学习掌握嵌入系统的基本功夫,先学习SPI可以建立一个很好的基础)。对于声频数据传输,满足声频信息中包含的各种取样频率的要求,就是声频数据传输和普通SPI的一个重要不同点。通常SAI用于在播放解码和录音编码芯片之间建立通讯接口。
如图是 STM32F7的SAI功能图:
  
40.png
  


下图是STM32F7的I2S功能块图:

  
41.png
  


可以看出STM32F7SAI有两个独立可配置的通道,带有FIFO、帧同步异步、时钟发生、主从模式、声频格式、DMA和中断等全面支持。每个通道主要有四信号线:数据、时钟、帧同步、主模式时钟(用于和外部编码解码芯片的时序协调,STM32F769-DISCO使用的声频处理芯片是WM8994)

代码例子:
这里我们通过例子BSP例程(STM32F7xx_DFP\2.8.0\Projects\STM32F769I-Discovery\Examples\BSP)的一部分Audio-Player来说明SAI的工作方式。例子代码见附件,解压到STM32F7xx_DFP\2.8.0\Projects\STM32F769I-Discovery\Example下使用

主程序:
  1. int main(void)
  2. {
  3.   uint8_t  lcd_status = LCD_OK;
  4.   MPU_Config();
  5.   CPU_CACHE_Enable();
  6.   HAL_Init();
  7.   SystemClock_Config();
  8. BSP_LED_Init(LED_GREEN);
  9.   BSP_LED_Init(LED_RED);
  10.   BSP_PB_Init(BUTTON_WAKEUP, BUTTON_MODE_GPIO);
  11.   lcd_status = BSP_LCD_Init();
  12.   while(lcd_status != LCD_OK);
  13.   BSP_LCD_LayerDefaultInit(0, LCD_FB_START_ADDRESS);
  14.   BSP_LCD_Clear(LCD_COLOR_WHITE);
  15. //以上所有例程序几乎一样,无需解释。详细学习,直接研究STM32F7xx_DFP\2.8.0\Projects\STM32F769I-Discovery\Examples\BSP

  16.    while (1)
  17.     AudioPlay_demo();  // 我们这里只分析这个例子。
  18. }
复制代码

AudioPlay_Demo()第一部分,初始化:主要是LCD界面!!
  1. void AudioPlay_demo (void)
  2. {
  3.   uint32_t *AudioFreq_ptr;
  4.   AudioFreq_ptr = AudioFreq+6; /*AF_48K*/
  5.   uint8_t frequency_str[256] = {0};
  6.   uint8_t volume_str[256] = {0};  
  7.   uint8_t ts_status = TS_OK;
  8.   Point Points2[] = {{100, 140}, {160, 180}, {100, 220}};
  9.   uwVolume = 40;
  10.   Audio_SetHint();
  11.   BSP_LCD_SetFont(&Font20);
  12.   ts_status = BSP_TS_Init(BSP_LCD_GetXSize(), BSP_LCD_GetYSize());
  13.   if (ts_status != TS_OK)
  14.   {
  15.     BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
  16.     BSP_LCD_SetTextColor(LCD_COLOR_RED);
  17.     BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 95, (uint8_t *)"ERROR", CENTER_MODE);
  18.     BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 80, (uint8_t *)"Touch Screen cannot be initialized", CENTER_MODE);
  19.   }
  20.   /*<b><font color="#0000ff"> SAI初始化</font></b>*/
  21.   if(<b><font color="#0000ff">BSP_AUDIO_OUT_Init</font></b>(OUTPUT_DEVICE_BOTH, uwVolume, *AudioFreq_ptr) == 0)
  22.   {
  23.     BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
  24.     BSP_LCD_SetTextColor(LCD_COLOR_GREEN);
  25.     BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 95, (uint8_t *)"  AUDIO CODEC   OK  ", CENTER_MODE);
  26.   }
  27.   else
  28.   {
  29.     BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
  30.     BSP_LCD_SetTextColor(LCD_COLOR_RED);
  31.     BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 95, (uint8_t *)"  AUDIO CODEC  FAIL ", CENTER_MODE);
  32.     BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 80, (uint8_t *)" Try to reset board ", CENTER_MODE);
  33.   }
复制代码
  1. /* Play audio on slots 0 and 2 */


  2. BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);

  3. AUDIO_Start((uint32_t *)AUDIO_SRC_FILE_ADDRESS, (uint32_t)AUDIO_FILE_SIZE);



  4. //开始播放,播放的声频文件audio_sample_tdm.bin\Binary目录,事先用ST-Link utility写入flash地址0x08080000
  5. /* Display the state on the screen */
  6. BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
  7. BSP_LCD_SetTextColor(LCD_COLOR_BLUE);
  8. BSP_LCD_DisplayStringAt(0, LINE(8), (uint8_t *)" PLAYING... changed by okwh at eeworld ", CENTER_MODE);
  9. sprintf((char*)volume_str, " VOL: %3ld ", uwVolume);
  10. BSP_LCD_DisplayStringAt(0, LINE(9), (uint8_t *)volume_str, CENTER_MODE);
  11. sprintf((char*)frequency_str, " FREQ: %6ld ", *AudioFreq_ptr);
  12. BSP_LCD_DisplayStringAt(0, LINE(10), (uint8_t *)frequency_str, CENTER_MODE);
  13. BSP_LCD_SetFont(&Font16);
  14. BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 40, (uint8_t *)"Write audio_sample_tdm.bin' in Binary to @0x08080000 of flash using ST-Link utility", CENTER_MODE);
  15. if(ts_status == TS_OK)
  16. {
  17. /* Set touchscreen in Interrupt mode and program EXTI accordingly on falling edge of TS_INT pin */
  18. ts_status = BSP_TS_ITConfig();
  19. BSP_TEST_APPLI_ASSERT(ts_status != TS_OK);
  20. Touchscreen_DrawBackground_Circles(16);
  21. }
  22. BSP_LCD_SetFont(&Font20);
  23. /* Audio is playing */
  24. BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
  25. BSP_LCD_FillPolygon(Points2, 3);
  26. BSP_LCD_SetTextColor(LCD_COLOR_BLACK);
  27. BSP_LCD_FillRect(100, 140, 25 , 80);
  28. BSP_LCD_FillRect(140, 140, 25 , 80);
  29. while (1)
  30.   {
  31. ...........略,主要是处理user按键,实现播放速度、音量控制
复制代码




此例使用BSP_AUDIO_OUT_Init初始化SAI,  AUDIO_Start先读取复制缓冲区大小的数据到整个环形缓冲区,并用BSP_AUDIO_OUT_Play设置DMA从缓冲区传送数据到SAI开始播放,播放中将使用BSP_AUDIO_OUT_xxxTransfer_CallBack更新赋值缓冲区半满全空标志。

系统时钟中断SysTick_Handler用 AUDIO_Process判断缓冲区标志,用GetData读取在flash的声频数据到缓冲区,
使用环形缓冲区(AUDIO_BufferTypeDef buffer_ctl)逐步从flash取得后续声频数据填充缓冲区,如此保证播放,


视频: 触摸控制播放的音量和频率
熙熙攘攘的世界,我们不懈前行......


回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2017-1-6 16:02:53 | 显示全部楼层
性能很不错!   没有什么意义,价格高的离谱。谁家回去用呀!  国产MCU也是不错的性能。


回复

使用道具 举报

123

TA的帖子

2

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2017-1-6 17:53:20 | 显示全部楼层
本帖最后由 okwh 于 2017-1-6 18:02 编辑

嵌入、应用、桌面,正在走向连接和融合,已经不象原来那么泾渭分明。
想当年(区区30多年前),一台8086的PC就超过10万了(那时的10万,可不是现在的虚胀钱),现在呢?
当年一部大哥大也数万,现在呢?当年,一部电视机重达30公斤,价格数万万,现在呢?
这不过一代人的时间啊。
这世界变化很快的,已经快过人的成长更替了

熙熙攘攘的世界,我们不懈前行......


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

小黑屋|手机版|Archiver|电子工程世界 ( 京ICP证 060456

GMT+8, 2018-9-23 06:16 , Processed in 0.116457 second(s), 18 queries , Gzip On, Redis On.

快速回复 返回顶部 返回列表