笔记:
本想使用PWM输出音频的,但无论怎么样调试,PWM的音频的频率总不对。后来,改用DAC了。
配置:
芯片:STM32F103VET
DAC:DAC通道2(8位右对齐)、定时器TIM7中断更改DAC值
WAVE数据:以const形式放于芯片上(8kHz采样、8bit、单声道)
弯路:
(1)使用TIM7控制DAC输出,用TRIG方式,通过DMA2通道传送数据到DAC写寄存器 => 没有任何波形输出
(2)以为不需要使用与 DAC通道 一致的定时器作驱动,故使用了 TIM3 。使TIM3工作于8K的工作频率,并允许IT_UPDATE,在TIM3定时器中断中更改DAC的值,不使用DMA2通道 => 有波形信号输出,但频率太高,1秒的音频在约50ms内输出完毕
(3)不使用TIM3,使用与DAC通道2相应的TIM7。将TIM7配置为8K工作频率,允许IT_UPDATE,在TIM7定时器中断中更改DAC的值 ,可正常驱动DAC。估计弯路(2)是由于TIM7的工作频率没有配置,导致DAC频率不正常所致,但未证实
(4)使用步骤(3)的定时器,改用DMA传送数据 => DAC无法正常输出音频 【由于时间关系暂时先不解决这问题了】
例程:
void DACInit(void)
{
DAC_InitTypeDef DAC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// 1. 配置TIM7
TIM_DeInit(TIM7);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = GetARRValue(8000); // 重置周期
TIM_TimeBaseStructure.TIM_Prescaler = 0; // 分频
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分割
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down; // 计数模式
TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStructure);
// 使能TIM7更新中断
TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE);
// 2. 配置DAC
DAC_DeInit();
/* DAC channel1 Configuration */
DAC_InitStructure.DAC_Trigger = DAC_Trigger_None; //
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bits8_0;
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
// DA通道2初始化
DAC_Init(DAC_Channel_2, &DAC_InitStructure);
/* Enable DAC Channel1: Once the DAC channel1 is enabled, PA.04 is
automatically connected to the DAC converter. */
DAC_Cmd(DAC_Channel_2, ENABLE);
// 3. 启动TIM7
TIM_Cmd(TIM7, ENABLE);
}
void TIM7_IRQHandler(void)
{
INT16U tmpCap;
if (TIM_GetITStatus(TIM7, TIM_IT_Update) != RESET)
{
if( wavecount < wave0Length )
{
tmpCap = wave0[wavecount];
wavecount++;
/* Set DAC Channel1 DHR register */
DAC_SetChannel2Data(DAC_Align_8b_R,tmpCap);
}
else
{
// 完成传输,关闭中断
wavecount = 0;
TIM_ITConfig(TIM7, TIM_IT_Update, DISABLE);
TIM_Cmd(TIM7, DISABLE);
// 需要关闭DAC,不然在没有声音的时候会有杂音
DAC_Cmd(DAC_Channel_2, DISABLE);
}
}
/* Clear TIM6 update interrupt */
TIM_ClearITPendingBit(TIM7, TIM_IT_Update);
}
// 根据采样率获得定时器自动
// 摘自waveplayer.c
INT16U GetARRValue(INT16U sample)
{
INT16U arrValue;
/* 更新OCA值以符合.WAV文件采样率 */
switch (sample)
{
case SAMPLE_RATE_8000 :
arrValue = (uint16_t)(72000000/8000);
break; /* 8KHz = 2x36MHz / 9000 */
case SAMPLE_RATE_11025:
arrValue = (uint16_t)(72000000/11025);
break; /* 11.025KHz = 2x36MHz / 6531 */
case SAMPLE_RATE_16000:
arrValue = (uint16_t)(72000000/16000);
break; /* 16KHz = 2x36MHz / 4500 */
case SAMPLE_RATE_22050:
arrValue = (uint16_t)(72000000/22050);
break; /* 22.05KHz = 2x36MHz / 2365 */
case SAMPLE_RATE_44100:
arrValue = (uint16_t)(72000000/44100);
break; /* 44.1KHz = 2x36MHz / 1633 */
case SAMPLE_RATE_48000:
arrValue = (uint16_t)(72000000/48000);
break; /* 48KHz = 2x36MHz / 1500 */
default:
arrValue = 0;
break;
}
return arrValue;
}
上一篇:STM32 PCM1770调试
下一篇:STM32F4 FFT 音乐频谱 不要太easy!
推荐阅读最新更新时间:2024-03-16 16:09