×
单片机 > 单片机程序设计 > 详情

(STM32)使用DAC输出WAVE音频波形

发布时间:2020-05-29 发布时间:
|

笔记:

本想使用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中断向量表的位置.重定向