#申请原创# @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播放,这里就先不尝试了,有兴趣的朋友可以去尝试一下
|