[STM32H5] 【NUCLEO-H563ZI测评】7.DAC输出测试+使用DAC播放音频

[复制链接]
 楼主| yuyy1989 发表于 2023-7-23 18:38 | 显示全部楼层 |阅读模式
<
#申请原创# @21小跑堂  
7.DAC输出测试+使用DAC播放音频
7.1使用DAC输出指定电压
DAC可以将数字量转换为模拟量,STM32H563有一个DAC控制器,12bit也可以设置为8bit,2个DAC转换通道,每个通道可独立转换。
先用DAC输出指定电压值,打开STM32CubeMX,找到DAC并使能,这里使用PA5作为DAC输出
QQ截图20230722215710.png
DAC初始化后需要手动开启DAC转换过程
QQ截图20230722215922.png
使用按键来切换1V 2V 3V的电压输出,代码示例

  1. uint8_t out_vol = 0;
  2. void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
  3. {
  4.     if(HAL_GPIO_ReadPin(USER_BUTTON_GPIO_Port,USER_BUTTON_Pin) == GPIO_PIN_SET)
  5.     {
  6.         HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_2,DAC_ALIGN_8B_R,out_vol*77.3);
  7.         out_vol+=1;
  8.         if(out_vol > 3)
  9.             out_vol = 0;
  10.     }
  11. }
运行效果,使用万用表测量电压
微信图片640_20230723170538.jpg 微信图片640_20230723170544.jpg 微信图片640_20230723170550.jpg
理论上也可以用DAC实现特定波形的输出,用按键切换波形,代码示例

  1. void proc_dac_wave()
  2. {
  3.     uint8_t changed = 0;
  4.     switch(wavetype)
  5.     {
  6.         case 0:
  7.             if(wavestep > 0)
  8.                 wavestep -= 1;
  9.             else
  10.             {
  11.                 if(dacvalue == 0)
  12.                     dacvalue = 255;
  13.                 else
  14.                     dacvalue = 0;
  15.                 changed = 1;
  16.                 wavestep = 9;
  17.             }
  18.             break;
  19.         case 1:
  20.             dacvalue+=1;
  21.             changed = 1;
  22.             break;
  23.         case 2:
  24.             if(wavestep > 0)
  25.                 wavestep -= 1;
  26.             else
  27.             {
  28.                 wavestep = 10;
  29.                 dacvalue+=15;
  30.                 changed = 1;
  31.             }
  32.             break;
  33.         case 3:
  34.             if(wavestep < 255)
  35.             {
  36.                 dacvalue=wavestep;
  37.                 changed = 1;
  38.             }
  39.             else if(wavestep > 300 && wavestep < 556)
  40.             {
  41.                 dacvalue= 555 - wavestep;
  42.                 changed = 1;
  43.             }
  44.             if(wavestep < 600)
  45.                 wavestep++;
  46.             else
  47.                 wavestep = 0;
  48.             break;
  49.         case 4:
  50.             if(wavestep < 90)
  51.             {
  52.                 dacvalue = sinvalues[wavestep];
  53.                 changed = 1;
  54.             }
  55.             else
  56.             {
  57.                 dacvalue = sinvalues[180 - wavestep];
  58.                 changed = 1;
  59.             }
  60.             if(wavestep < 179)
  61.                 wavestep++;
  62.             else
  63.                 wavestep = 0;
  64.             break;
  65.         case 5:
  66.             if(wavestep < 90)
  67.             {
  68.                 dacvalue = 127 + (sinvalues[wavestep]/2);
  69.                 changed = 1;
  70.             }
  71.             else
  72.             {
  73.                 dacvalue = 128 - (sinvalues[180 - wavestep]/2);
  74.                 changed = 1;
  75.             }
  76.             if(wavestep < 179)
  77.                 wavestep++;
  78.             else
  79.                 wavestep = 0;
  80.             break;
  81.         case 6:
  82.             if(wavestep < 90)
  83.             {
  84.                 dacvalue = 127 + (sinvalues[wavestep]/2);
  85.                 changed = 1;
  86.             }
  87.             else if(wavestep < 180)
  88.             {
  89.                 dacvalue = 127 + (sinvalues[180 - wavestep]/2);
  90.                 changed = 1;
  91.             }
  92.             else if(wavestep < 270)
  93.             {
  94.                 dacvalue = 128 - (sinvalues[wavestep - 180]/2);
  95.                 changed = 1;
  96.             }
  97.             else
  98.             {
  99.                 dacvalue = 128 - (sinvalues[360 - wavestep]/2);
  100.                 changed = 1;
  101.             }
  102.             if(wavestep < 359)
  103.                 wavestep++;
  104.             else
  105.                 wavestep = 0;
  106.             break;
  107.         default:
  108.             break;
  109.     }
  110.     if(changed > 0)
  111.         HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_2,DAC_ALIGN_8B_R,dacvalue);
  112. }

  113. void usercode_loop(void)
  114. {
  115.     yuyy_delay_ms(1);
  116.     proc_dac_wave();
  117. }

  118. void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
  119. {
  120.     if(HAL_GPIO_ReadPin(USER_BUTTON_GPIO_Port,USER_BUTTON_Pin) == GPIO_PIN_SET)
  121.     {
  122.         if(wavetype < 6)
  123.             wavetype += 1;
  124.         else
  125.             wavetype = 0;
  126.         wavestep = 0;
  127.     }
  128. }
运行效果,波形展示
QQ截图20230723180050.png QQ截图20230723180108.png QQ截图20230723180133.png QQ截图20230723180210.png QQ截图20230723180227.png QQ截图20230723180242.png QQ截图20230723180254.png
7.2使用DAC播放音频
耳机音箱的喇叭最终也是模拟量输出,因此可以使用DAC来实现播放音频,接下来尝试一下。
用Adobe Audition打开你想播放的音频
QQ截图20230722213905.png
将它转换为WAV模式,这个格式下文件内存储的就是数字电平信息,为了减少空间占用,这里按如下参数导出
QQ截图20230722210838.png
用winhex打开转换后的WAV文件,复制中间的一段内容,用这个选项可以直接以数组的形式复制,把复制的数组粘贴到代码中
QQ截图20230722214158.png
打开打开STM32CubeMX,修改定时器频率,让它和导出的音频文件的采样率一致
QQ截图20230722215417.png
播放控制代码
  1. #define AUDIO_DATA_LEN 126960
  2. uint8_t play = 0;
  3. uint32_t wavestep = 0;
  4. const uint8_t audio_data[AUDIO_DATA_LEN];
  5. void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
  6. {
  7.     if(HAL_GPIO_ReadPin(USER_BUTTON_GPIO_Port,USER_BUTTON_Pin) == GPIO_PIN_SET)
  8.     {
  9.         play = 1 - play;
  10.     }
  11. }
  12. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  13. {
  14.     if(play)
  15.     {
  16.         HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_2,DAC_ALIGN_8B_R,audio_data[wavestep]);
  17.         wavestep += 1;
  18.         if(wavestep >= AUDIO_DATA_LEN)
  19.             wavestep = 0;
  20.     }
  21. }


运行效果,接了个音箱作为声音输出

虽然音质不太好,但也成功用DAC播放了音频,开发板上还有USB和网口,可以尝试结合USB做个USB声卡,或者通过USB读取U盘中的WAV文件进行播放,或者利用以太网口通过网络播放,或者也可以用ADC连接MIC实现录音再用DAC播放,这里就先不尝试了,有兴趣的朋友可以去尝试一下


t1ngus4 发表于 2024-1-12 16:48 | 显示全部楼层
DAC这块用的比较少,但是我觉得DAC确实做音频方面效果很不错
ex7s4 发表于 2024-1-12 17:50 | 显示全部楼层
不知道这H563的DAC是多少位的?
zhizia4f 发表于 2024-1-12 18:52 | 显示全部楼层
输出的波形很稳啊,我觉得可以用个这芯片做个简单的DDS了
q1ngt12 发表于 2024-1-12 20:55 | 显示全部楼层
话说输出波形的话,最高可以达到多少的频率?
p0gon9y 发表于 2024-1-12 22:25 | 显示全部楼层
话说输出波形的话,最高可以达到多少的频率?
lix1yr 发表于 2024-1-13 08:12 | 显示全部楼层
很不错啊,这个播放音乐这块我很喜欢
lamanius 发表于 2024-1-13 08:32 | 显示全部楼层
音质不好的话,怎么做会能优化音质啊?
q1d0mnx 发表于 2024-1-13 09:22 | 显示全部楼层
其实你应该把WAV的采样频率设置更好一些就好了吧
suw12q 发表于 2024-1-13 10:45 | 显示全部楼层
这芯片的DAC是不是配合DMA使用就会好一些了
kaif2n9j 发表于 2024-1-13 11:38 | 显示全部楼层
楼主能分享一下这个工程么,很想学一学DAC这块的知识
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:同飞软件研发工程师
简介:制冷系统单片机软件开发,使用PID控制温度

161

主题

815

帖子

10

粉丝
快速回复 在线客服 返回列表 返回顶部
认证:同飞软件研发工程师
简介:制冷系统单片机软件开发,使用PID控制温度

161

主题

815

帖子

10

粉丝
快速回复 在线客服 返回列表 返回顶部