历史上的今天
返回首页

历史上的今天

今天是:2024年12月30日(星期一)

正在发生

2021年12月30日 | STM32F103使用DAC功能输出正弦波

2021-12-30 来源:eefocus

在DAC的主要特征中可以看出,DAC内部带有波形发生器。


DAC 主要特征


2个DAC转换器:每个转换器对应1个输出通道

8位或者12位单调输出

12位模式下数据左对齐或者右对齐

同步更新功能

噪声波形生成

三角波形生成

双DAC通道同时或者分别转换

每个通道都有DMA功能

外部触发转换

输入参考电压V REF+


但是这里面只有三角波和噪声波,那么正弦波要如何生成呢?


虽然DAC没有自带正弦波的功能,但是我们可以先生成一个符合正弦规律的数组,然后通过定时器,将正弦数组中的值依次发送出去,这样输出的电压值也就会成正弦规律变化了。


下面直接通过代码来演示如何输出正弦波


#include "dac_sin.h"


#define DAC_DHR12RD_Address      0x40007420



uc16 Sine12bit[32] = {2047, 2447, 2831, 3185, 3498, 3750, 3939, 4056, 4095, 4056,

                      3939, 3750, 3495, 3185, 2831, 2447, 2047, 1647, 1263, 909,

                      599, 344, 155, 38, 0, 38, 155, 344, 599, 909, 1263, 1647

                     };


u32 DualSine12bit[32];

u8 Idx = 0;


//用DMA在PA4、PA5上产生正弦波

void DAC_SIN_Init(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    DAC_InitTypeDef  DAC_InitStructure;

    TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;

    DMA_InitTypeDef  DMA_InitStructure;

    //时钟设置

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);

    //GPIO设置

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4 | GPIO_Pin_5;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    //高级定时器设置

    TIM_TimeBaseStructure.TIM_Period = 0x19;

    TIM_TimeBaseStructure.TIM_Prescaler = 0x00;

    TIM_TimeBaseStructure.TIM_ClockDivision = 0x00;

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x00;

    TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);


    TIM_SelectOutputTrigger(TIM8, TIM_TRGOSource_Update);

    //DAC设置

    DAC_InitStructure.DAC_Trigger = DAC_Trigger_T8_TRGO; //TIM8触发

    DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;

    DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;

    DAC_Init(DAC_Channel_1, &DAC_InitStructure);


    DAC_Init(DAC_Channel_2, &DAC_InitStructure);


    for(Idx = 0; Idx < 32; Idx++)

    {

        DualSine12bit[Idx] = (Sine12bit[Idx] << 16) + (Sine12bit[Idx]);

    }

    //DMA设置

    DMA_DeInit(DMA2_Channel4);


    DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12RD_Address; //DMA外设基地址

    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&DualSine12bit; //DMA内存基地址

    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,从存储器读

    DMA_InitStructure.DMA_BufferSize = 32; //DMA通道的DMA缓存的大小

    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变

    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增

    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //数据宽度为32位

    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; //数据宽度为32位

    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作模式为循环模式

    DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级

    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x 非存储器到存储器模式

    DMA_Init(DMA2_Channel4, &DMA_InitStructure);


    DMA_Cmd(DMA2_Channel4, ENABLE); //使能DMA2通道4


    DAC_Cmd(DAC_Channel_1, ENABLE); //使能DAC通道1

    DAC_Cmd(DAC_Channel_2, ENABLE); //使能DAC通道2


    DAC_DMACmd(DAC_Channel_2, ENABLE); //使能DAC的DMA功能


    TIM_Cmd(TIM8, ENABLE); //使能定时器

}


Sine12bit数组中存放的数据就是按照正弦规律变化了,可以将数组中的数据复制到表格中,观察一下。

image.png?imageView2/2/w/550

可以看出数组中的数据组成了一个标准的正弦波。


数据有了之后开始初始化DAC,这里DAC依然使用定时器触发,使用定时8触发,波形的产生方式设置为无,因为这里不使用内部的波形发生器。


接下来数据的传输选择使用DMA模式,当然也可是通过程序设置一个循环来依次将数据中的值放到DAC寄存器中去,但是这样比较占用单片机的资源,为了节省资源,可以让单片机自己来实现这个功能。

image.png?imageView2/2/w/550

将DMA的外设地址设置为DAC寄存器的地址,将DMA的内存地址设置为存储正弦波数据的数组,这样每次定时器8的中断发生之后,DMA就会自动从数组中拿出一个数据设置到DAC的寄存器中。通过DMA功能就可以实现数组中的数据依次被放到DAC的数据保持寄存器中。


最后使能定时器,DAC,DMA功能后,DAC的两个输出端口PA4和PA5就会自动输出成正弦规律变化的波形了。

推荐阅读

史海拾趣

Headland Technology Product Group公司的发展小趣事

近年来,随着环保意识的日益增强,HBControls积极响应国家号召,致力于绿色环保产品的研发和生产。公司投入大量资金引进环保设备和技术,对生产流程进行改造升级,以减少对环境的影响。同时,HBControls还积极推广绿色供应链理念,与供应商共同构建绿色、低碳的供应链体系。这些举措不仅提升了公司的社会形象,也为企业的可持续发展奠定了坚实的基础。

All Sensors公司的发展小趣事

All Sensors公司的创始人Dennis被誉为美国硅谷的传奇人物。在70年代,Dennis在硅谷成功发明了全球第一颗压力传感器,这一创新不仅奠定了All Sensors在传感器领域的领先地位,也为整个电子行业带来了新的技术革命。这颗传感器的诞生,标志着All Sensors正式踏上了传感器技术的研发之路,为后续的发展奠定了坚实的基础。

Calex Mfg Co Inc公司的发展小趣事

在国内市场取得一定成绩后,Calex Mfg. Co., Inc.开始积极拓展海外市场。公司制定了全球化战略,通过参加国际展会、建立海外销售网络等方式,不断开拓国际市场。同时,公司还根据不同地区的市场需求,推出定制化的产品和服务,进一步提升了其在国际市场中的竞争力。

CBM_America_Corporation公司的发展小趣事

在面临激烈的市场竞争时,CBM_America_Corporation选择与一家国际知名的电子制造商建立战略合作关系。通过共享技术资源和市场渠道,两家公司共同开发了一款具有竞争力的智能设备。这一合作不仅提升了CBM的品牌影响力,还为其带来了稳定的订单和利润增长。随着合作的深入,CBM逐渐在电子行业中占据了重要的地位。

FUJIKURA公司的发展小趣事

随着科技的快速发展,CBM_America_Corporation意识到传统电子产品市场的饱和趋势。为了保持竞争力,公司决定进行创新转型,将业务重心转向智能家居和物联网领域。通过研发智能家居设备和物联网解决方案,CBM成功打开了新的市场空间。同时,公司还积极拓展多元化业务,涉及到了电子支付、数据安全等领域,进一步提升了公司的综合实力。

Elec & Eltek公司的发展小趣事

在国内市场取得一定成绩后,Elec公司开始将目光投向国际市场。为了更好地适应国际市场的需求,Elec公司积极引进国际先进技术和管理经验,并加强与国际知名企业的合作。同时,Elec公司还加大了在海外市场的营销力度,通过参加国际展会、举办技术研讨会等方式提高品牌知名度。经过多年的努力,Elec公司的产品已远销欧美、东南亚等多个国家和地区,成为国际市场上具有竞争力的电子品牌。

问答坊 | AI 解惑

大家好!高人过来出个主意呀!

现在要做个高速的图像传输缓冲,速度为100Mb/s,请大家推荐一个好的方案!谢谢先! FPGA+SDRAM方案可以吗?FPGA选那个型号好!…

查看全部问答>

LPC1114F样片申请

你好!!我最近在搞ARM7单片机(LPC1114),我买的是一块板!!由于我最近用这款芯片在搞一个项目,灯光照明控制的,要做个最小系统!!今天,在网上看见贵公司提供LPC1114F样片!!在这里提交了这份申请表!!望贵公司批准!!谢谢!!  …

查看全部问答>

MSP430修改中断优先级

如何把430的TA定时设为最高优先级…

查看全部问答>

请问YL 2440的BIOS程序谁调试过?

调试YL2440的YLP2440_MON,用的是ADS1.2,H-JTAG。调试时总是在 main函数入口出就异常了,不再往下继续执行,请问谁遇到这个问题,不知道怎么解决?…

查看全部问答>

驱动中使用__try快的链接错误问题

我在驱动开发中使用了__try __finally块后链接的时候会出现链接错误如下: unresolved external symbol __except_handler4 是不是少了哪个链接库,我链接的库有wdm.lib BufferOverflowK.lib wmilib.lib usbd.lib 求各位大侠指点!…

查看全部问答>

Windows Mobile 鼠标问题

多普达和三星的机器很多用了轨迹球和一些感应器件,但是不知道怎么在Windows Mobile里面加上鼠标,调了一下lcd driver,但是还是没有达到理想的效果,能偶尔闪出鼠标指针,哪位做过Mobile鼠标的能来指点下?…

查看全部问答>

IROM启动方式出问题

以前一直没用过IROM启动方式,现在在2450平台上弄IROM方式启动,编译的内核启动不了,麻烦大侠们帮忙看看哪里出问题了。 Read OS image to BootMedia Success waitforconnect INFO: OEMLaunch: Jumping to Physical Address 0x3020D2DCh (Virtual ...…

查看全部问答>

eVC中有这样一个bug:当您使用 CWnd 类版本的 GetDC 方法和 ReleaseDC 方法 BUG: 内存泄漏。 如果打了SP4补丁,此问题是否修复?

eVC中有这样一个bug:当您使用 CWnd 类版本的 GetDC 方法和 ReleaseDC 方法 BUG: 内存泄漏。 如果打了SP4补丁,此问题是否修复? 参看微软的信息:http://support.microsoft.com/kb/819635/zh-cn…

查看全部问答>

进程查询的终止条件

如何通过当前的进程结束引起该进程的父进程?…

查看全部问答>