STM32实验-输出DAC正弦波

这篇具有很好参考价值的文章主要介绍了STM32实验-输出DAC正弦波。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

首先我们知道正弦波的解析式为y=Asin(omiga*x+fei)+b,拓展到STM32中则会得到如下的式子:

y=2048*sin((2*pi/samples)*x)+2048.

其中形参的取值范围是(samples/2)<maxval,采样的间隔是2*pi/samples。

接下来编写我们的函数代码dac_sin.c:

#include "./BSP/DAC/dac_sin.h"
#include "math.c"
 
DAC_HandleTypeDef g_dac_handle;
DMA_HandleTypeDef g_dma_handle;
uint16_t g_dac_sin_buf[4096];

void dac_dma_init(void){

    g_dma_handle.Instance = DMA2_Channel3;
    g_dma_handle.Init.Direction = DMA_MEMORY_TO_PERIPH;  //外设到内存
    g_dma_handle.Init.PeriphInc = DMA_PINC_DISABLE;  //因为选取的是DMA2的数据寄存器,选择不增量
    g_dma_handle.Init.MemInc = DMA_MINC_ENABLE;  //对于存储器需要存储多个数据,所以选择增量模式
    g_dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; //外设数据位宽,我们选择16位半字(全字可以理解为全角中文字符)
    g_dma_handle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;  //存储器数据位宽,我们也选择16位半字
    g_dma_handle.Init.Mode = DMA_CIRCULAR;   //选择循环模式
    g_dma_handle.Init.Priority = DMA_PRIORITY_MEDIUM;   //只有1个DMA随便选
    HAL_DMA_Init(&g_dma_handle);
 
    DAC_ChannelConfTypeDef dac_ch_conf;
 
    g_dac_handle.Instance = DAC1; //寄存器基地址
    HAL_DAC_Init(&g_dac_handle);
    _HAL_LINKDMA(&g_dac_handle, DMA_Handle1, &g_dma_handle); //DMA_Handle1是因为选用的是DAC通道1
 
    dac_ch_conf.Trigger = DAC_TRIGGER_T7_TRGO; //触发源选择,选择外部定时器7
    dac_ch_conf.OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
    HAL_DAC_ConfigChannel(&g_dac_handle, &dac_ch_conf, DAC_CHANNEL_1);
 
    HAL_DAC_Start(&g_dac_handle, (uint32_t*)g_dac_sin_buf, (uint32_t)&DAC->DHR12R1, 0); //第三个参数,12位右对齐
}
 
void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac){
 
    if(hdac->Instance == DAC1){
        GPIO_InitTypeDef gpio_init_struct;
        __HAL_RCC_GPIOA_CLK_ENABLE();
        __HAL_RCC_DAC_CLK_ENABLE();
 
        gpio_init_struct.Pin = GPIO_PIN_4;
        gpio_init_strcut.Mode = GPIO_MODE_ANALOG;
        HAL_GPIO_Init(GPIOA, &gpio_init_struct);
    }
}
 
void dac_dma_wave_enable(uint16_t cndtr, uint16_t arr, uint16_t psc){
    TIM_HandleTypeDef g_tim7_handle = {0};
    TIM_MasterConfigTypeDef tim_master_config = {0};
    __HAL_RCC_TIM7_CLK_ENABLE();

    g_tim7_handle.Instance = TIM7;
    g_tim7_Handle.Init.Prescalar = psc;
    g_tim7_handle.init.Period = arr;
    HAL_TIM_Base_Init(&g_tim7_handle);
    
    tim_master_config.MasterOutputTrigger = TIM_TRGO_UPDATE; //选择更新,更新事件作为触发源
    tim_master_config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; //可选同步或无,我们选择无
    HAL_TIMEx_MasterConifgSynchronization(&g_tim7_handle, &);
    //配置定时器触发DAC变换
    HAL_TIM_Base_Start(&g_tim7_handle);

    HAL_DAC_Stop_DMA(&g_dac_handle, &DAC_CHANNEL_1);
    HAL_DAC_Start_DMA(&g_dac_handle, &DAC_CHANNEL_1, (uint32_t*)g_dac_sin_buf, cndtr); //第三个参数为数据来源,第四个参数为数据长度
}

void dac_creat_sin_buf(uint16_t maxval, uint_16 samples){
    uint8_t i;
    float outdata = 0;
    float inc = (2 * 3.1415926) / samples;

    if(maxval <= (samples / 2))return;

    for(i=0; i<samples; i++){
        outdata = maxval * sin(inc * i) + maxval;
        if(outdata > 4095){
            outdata = 4095;
        }
        g_dac_sin_buf[i] = outdata;
    }
}

接下来编写函数头文件dac_sin.h:

#ifndef __DAC_SIN_H
#define __DAC_SIN_H

extern g_dac_sin_buf[4096];
 
void dac_dma_init(void);
void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac);
void dac_creat_sin_buf(uint16_t vol);
 
#endif

最后编写主函数main.c:

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./USMART/usmart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./BSP/DAC/dac_sin.h"
#include "./BSP/ADC/adc.h"
 
int main(void)
{
    uint16_t adcx;
    float temp;
    uint8_t t = 0;
    uint16_t dacval = 0;
    uint8_t key;
 
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟, 72Mhz */
    delay_init(72);                             /* 延时初始化 */
    usart_init(115200);                         /* 串口初始化为115200 */
    usmart_dev.init(72);                        /* 初始化USMART */
    led_init();                                 /* 初始化LED */
    lcd_init();                                 /* 初始化LCD */
    key_init();                                 /* 初始化按键 */
    adc3_init();                                /* 初始化ADC3 */
    dac_dma_init(1);                                /* 初始化DAC1_OUT1通道 */
    
    lcd_show_string(30,  50, 200, 16, 16, "STM32F103", RED);
    lcd_show_string(30,  70, 200, 16, 16, "DAC TEST", RED);
    lcd_show_string(30,  90, 200, 16, 16, "ATOM@ALIENTEK", RED);
    lcd_show_string(30, 110, 200, 16, 16, "WK_UP:+  KEY1:-", RED);

    dac_creat_sin_buf(2048, 100);
    dac_dma_wave_enable(100, 10 - 1, 72 - 1); //100kHz, 100个点,得到1kHz的正弦波
    
    while (1)
    {
        t++;
        key = key_scan(0);          /* 按键扫描 */
 
        if (key == WKUP_PRES)
        {
            dac_creat_sin_buf(2048, 100);
            dac_dma_wave_enable(100, 10 - 1, 24 - 1); //300kHz, 100个点,得到3kHz的正弦波
        }
        else if (key == KEY1_PRES)
        {
            dac_creat_sin_buf(2048, 100);
            dac_dma_wave_enable(10, 10 - 1, 24 - 1);  //300kHz, 10个点,得到30kHz的正弦波
        }
 
        if(t == 40){
            LED0_TOGGLE();
            t = 0;
        }
 
        delay_ms(10);
    }
}

到这里我们的实验代码就写完了。文章来源地址https://www.toymoban.com/news/detail-612501.html

到了这里,关于STM32实验-输出DAC正弦波的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【stm32】DAC输出三角波锯齿波

    导入DAC.ioc(见上节DAC学习笔记) CubeMX图形化配置 DAC配置 实现0.1ms定时周期 时钟树配置 程序编写 实现效果 采用CubeMonitor监测生成波形 也可用示波器检测波形生成结果 在此处更改配置 使用DMA触发任意波形 若要调整锯齿波的周期,修改TIM6的分频系数和计数周期即可 程序编写

    2024年02月22日
    浏览(39)
  • 【STM32+HAL】DAC+DMA输出波形实现

    有关CUBEMX的初始化配置,参见我的另一篇blog:【STM32+HAL】CUBEMX初始化配置 1、芯片: STM32F407ZGT6 2、STM32CubeMx软件 3、IDE: MDK-Keil软件 4、STM32F4xxHAL库 1、DAC+DMA输出波形 2、按键切换波形及频率 3、串口打印当前波形以及频率值 1、开启DAC 这里开启的是通道一 Output Buffer:关闭后可

    2024年02月02日
    浏览(47)
  • STM32——DAC数模转换实验

    一、数模转换原理 STM32的DAC模块是十二位数字输入,电压输出型的DAC,DAC可以配置为8位或12位模式,也可以与DMA控制器配合使用。DAC工作在12位模式时,数据可以设置成左对齐或者右对齐。DAC模块有2个输出通道,每个通道都有单独的转换器。在双DAC模式下,2个通道可以独立的

    2024年02月05日
    浏览(40)
  • STM32CubeMX教程17 DAC - 输出三角波噪声波

    正点原子stm32f407探索者开发板V2.4 STM32CubeMX软件(Version 6.10.0) keil µVision5 IDE(MDK-Arm) ST-LINK/V2驱动 野火DAP仿真器 XCOM V2.6串口助手 一台示波器 使用STM32CubeMX软件配置STM32F407开发板的 DAC OUT1实现输出三角波 STM32F407的DAC输出引脚除可以输出 DACoutput = VREF+ * DOR / 4095 的模拟电压之外

    2024年01月18日
    浏览(40)
  • STM32CubeMX教程18 DAC - DMA输出自定义波形

    开发板(正点原子stm32f407探索者开发板V2.4) STM32CubeMX软件(Version 6.10.0) 野火DAP仿真器 keil µVision5 IDE(MDK-Arm) ST-LINK/V2驱动 一台示波器 逻辑分析仪nanoDLA 使用STM32CubeMX软件配置STM32F407开发板的 DAC OUT1实现输出0-3.3V 周期为12.8ms的正弦波形 由于STM32F407的两个DAC输出通道只能自动

    2024年01月19日
    浏览(51)
  • STM32配置ADC2(DMA)进行采集 DAC 输出-2

    在上一节的基础上,我们把 DAC(三角波)给集成进来,实现按下按键输出三角波,通过串口发送数据给电脑,分析然后画出电压的波形并且展示出来 开发板:正点原子探索者STM32F407ZG 2.1 DAC部分 这里我们采用 实验22-2 DAC输出三角波实验 的例程,查看主函数找中和 DAC 相关的代

    2024年02月01日
    浏览(34)
  • STM32配置ADC2(DMA)进行采集 DAC 输出-1

    在正点原子的ADC(DMA)例程上,将ADC1改成ADC2来采集电压,并且进行测试 开发板:正点原子探索者STM32F407ZG 2.1 ADC相关 通过查看开发指南我们发现,ADC1 和 ADC2 的通道 5 都是采用的 PA5 引脚,就意味着我们修改为 ADC2 后还是可以通过 PA5 来进行电压的测量。 对应的我们在adc.h中

    2024年02月02日
    浏览(59)
  • Proteus仿真stm32f103r6输出PWM/正弦波

    Proteus仿真stm32f103r6输出PWM/正弦波  

    2024年01月23日
    浏览(47)
  • STM32模拟SPI时序控制双路16位数模转换(16bit DAC)芯片DAC8552电压输出

    STM32部分芯片具有12位DAC输出能力,要实现16位及以上DAC输出需要外挂DAC转换ASIC。 DAC8552是双路16位DAC输出芯片,通过SPI三线总线进行配置控制输出。这里介绍通过GPIO管脚模拟时序进行控制的方式。 DAC8552支持2.7V~5.5V的供电,根据需要提供电源电压,对于STM32可能面对不同供电电

    2023年04月09日
    浏览(41)
  • STM32F103R8T6 SPWM实现正弦波输出

    PWM合成正弦波,原理什么的不详细说了,概括一下就是 PWM有效面积的积分 = 正弦波的有效面积。PWM的频率越快,细分的越多,锯齿也就越不明显。 做法是:首先利用正弦波取点软件,取点1000个,生成一个正弦波的数组。 PWM波的频率(F_PWM)与正弦波频率(F_SIN)之间的对应关系与

    2024年02月03日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包