历史上的今天
今天是:2025年07月24日(星期四)
2018年07月24日 | (STM32)使用DAC输出WAVE音频波形
2018-07-24 来源:eefocus
笔记:
本想使用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;
}
史海拾趣
|
我从本论坛下了一个单片机电子万年历的资料有问题想请教下各位高手 具体的问题是电路数码管有的亮有的不亮,还有程序不运行请教下各位是什么问题啊 谢谢!!电路图和程序都在附件中请大家帮帮忙看下市怎么回事?… 查看全部问答> |
|
这些天在研究论坛里曾经组织过的活动----魔幻光影棒 看了那个用MSP430F1232的电路图 看不明白了~ 问几个笨笨的问题: 1. LVC573(74LCX573)的作用到底是什么呢?请详细的说下~~ 2. ULN2003的作用呢?在网上查资料 貌似 ...… 查看全部问答> |
|
带个DC12V的电池就ok了 比如摩托车电池 还有很多系统里面都带有后备电池都是DC12V的 要是这些都没有也可以去商店买8个1.5V的干电池传联起来用也可以 用电池供电可以保证电的质量 用这个方法可以帮助判断很多可能是电源引起的故障… 查看全部问答> |
|
想把5.0的bsp移植到6.0,除了kitl,其他目录都编译通过了, 在整kitl时,发现了个问题,如下~~~ 这个是kitl目录下的source文件 [code] TARGETNAME=KITL TARGETTYPE=DYNLINK DLLENTRY=KitlDllMain DEFFILE= NOLIBC=1 SOURCES= TARGETLIBS ...… 查看全部问答> |
|
情况是这样的: 我一个在linux下跑的C程序 主要是完成GSM发短信的功能~~~ 短信短一点的情况 可以成功发出去“HELLO WORLD”这样~~ 长一点 就发布过去“fwefjweifjweofjwoiejfioewfjwoejfweo”就发不出去了~ 但是我在minicom 下是可以发送出去 ...… 查看全部问答> |




