目录

银杏科技有限公司旗下技术文档发布平台
技术支持电话0379-69926675-801
技术支持邮件Gingko@vip.163.com
版本 日期 作者 修改内容
V1.0 2020-11-18 gingko 初次建立

STM32CubeMX教程十二——DDS输出正弦波

1.在主界面选择File–>New Project 或者直接点击ACCEE TO MCU SELECTOR 2.出现芯片型号选择,搜索自己芯片的型号,双击型号,或者点击Start Project进入配置在搜索栏的下面,提供的各种查找方式,可以选择芯片内核,型号等等,可以帮助你查找芯片。本实验选取的芯片型号为:STM32F429IGHx。 3.配置RCC,使用外部时钟源 4. 调试选择Serial Wire,时基源选择SysTick 5.将PI3,PI4,PH14设置为GPIO_Output 引脚模式配置 6.配置DAC 7.配置定时器 定时器中断使能 8.配置SD卡 SD卡引脚配置 9.配置Middleware(中间件),即fatfs 10.时钟源设置,选择外部高速时钟源,配置为最大主频 11.工程文件的设置, 这里就是工程的各种配置 我们只用到有限几个,其他的默认即可IDE我们使用的是MDK V5.27 12.点击Code Generator,进行进一步配置

13.然后点击GENERATE CODE创建工程 创建成功,打开工程。



实验十二:DDS实验——输出正弦波

一、实验目的与意义

  1. 了解STM32 DAC结构
  2. 了解STM32 DAC特征
  3. 掌握DDS原理
  4. 掌握STM32 HAL库中DAC属性的配置方法
  5. 掌握KEIL MDK 集成开发环境使用方法

二、实验设备及平台

  1. iCore3L 双核心板
  2. JLINK(或相同功能)仿真器
  3. Micro USB线缆
  4. Keil MDK 开发平台
  5. STM32CubeMX开发平台
  6. 装有WIN XP(及更高版本)系统的计算机

三、实验原理

1.DAC简介

STM32F429IGH6的DAC模块主要特性:

DAC框图: DAC 包含:

从图中可以看出,DAC输出是受DORx(x=1/2,下同)寄存器直接控制的,但是我们不能直接往DORx寄存器写入数据,而是通过DHRx间接的传给DORx寄存器,实现对DAC输出的控制。前面我们提到,STM32F429IGH6的DAC支持8/12位模式,8位模式的时候是固定的右对齐的,而12位模式又可以设置左对齐/右对齐。单DAC通道x,总共有3种情况:

  1. 8位数据右对齐:用户将数据写入DAC_DHR8Rx[7:0]位(实际存入DHRx[11:4]位)。
  2. 12位数据左对齐:用户将数据写入DAC_DHR12Lx[15:4]位(实际存入DHRx[11:0]位)。
  3. 12位数据右对齐:用户将数据写入DAC_DHR12Rx[11:0]位(实际存入DHRx[11:0]位)。

关闭触发 (TEN = 0) 时的转换时序图: DAC输入/输出引脚: DAC内部输入/输出信号:

2.DAC输出电压公式

3.DAC部分寄存器介绍

4、DDS原理

4.1 什么是频率

频率是指单位时间内某事件重复的次数。在电子学中,信号的频率是指单位时间内信号的周期数,单位是赫兹(Hertz,简称Hz)。很多年前有一个著名的德国物理学家海因里希· 鲁道夫·赫兹,他首先证明了电磁波的存在,为了纪念他,频率的单位就用他的名字命名。频率是一个非常常用、也是一个非常重要的国际单位;日常生活中,我们收听的收音机、观看的电视机、交流市电、移动蜂窝电话等信号的传输过程,都利用了信号的频率特性。频率与信号的周期互为倒数关系,所以频率也可以表示为:

4.2 怎么得到任意频率的信号
4.3 直接数字合成技术简介
4.4 DDS原理

4.4.1 相位累加器

4.4.2 角度-幅度转换

4.4.3 D/A 转换

四、实验程序

1.主函数

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_DAC1_Init();
  MX_SDMMC1_SD_Init();
  MX_TIM3_Init();
  MX_FATFS_Init();
  res = f_mount(&fatfs,"0:",1); 
  if(res != RES_OK)    
  {
    while(1)
    {
      LED_ON;
      HAL_Delay(300);
      LED_OFF;
      HAL_Delay(300);
    }
  }
  wave.waveform(WAVE_SINE,0);
  wave.set_frequency(1000);
  //计算频率为1K的波表数据
  i = 0;
  while(1)
  {
    wave.accumulator = wave.accumulator + wave.fword;
    if(wave.accumulator > 4294967295)break;
    temp = wave.accumulator >> 18;
    f = wave.buffer[temp];
    g = f / 16384.0;
    g = g * 2.0 +0.05;
    g = g * 4096 / 2.5;
    wave.buffer[i ++]  = g;
  }
  counter = i - 1;
  HAL_TIM_Base_Start_IT(&htim3);
  HAL_DAC_Start(&hdac1, DAC_CHANNEL_1);
  LED_ON;
  while (1)
  {
  }
}

2.set_frequency函数

static int set_frequency(int freq)
{
  //32位相位累加器 400K 采样率
  wave.accumulator = 0;
  wave.fword = (int)(freq * 4294.967296 * 2.5);
  return 0;
}

3.HAL_DAC_SetValue函数

HAL_DAC_SetValue(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data)
//hdac:指向DAC_HandleTypeDef结构的指针
//Channel:选定DAC通道
//Alignment:数据对方方式
//Data:放入寄存器中的值

4.DAC初始化函数

void MX_DAC1_Init(void)
{
  DAC_ChannelConfTypeDef sConfig = {0};
  hdac1.Instance = DAC1;
  if (HAL_DAC_Init(&hdac1) != HAL_OK)
  {
    Error_Handler();
  }
  sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;//关闭
  sConfig.DAC_Trigger = DAC_TRIGGER_NONE;//关闭DAC触发
  sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;//使用输出缓存,提高驱动力
  sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_DISABLE;//关闭DAC芯片连接
  sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;//缓冲器偏移校准采用出厂修整
  if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
}

五、实验步骤

  1. 把仿真器与iCore3L的SWD调试口相连(直接相连或者通过转接器相连);
  2. 将iCore3L与扩展底板相连,为扩展板供电;
  3. 打开Keil MDK 开发环境,并打开本实验工程;
  4. 烧写程序到iCore3L上;
  5. 也可以进入Debug 模式,单步运行或设置断点验证程序逻辑。

六、实验现象

用示波器测量iCore3L底板的DAC引脚(PA4)可以看到2Vpp 1KHz的正弦波,如下图。