硬件部分:
跳线帽将AIN和DAC连起来即可,如下图所示:
具体看原理图:
下图中,PWM AUDIO就是上图开发板上的AIN引脚。
下图中,PWM AUDIO通过TDA1308T芯片对应到PHONE(3.5mm音频输出口)。
其他信息:
1)图1 DAC对应STM32芯片的PA4引脚;
2)本次使用TIM3定时器,其他定时器也可用。
软件部分:
通过硬件连接方式,不难理解开发思路:
1)DAC输出信号至音频输出端;
2)利用TIM定时器产生中断给DAC喂数据;
具体代码如下:
1)dac.h头文件
- /**
- ******************************** STM32F10x *********************************
- * @文件名称: dac.h
- * @作者名称: Aaron
- * @库版本号: V3.5.0
- * @工程版本: V1.0.0
- * @开发日期: 2020年11月23日
- * @摘要简述: dac头文件
- ******************************************************************************/
- /*----------------------------------------------------------------------------
- * @更新日志:
- * @无
- * ---------------------------------------------------------------------------*/
- #ifndef __DAC_H
- #define __DAC_H
- /* 包含头文件 -----------------------------------------------------------------*/
- #include "stm32f10x.h"
- /* 函数申明 -------------------------------------------------------------------*/
- void Dac1_Init(void); // DAC1 初始化
- void Dac1_Set_Vol(u16 vol); // 设置DAC1 电压值
- #endif /* __DAC_H */
- /****** Copyright (C)2020 Aaron. All Rights Reserved ****** END OF FILE *******/
复制代码
2)dac.c源文件
- /**
- ******************************** STM32F10x *********************************
- * @文件名称: dac.c
- * @作者名称: Aaron
- * @库版本号: V3.5.0
- * @工程版本: V1.0.0
- * @开发日期: 2020年11月23日
- * @摘要简述: dac源文件
- ******************************************************************************/
- /*----------------------------------------------------------------------------
- * @更新日志:
- * @无
- * ---------------------------------------------------------------------------*/
- /* 包含头文件 -----------------------------------------------------------------*/
- #include "dac.h"
- /************************************************
- 函数名称:void Dac1_Init()
- 函数功能:Dac1初始化函数
- 入口参数:无
- 返回参数:无
- 开发作者:Aaron
- *************************************************/
- void Dac1_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- DAC_InitTypeDef DAC_InitType;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE ); // 使能GPIOA通道时钟
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE ); // 使能DAC通道时钟
- // 设置PA4,模拟输入,因为一旦使能DACx通道后,相应的GPIO引脚会自动与DAC模拟输出相连,设置为输入,可避免额外的干扰
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // 选择引脚4
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // 模拟输入
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_SetBits(GPIOA,GPIO_Pin_4) ; // 令PA4输出高
- DAC_InitType.DAC_Trigger=DAC_Trigger_None; // 不使用触发功能
- DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None; // 不使用波形发生
- DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0; // 屏蔽、幅值设置
- DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ; // DAC1输出缓存关闭 BOFF1=1
- DAC_Init(DAC_Channel_1,&DAC_InitType);
- DAC_Cmd(DAC_Channel_1, ENABLE); // 使能DAC1转换通道
- DAC_SetChannel1Data(DAC_Align_12b_R, 0); // 12位右对齐数据格式设置DAC值
- }
- /************************************************
- 函数名称:Dac1_Set_Vol(u16 vol)
- 函数功能:设置通道1输出电压函数
- 入口参数:u16 vol:输入值范围0~3300,表示0~3.3V
- 返回参数:无
- 开发作者:Aaron
- *************************************************/
- void Dac1_Set_Vol(u16 vol)
- {
- float temp=vol;
- temp/=1000; // 即temp=temp/1000
- temp=temp*4096/3.3; // 因为DAC是12位,所以2^12=4096
- DAC_SetChannel1Data(DAC_Align_12b_R,temp); // 12位右对齐数据格式设置DAC值
- }
复制代码
3)timer.h头文件
- /**
- ******************************** STM32F10x *********************************
- * @文件名称: timer.h
- * @作者名称: Aaron
- * @库版本号: V3.5.0
- * @工程版本: V1.0.0
- * @开发日期: 2020年11月23日
- * @摘要简述: timer源文件
- ******************************************************************************/
- /*----------------------------------------------------------------------------
- * @更新日志:
- * @无
- * ---------------------------------------------------------------------------*/
- #ifndef __TIMER_H
- #define __TIMER_H
- /* 包含头文件 -----------------------------------------------------------------*/
- #include "stm32f10x.h"
- /* 函数申明 -------------------------------------------------------------------*/
- void TIMER3_Interrput_Init(u16 arr, u16 psc); // 定时器3中断初始化函数
- #endif /* __TIMER_H */
- /****** Copyright (C)2020 Aaron. All Rights Reserved ****** END OF FILE *******/
复制代码
4)timer.c源文件
- /**
- ******************************** STM32F10x *********************************
- * @文件名称: timer.c
- * @作者名称: Aaron
- * @库版本号: V3.5.0
- * @工程版本: V1.0.0
- * @开发日期: 2020年11月23日
- * @摘要简述: timer源文件
- ******************************************************************************/
- /*----------------------------------------------------------------------------
- * @更新日志:
- * @无
- * ---------------------------------------------------------------------------*/
- /* 包含头文件 -----------------------------------------------------------------*/
- #include "timer.h"
- /************************************************
- 函数名称:TIMER3_Interrput_Init(u16 arr, u16 psc)
- 函数功能:定时器3 中断初始化函数
- 入口参数:u16 arr:自动重装载值, u16 psc:时钟预分频数
- 举例:令arr=4999,psc=7199,
- 则计数周期为(7199+1)/72000000=0.00001s,对应频率10KHz;
- 计数(4999+1)=5000值,需0.5s
- 返回参数:无
- 开发作者:Aaron
- *************************************************/
- void TIMER3_Interrput_Init(u16 arr, u16 psc)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitTypeStruct;
- NVIC_InitTypeDef NVIC_InitTypeDef_TIM3Struct;
- TIM_DeInit(TIM3);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); // 使能TIM3时钟
- // 定时器7 参数初始化配置
- TIM_TimeBaseInitTypeStruct.TIM_Period=arr;
- TIM_TimeBaseInitTypeStruct.TIM_Prescaler=psc;
- TIM_TimeBaseInitTypeStruct.TIM_CounterMode=TIM_CounterMode_Down; // 向上计数模式
- TIM_TimeBaseInitTypeStruct.TIM_ClockDivision=TIM_CKD_DIV1;
- TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitTypeStruct);
- TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); // 使能定时器3更新中断
- // 定时器3 中断优先级配置
- NVIC_InitTypeDef_TIM3Struct.NVIC_IRQChannel=TIM3_IRQn;
- NVIC_InitTypeDef_TIM3Struct.NVIC_IRQChannelCmd=ENABLE;
- NVIC_InitTypeDef_TIM3Struct.NVIC_IRQChannelPreemptionPriority=1;
- NVIC_InitTypeDef_TIM3Struct.NVIC_IRQChannelSubPriority=3;
- NVIC_Init(&NVIC_InitTypeDef_TIM3Struct);
- // 使能定时器3
- TIM_Cmd(TIM3,ENABLE);
- }
- /************************************************
- 函数名称:TIM3_IRQHandler()
- 函数功能:定时器3 中断服务函数
- 入口参数:无
- 返回参数:无
- 开发作者:Aaron
- *************************************************/
- extern u16 Data;
- void TIM3_IRQHandler(void)
- {
- // 获取定时器3 状态
- if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) // 判断定时器3 状态是否为更新中断
- {
- GetData();
- Dac1_Set_Vol(Data);
- TIM_ClearITPendingBit(TIM3,TIM_IT_Update); // 清除更新中断标识
- }
- }
复制代码
5)main.c主函数
- /**
- ******************************** STM32F10x *********************************
- * @文件名称: main.c
- * @作者名称: Aaron
- * @库版本号: V3.5.0
- * @工程版本: V1.0.0
- * @开发日期: 2020年11月23日
- * @摘要简述: 主函数
- ******************************************************************************/
- /*----------------------------------------------------------------------------
- * @更新日志:
- * @无
- * ---------------------------------------------------------------------------*/
- /* 包含头文件 -----------------------------------------------------------------*/
- #include "led.h"
- #include "dac.h"
- #include "timer.h"
- #include "delay.h"
- int main(void)
- {
- LED_Init(); // LED端口初始化//
- LED0=1;
- delay_init(); // 延时函数初始化//
- TIMER3_Interrput_Init(3599, 1);
- Dac1_Init(); // DAC初始化//
- while(1)
- {
- delay_ms(200);
- LED0=!LED0;
- }
- }
复制代码
备注:getdata相关代码主要用来计算要喂给dac的值,我建了一个3000个数值的正弦波信号来调试程序,后期更具需要改声音数据吧。
实验结果:
将耳机插在Phone口上(即3.5mm音频接口),耳机左声道可听到所设的声音。
————————————————
版权声明:天亮继续睡
|