当前位置: 首页 > article >正文

STM32G474使用TIM2触发DAC输出输出正弦波

STM32G474使用TIM2触发DAC输出,数据从内存到外设就要使用DMA来协助。DAC1每隔1秒输出一个正弦波数据,就会模拟近似得到模拟的正弦波形。用来测试CPU内部的运算放大器,或者用作其它模拟输入信号。

测试程序如下:

#include "DAC.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "string.h" //使能strcpy(),strlen(),memset()
#include "delay.h"

/*
STM32G474之DAC输出,使用DMA从内存搬运数据到DAC1外设,使用TIM2触发DAC1输出
*/

void DAC1_CHANNEL_1_Init(void);

const uint16_t Sine12bit[32] = { 511,  611,  707,  796,  873,  937,  984, 1013,
                                1023, 1013,  984,  937,  873,  796,  707,  611,
                                 511,  412,  315,  227,  149,   86,   38,    9,
                                   0,    9,   38,   86,  149,  227,  315,  412};
//函数功能:DAC1通道1初始化
void DAC1_CHANNEL_1_Init(void)
{
    DAC_HandleTypeDef      hdac1;
//DAC1句柄,若直接对寄存器DAC1->DHR12R1和DAC1->DHR12R2操作,就可以将其设置为局部变量
//DAC1->DHR12R1为DAC通道1(12位右对齐数据保持寄存器)
//DAC1->DHR12R2为DAC通道2(12位右对齐数据保持寄存器)

    GPIO_InitTypeDef GPIO_InitStruct = {0};
    DAC_ChannelConfTypeDef sConfig;        //DAC通道参数相关结构体

    DMA_HandleTypeDef hdma_dac1_ch1;

    TIM_HandleTypeDef htim2;
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

    __HAL_RCC_DAC1_CLK_ENABLE();
    //使能DAC1时钟
    //RCC_AHB2ENR寄存器bit18(DAC1EN),令DAC1EN=1使能DAC1时钟

  
  __HAL_RCC_GPIOA_CLK_ENABLE();//GPIOA时钟使能
  GPIO_InitStruct.Pin = GPIO_PIN_4;              //选择引脚号码为4
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;       //模拟模式
    GPIO_InitStruct.Pull = GPIO_NOPULL;            //引脚上拉和下拉都没有被激活
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    //根据GPIO_InitStruct结构变量指定的参数初始化GPIOA的外设寄存器,将PA4引脚连接到DAC1通道1

    hdac1.Instance = DAC1; //DAC1
    HAL_DAC_Init(&hdac1);  //初始化DAC

    sConfig.DAC_HighFrequency     = DAC_HIGH_FREQUENCY_INTERFACE_MODE_ABOVE_160MHZ;
    //DAC时钟选择
  sConfig.DAC_DMADoubleDataMode = DISABLE; //双重数据模式(高带宽模式)关闭
  sConfig.DAC_SignedFormat      = DISABLE; //有符号模式关闭
  sConfig.DAC_SampleAndHold     = DAC_SAMPLEANDHOLD_DISABLE; //关闭采样保持


//  sConfig.DAC_Trigger           = DAC_TRIGGER_NONE;          //不需要外部触发
  sConfig.DAC_Trigger = DAC_TRIGGER_T2_TRGO;//使用TIM2触发DAC输出
  sConfig.DAC_Trigger2 = DAC_TRIGGER_NONE;


  sConfig.DAC_OutputBuffer      = DAC_OUTPUTBUFFER_ENABLE;   //DAC输出缓冲器打开
    sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_ENABLE;//允许内部连接DAC_Channel
//    sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_DISABLE;    //不允许内部连接DAC_Channel
    sConfig.DAC_UserTrimming      = DAC_TRIMMING_FACTORY;      //工厂矫正模式
  HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_1);   //初始化

    __HAL_RCC_DMA1_CLK_ENABLE();   //DMA1时钟使能
    __HAL_RCC_DMAMUX1_CLK_ENABLE();//设置RCC->AHB1ENR寄存器bit2(DMAMUX1EN位),令DMAMUX1EN=1,DMAMUX1时钟使能
    hdma_dac1_ch1.Instance = DMA1_Channel1;//使用DMA1的通道1
    hdma_dac1_ch1.Init.Request = DMA_REQUEST_DAC1_CHANNEL1;//DMA需求来源DAC1
    hdma_dac1_ch1.Init.Direction = DMA_MEMORY_TO_PERIPH;
    //设置DMA_CCRx寄存器bit4(DIR位),令DIR=1,数据传输方向:内存到外设
    hdma_dac1_ch1.Init.PeriphInc = DMA_PINC_DISABLE;
    //设置DMA_CCRx寄存器bit6(PINC位),令PINC=0,外设地址不增加
    hdma_dac1_ch1.Init.MemInc = DMA_MINC_ENABLE;
    //设置DMA_CCRx寄存器bit7(MINC位),令MINC=1,内存地址增加
    hdma_dac1_ch1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    //设置DMA_CCRx寄存器bit9:8(PSIZE[1:0]位),令PSIZE[1:0]=10,外设数据宽度32bits
    hdma_dac1_ch1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    //设置DMA_CCRx寄存器bit11:10(MSIZE[1:0]]位),令MSIZE[1:0]=01,内存数据宽度16bits
    hdma_dac1_ch1.Init.Mode = DMA_CIRCULAR;
    //DMA_CIRCULAR:“DAM循环搬运数据”
    //DMA_NORMAL;若启动一次DMA,则DMA搬运一次数据
    //设置DMA_CCRx寄存器bit5(CIRC位),令CIRC=1,这里设置“DAM循环搬运数据”

    hdma_dac1_ch1.Init.Priority = DMA_PRIORITY_VERY_HIGH;
    //设置DMA_CCRx寄存器bit13:12(PL[1:0]),令PL[1:0]=11b,DMA抢占优先级最高
    HAL_DMA_Init(&hdma_dac1_ch1);

    __HAL_LINKDMA(&hdac1,DMA_Handle1,hdma_dac1_ch1);
    //将DAC1与DMA联系起来
    //把hdac1结构体的参数赋给DMA_Handle1

  __HAL_RCC_TIM2_CLK_ENABLE();//使能“定时器2”的时钟,Enable TIM2 clock
  htim2.Instance = TIM2;
  htim2.Init.Period = 9999;
    //定时器周期(9999+1)
  htim2.Init.Prescaler = 16;
    //设置TIM1预分频器为(16+1)
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    //设置时钟分频系数,TIM1_CR1中的CKD[9:8]=00b,tDTS=ttim_ker_ck;
    //溢出时间为(9999+1)*1*(16+1)/170000000/1=0.01秒

  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.RepetitionCounter = 0;//重复计数(1-0),产生一次中断
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;//TIM_AUTORELOAD_PRELOAD_DISABLE;
    //这里设置“使能重装载”

  HAL_TIM_Base_Init(&htim2);

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig);

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
    //TIM_TRGO_UPDATE是“更新事件用来触发器输出”Update event is used as trigger output (TRGO2)
//  sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
    //TIM1_TRGO2是adc_ext_trg10,用来触发ADC1/2/3/4/5

  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);
    //Configures the TIM in master mode.

/*
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
    //设置NVIC中断分组4:4位抢占优先级,0位响应优先级
    //选择中断优先级组4,即抢占优先级为4位,取值为0~15,响应优先级组为0位,取值为0
    //DMA1_Channel1_IRQn抢占优先级为5,响应优先级为0
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);//使能DMA1_Channel1_IRQn中断
*/

  HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1,(uint32_t*)Sine12bit, 32, DAC_ALIGN_12B_R);
    //启动DMA传输
    HAL_TIM_Base_Start(&htim2);//启动TIM2
}

测试PA4引脚的波形如下:


http://www.kler.cn/news/362741.html

相关文章:

  • [手机Linux PostmarketOS]七, Linux使用selenium爬虫
  • 落实“双碳”行动,深兰科技推动分子能源技术在AI硬件产品领域的应用及产业化进程
  • 推荐一个开源非线性视频编辑器:Kdenlive
  • Node.js是什么? 能做什么?
  • 【python + Redis】hash值查增删
  • Linux文件的查找和打包以及压缩
  • uniapp使用webView打开的网页有缓存如何解决(APP,微信小程序)
  • HarmonyOS鸿蒙分布式文件操作的时候权限问题
  • Rust中的Sync特征:确保多线程间安全共享数据
  • 软件工程--需求分析与用例模型
  • Python包——Matplotlib
  • C++STL之list
  • 探索卷积层参数量与计算量
  • MySQL--基本介绍
  • HBuilder X 中Vue.js基础使用2(三)
  • 基于 Konva 实现Web PPT 编辑器(三)
  • qt生成uuid,转成int。ai回答亲测可以
  • 线性可分支持向量机的原理推导 9-32线性分类超平面的位置 公式解析
  • Dubbo接口解析
  • WordPress多站点子目录模式更换域名的教程方法
  • elementUI进度条el-progress不显示白色
  • 使用预测或实际LTV计算ROI
  • ubuntu22 安装labelimg制作自己的深度学习目标检测数据集
  • 微软大哥,全球第一(交易积累)
  • IDEA 如何导入NC65项目
  • 【贪心算法】(第十一篇)