打印
[STM32H5]

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

[复制链接]
544|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
#申请原创# @21小跑堂  
7.DAC输出测试+使用DAC播放音频
7.1使用DAC输出指定电压
DAC可以将数字量转换为模拟量,STM32H563有一个DAC控制器,12bit也可以设置为8bit,2个DAC转换通道,每个通道可独立转换。
先用DAC输出指定电压值,打开STM32CubeMX,找到DAC并使能,这里使用PA5作为DAC输出

DAC初始化后需要手动开启DAC转换过程

使用按键来切换1V 2V 3V的电压输出,代码示例

uint8_t out_vol = 0;
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
    if(HAL_GPIO_ReadPin(USER_BUTTON_GPIO_Port,USER_BUTTON_Pin) == GPIO_PIN_SET)
    {
        HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_2,DAC_ALIGN_8B_R,out_vol*77.3);
        out_vol+=1;
        if(out_vol > 3)
            out_vol = 0;
    }
}
运行效果,使用万用表测量电压

理论上也可以用DAC实现特定波形的输出,用按键切换波形,代码示例

void proc_dac_wave()
{
    uint8_t changed = 0;
    switch(wavetype)
    {
        case 0:
            if(wavestep > 0)
                wavestep -= 1;
            else
            {
                if(dacvalue == 0)
                    dacvalue = 255;
                else
                    dacvalue = 0;
                changed = 1;
                wavestep = 9;
            }
            break;
        case 1:
            dacvalue+=1;
            changed = 1;
            break;
        case 2:
            if(wavestep > 0)
                wavestep -= 1;
            else
            {
                wavestep = 10;
                dacvalue+=15;
                changed = 1;
            }
            break;
        case 3:
            if(wavestep < 255)
            {
                dacvalue=wavestep;
                changed = 1;
            }
            else if(wavestep > 300 && wavestep < 556)
            {
                dacvalue= 555 - wavestep;
                changed = 1;
            }
            if(wavestep < 600)
                wavestep++;
            else
                wavestep = 0;
            break;
        case 4:
            if(wavestep < 90)
            {
                dacvalue = sinvalues[wavestep];
                changed = 1;
            }
            else
            {
                dacvalue = sinvalues[180 - wavestep];
                changed = 1;
            }
            if(wavestep < 179)
                wavestep++;
            else
                wavestep = 0;
            break;
        case 5:
            if(wavestep < 90)
            {
                dacvalue = 127 + (sinvalues[wavestep]/2);
                changed = 1;
            }
            else
            {
                dacvalue = 128 - (sinvalues[180 - wavestep]/2);
                changed = 1;
            }
            if(wavestep < 179)
                wavestep++;
            else
                wavestep = 0;
            break;
        case 6:
            if(wavestep < 90)
            {
                dacvalue = 127 + (sinvalues[wavestep]/2);
                changed = 1;
            }
            else if(wavestep < 180)
            {
                dacvalue = 127 + (sinvalues[180 - wavestep]/2);
                changed = 1;
            }
            else if(wavestep < 270)
            {
                dacvalue = 128 - (sinvalues[wavestep - 180]/2);
                changed = 1;
            }
            else
            {
                dacvalue = 128 - (sinvalues[360 - wavestep]/2);
                changed = 1;
            }
            if(wavestep < 359)
                wavestep++;
            else
                wavestep = 0;
            break;
        default:
            break;
    }
    if(changed > 0)
        HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_2,DAC_ALIGN_8B_R,dacvalue);
}

void usercode_loop(void)
{
    yuyy_delay_ms(1);
    proc_dac_wave();
}

void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
    if(HAL_GPIO_ReadPin(USER_BUTTON_GPIO_Port,USER_BUTTON_Pin) == GPIO_PIN_SET)
    {
        if(wavetype < 6)
            wavetype += 1;
        else
            wavetype = 0;
        wavestep = 0;
    }
}
运行效果,波形展示

7.2使用DAC播放音频
耳机音箱的喇叭最终也是模拟量输出,因此可以使用DAC来实现播放音频,接下来尝试一下。
用Adobe Audition打开你想播放的音频

将它转换为WAV模式,这个格式下文件内存储的就是数字电平信息,为了减少空间占用,这里按如下参数导出

用winhex打开转换后的WAV文件,复制中间的一段内容,用这个选项可以直接以数组的形式复制,把复制的数组粘贴到代码中

打开打开STM32CubeMX,修改定时器频率,让它和导出的音频文件的采样率一致

播放控制代码
#define AUDIO_DATA_LEN 126960 
uint8_t play = 0;
uint32_t wavestep = 0;
const uint8_t audio_data[AUDIO_DATA_LEN];
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
    if(HAL_GPIO_ReadPin(USER_BUTTON_GPIO_Port,USER_BUTTON_Pin) == GPIO_PIN_SET)
    {
        play = 1 - play;
    }
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(play)
    {
        HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_2,DAC_ALIGN_8B_R,audio_data[wavestep]);
        wavestep += 1;
        if(wavestep >= AUDIO_DATA_LEN)
            wavestep = 0;
    }
}


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

虽然音质不太好,但也成功用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了

使用特权

评论回复
5
q1ngt12| | 2024-1-12 20:55 | 只看该作者
话说输出波形的话,最高可以达到多少的频率?

使用特权

评论回复
6
p0gon9y| | 2024-1-12 22:25 | 只看该作者
话说输出波形的话,最高可以达到多少的频率?

使用特权

评论回复
7
lix1yr| | 2024-1-13 08:12 | 只看该作者
很不错啊,这个播放音乐这块我很喜欢

使用特权

评论回复
8
lamanius| | 2024-1-13 08:32 | 只看该作者
音质不好的话,怎么做会能优化音质啊?

使用特权

评论回复
9
q1d0mnx| | 2024-1-13 09:22 | 只看该作者
其实你应该把WAV的采样频率设置更好一些就好了吧

使用特权

评论回复
10
suw12q| | 2024-1-13 10:45 | 只看该作者
这芯片的DAC是不是配合DMA使用就会好一些了

使用特权

评论回复
11
kaif2n9j| | 2024-1-13 11:38 | 只看该作者
楼主能分享一下这个工程么,很想学一学DAC这块的知识

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

146

主题

698

帖子

6

粉丝