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

 

笔记:

本想使用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;
}





  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值