用户工具

站点工具


icore4t_25

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

后一修订版
前一修订版
icore4t_25 [2020/09/25 15:08]
fmj 创建
icore4t_25 [2022/04/01 10:46] (当前版本)
sean
行 2: 行 2:
 |技术支持电话|**0379-69926675-801**||| |技术支持电话|**0379-69926675-801**|||
 |技术支持邮件|Gingko@vip.163.com||| |技术支持邮件|Gingko@vip.163.com|||
-|技术论坛|http://​www.eeschool.org||| 
 ^  版本 ​ ^  日期 ​ ^  作者 ​ ^  修改内容 ​ ^ ^  版本 ​ ^  日期 ​ ^  作者 ​ ^  修改内容 ​ ^
 |  V1.0  |  2020-09-25 |  gingko ​ |  初次建立 ​ |  |  V1.0  |  2020-09-25 |  gingko ​ |  初次建立 ​ | 
行 62: 行 61:
 \\ \\
 \\ \\
-===== 实验二十DAC实验——输出直流电压 ​=====+===== 实验二十DDS实验——输出正弦波 ​=====
  
 ==== 一、实验目的与意义 ==== ==== 一、实验目的与意义 ====
行 68: 行 67:
   - 了解STM32 DAC结构。   - 了解STM32 DAC结构。
   - 了解STM32 DAC特征。   - 了解STM32 DAC特征。
-  - 掌握DAC的使用方法+  - 掌握DDS原理
   - 掌握STM32 HAL库中DAC属性的配置方法。   - 掌握STM32 HAL库中DAC属性的配置方法。
   - 掌握KEIL MDK 集成开发环境使用方法。   - 掌握KEIL MDK 集成开发环境使用方法。
行 82: 行 81:
 ==== 三、实验原理 ==== ==== 三、实验原理 ====
  
-**1、DAC简介**+=== 1、DAC简介 ​===
   * STM32H750的DAC模块(数字/​模拟转换模块)是12位数字输入,电压输出型的DAC。DAC可以配置为8位或12位模式,也可以与DMA控制器配合使用。DAC工作在12位模式时,数据可以设置成左对齐或右对齐。DAC模块有2个输出通道,每个通道都有单独的转换器。在双DAC模式下,2个通道可以独立地进行转换,也可以同时进行转换并同步地更新2个通道的输出。DAC可以通过引脚输入参考电压Vref+(通ADC共用)以获得更精确的转换结果。   * STM32H750的DAC模块(数字/​模拟转换模块)是12位数字输入,电压输出型的DAC。DAC可以配置为8位或12位模式,也可以与DMA控制器配合使用。DAC工作在12位模式时,数据可以设置成左对齐或右对齐。DAC模块有2个输出通道,每个通道都有单独的转换器。在双DAC模式下,2个通道可以独立地进行转换,也可以同时进行转换并同步地更新2个通道的输出。DAC可以通过引脚输入参考电压Vref+(通ADC共用)以获得更精确的转换结果。
   * STM32H750的DAC模块主要特性:   * STM32H750的DAC模块主要特性:
行 100: 行 99:
  
   * DAC框图:   * DAC框图:
-{{ :icore4t:icore4t_arm_hal_24_1.png?direct |}} +{{ :icore4t:icore4t_arm_hal_25_1.png?direct |}} 
   * DAC 包含:   * DAC 包含:
     * 多达两条输出通道     * 多达两条输出通道
行 119: 行 118:
  
   * 关闭触发 (TEN = 0) 时的转换时序图:​   * 关闭触发 (TEN = 0) 时的转换时序图:​
-{{ :icore4t:icore4t_arm_hal_24_2.png?direct |}} +{{ :icore4t:icore4t_arm_hal_25_2.png?direct |}} 
   * DAC输入/​输出引脚:   * DAC输入/​输出引脚:
-{{ :icore4t:icore4t_arm_hal_24_3.png?direct |}} +{{ :icore4t:icore4t_arm_hal_25_3.png?direct |}} 
   * DAC内部输入/​输出信号:   * DAC内部输入/​输出信号:
-{{ :icore4t:icore4t_arm_hal_24_4.png?direct |}} +{{ :icore4t:icore4t_arm_hal_25_4.png?direct |}} 
 === 2、DAC输出电压公式 === === 2、DAC输出电压公式 ===
  
行 129: 行 128:
   * 各 DAC 通道引脚的模拟输出电压通过以下公式确定: ​   * 各 DAC 通道引脚的模拟输出电压通过以下公式确定: ​
  
-''​**DAC_output= V_REF  ×  DOR/​4096** ​+  * **DAC_output= V_REF  ×  DOR/​4096** ​
  
 === 3、DAC部分寄存器介绍 === === 3、DAC部分寄存器介绍 ===
行 135: 行 134:
   * 我们介绍一下要实现 DAC 的通道 1 输出,需要用到的一些寄存器。首先是 DAC控制寄存器 DAC_CR,该寄存器的各位描述如图所示:   * 我们介绍一下要实现 DAC 的通道 1 输出,需要用到的一些寄存器。首先是 DAC控制寄存器 DAC_CR,该寄存器的各位描述如图所示:
 {{ :​icore4t:​icore4t_arm_hal_24_5.png?​direct |}}  {{ :​icore4t:​icore4t_arm_hal_24_5.png?​direct |}} 
 +
   * DAC_CR 的低 16 位用于控制通道 1,而高 16 位用于控制通道 2,我们这里仅列出比较本章需要设置的一些位:   * DAC_CR 的低 16 位用于控制通道 1,而高 16 位用于控制通道 2,我们这里仅列出比较本章需要设置的一些位:
     * EN1 位:用于 DAC 通道 1 的使能,我们需要用到 DAC 通道 1 的输出,该位必须设置为 1。     * EN1 位:用于 DAC 通道 1 的使能,我们需要用到 DAC 通道 1 的输出,该位必须设置为 1。
行 142: 行 142:
     * DMAEN1 位,用于控制 DAC 通道 1 的 DMA 使能,本章不使能,设置该位为 0 即可。CEN1 位,用于控制 DAC 通道 1 的输出缓冲校准使能,本章不使用校准功能(默认有一个出场校准值,我们使用默认的校准值即可),设置该位为 0 即可。     * DMAEN1 位,用于控制 DAC 通道 1 的 DMA 使能,本章不使能,设置该位为 0 即可。CEN1 位,用于控制 DAC 通道 1 的输出缓冲校准使能,本章不使用校准功能(默认有一个出场校准值,我们使用默认的校准值即可),设置该位为 0 即可。
   * 然后,我们介绍 DAC 模式控制寄存器( DAC1_MCR),该寄存器各位描述如图所示:   * 然后,我们介绍 DAC 模式控制寄存器( DAC1_MCR),该寄存器各位描述如图所示:
-{{ :icore4t:icore4t_arm_hal_24_6.png?direct |}} +{{ :icore4t:icore4t_arm_hal_25_6.png?direct |}}  
     * 位 2:0 MODE1[2:​0]: DAC 通道 1 模式 (DAC Channel 1 mode)     * 位 2:0 MODE1[2:​0]: DAC 通道 1 模式 (DAC Channel 1 mode)
   * 仅当 DAC 已禁止且不处于校准模式时( DACx_CR 寄存器中的位 EN1 = 0 且位 CEN1 = 0),才可写入这些位。如果 EN1=1 或 CEN1 =1,则会忽略写操作。这些位可由软件置 1 和清零,用于选择 DAC 通道 1 模式。   * 仅当 DAC 已禁止且不处于校准模式时( DACx_CR 寄存器中的位 EN1 = 0 且位 CEN1 = 0),才可写入这些位。如果 EN1=1 或 CEN1 =1,则会忽略写操作。这些位可由软件置 1 和清零,用于选择 DAC 通道 1 模式。
行 156: 行 157:
     * 111: DAC 通道 1 连接到片上外设且禁止了缓冲器     * 111: DAC 通道 1 连接到片上外设且禁止了缓冲器
   * **注: 仅可在 EN1 = 0 时修改该寄存器。**   * **注: 仅可在 EN1 = 0 时修改该寄存器。**
-本实验中iCore4T的参考电压为2.5V,我们使用DAC1通道一输出1.2V电压。原理图如下: + 
-{{ :icore4t:icore4t_arm_hal_24_7.png?​direct&​650 |}}  +=== 4、DDS原理 === 
-{{ :icore4t:icore4t_arm_hal_24_8.png?​direct&​700 |}}  +  * 4.1 什么是频率 
-==== 实验程序 ====+    * 频率是指单位时间内某事件重复的次数。在电子学中,信号的频率是指单位时间内信号的周期数,单位是赫兹(Hertz,简称Hz)。很多年前有一个著名的德国物理学家海因里希 · 鲁道夫 · 赫兹,他首先证明了电磁波的存在,为了纪念他,频率的单位就用他的名字命名。频率是一个非常常用、也是一个非常重要的国际单位;日常生活中,我们收听的收音机、观看的电视机、交流市电、移动蜂窝电话等信号的传输过程,都利用了信号的频率特性。频率与信号的周期互为倒数关系,所以频率也可以表示为: 
 +{{ :​icore4t:​icore4t_arm_hal_25_7.jpg?​direct&​650 |}} 
 +  * 4.2 怎么得到任意频率的信号 
 +    * 既然信号的频率特性那么重要,我们怎么样才能得到自己想要的频率的信号呢?一般来说,我们通过下面三种方法得到想要的频率信号。 
 +    * 晶体或者晶体振荡器:晶体振荡器是利用石英晶体的压电效应,来产生我们想要的频率,他有精度高、稳定性强、温漂小等特点。晶体或者晶振是电路中常用的元器件,它能给我们的电路提供稳定的时钟源,但它也有它的局限性,晶体一旦切割完毕,他的固有频率也就固定了,所以晶体或者晶振不适用于要求频率时刻变化的场合。 
 +    * RLC 振荡器:利用RC 振荡或者 LC 振荡的原理,通过改变其中的R、L或者C达到改变振荡频率的目的。这种振荡器电路简单、起振容易,所以也很常用。不过他频率稳定性一般,不适合在频率精度要求较高的场合使用。 
 +    * 频率合成技术:频率合成技术可以理解为我们通过某种方法,对固定的频率进行运算,来完成频率的变换。频率合成方法一般有锁相环(PLL)法和直接数字合成技术。PLL 是一种闭环系统,他通过对输入频率进行倍频、分频等过程,完成频率的变换。这种技术一般用于输出频点不多的场合(例如MCU中频率的倍频过程),它得天独厚的优势是可以产生比输入频率更高的频率。直接数字合成技术为本节讨论的重点,以下内容均讨论直接数字合成技术。 
 +  * 4.3 直接数字合成技术简介 
 +    * 直接数字合成(Direct Digital Synthesizer, DDS)是1971年由J.Tierncy等人提出的,它通过基于相位累加的变换方式,对输入频率进行变换,来达到任意频率输出的目的。它具有输出频率稳定、分辨率高、切换速度快等优点,配合波形查找表及相关路,它能产生任意的波形,这也是它最大的优势。 
 +  * 4.4 DDS原理 
 +    * 一个典型的DDS系统包括相位累加器、幅度变换及DA转换电路。它基于同一个系统时钟驱动的。在某一个时钟时刻,相位累加器产生一个特定的相位角度,通过相位角度-幅度变换,查找到波形表中电压值,然后送给DAC,来重现这一时刻的模拟电压,这就完成了DDS工作的一个步进。通过不断的时钟驱动,我们就能得到连续的模拟波形。 
 +{{ :​icore4t:​icore4t_arm_hal_25_8.png?​direct&​700 |}}  
 +    * 4.4.1 相位累加器 
 +      * 相位累加器(ACCUMULATOR)是DDS的核心,它由一个加法器和一个D触发器组成。相位累加器由多位组成,典型的应用中,一般取 16~48位。相位累加器工作过程中,时钟每动作一次,累加器便累加一次调谐字(TUNING WORD);所以相位累加器输出一个以时间为序列的数字字,它线性增长,直到达到最大值2n(假设该累加器为n位),如果大于最大值,则舍弃溢出的高位,仍然保留n位。 
 +      * 为了形象的描述相位累加器的工作过程,我们可以把相位累加器看做一个圆周,如图三所示。其中,n表示相位累加器的位数,2n为相位累加器的模数,也就是圆周等分点数,每次的步进值为调谐字(TUNING WORD)。如果把相位累加器旋转一周作为一个周期的话,则最终频率输出可以用方程式(2)来描述。 
 +{{ :​icore4t:​icore4t_arm_hal_25_9.jpg?​direct&​600 |}} 
 +      * 如果把调谐字(TUNING WORD)设置为最小值1,带入方程式(2)则可得到最小输出频率,也就是频率分辨率。通过公式(3)我们可以看出,相位累加器位数越高,则频率分辨率越高。在100MHz的采样时钟下,48位的相位累加器可以使得频率分辨率优于 1μHz。 
 +{{ :​icore4t:​icore4t_arm_hal_25_10.png?​direct&​700 |}}  
 +    * 4.4.2 角度-幅度转换 
 +      * 相位累加器的输出为线性的,如果我们需要输出任意的波形,我们则需要角度-幅度转换。一般地可以通过查找表的方法来实现。相位累加器的输出作为查找表的地址,数据线作为内容输出,则完成了角度-幅度转换。图四示意图为单周期正弦波查找表,n位的相位累加器输出(线性变化)作为查找表的地址线,数据输出端则为按正弦规律变化的数字序列。 
 +{{ :​icore4t:​icore4t_arm_hal_25_11.png?​direct&​700 |}}  
 +    * 4.4.3、D/A 转换 
 +      * 相位累加器的输出经过波形查找表后,得到按预置波形变化的数字序列,还需要进行数字-模拟转换,才能得到我们需要的模拟波形,这个过程为 D/​A转换,如图五所示。DAC 的驱动时钟与相位累加器的时钟同源,所以保证DDS 每个模块工作“步调”一致。 
 +{{ :​icore4t:​icore4t_arm_hal_25_12.png?​direct&​700 |}}  
 +  * 本实验中iCore4T的参考电压为2.5V,我们使用DAC1通道一作为DA输出,通过频率字控制输出频率为1KHz正弦波。原理图如下: 
 +{{ :icore4t:icore4t_arm_hal_25_13.png?​direct&​500 |}}  
 +{{ :icore4t:icore4t_arm_hal_25_14.png?​direct&​500 |}}  
 +==== 四、实验程序 ====
 === 1、主函数 === === 1、主函数 ===
 <code c> <code c>
行 167: 行 195:
   SystemClock_Config();​   SystemClock_Config();​
  
-    ​i2c.initialize();​ +  ​i2c.initialize();​ 
-    axp152.initialize();​ +  axp152.initialize();​ 
-    axp152.set_dcdc1(3500);//​[ARM & FPGA BK1/2/6 &​OTHER] +  axp152.set_dcdc1(3500);//​[ARM & FPGA BK1/2/6 &​OTHER] 
-    axp152.set_dcdc2(1200);//​[FPGA INT & PLL D] +  axp152.set_dcdc2(1200);//​[FPGA INT & PLL D] 
-    axp152.set_aldo1(2500);//​[FPGA PLL A] +  axp152.set_aldo1(2500);//​[FPGA PLL A] 
-    axp152.set_dcdc4(3300);//​[POWER_OUTPUT]+  axp152.set_dcdc4(3300);//​[POWER_OUTPUT]
     ​     ​
-    ​axp152.set_dcdc3(3300);//​[FPGA BK4][Adjustable] +  ​axp152.set_dcdc3(3300);//​[FPGA BK4][Adjustable] 
-    axp152.set_aldo2(3300);//​[FPGA BK3][Adjustable] +  axp152.set_aldo2(3300);//​[FPGA BK3][Adjustable] 
-    axp152.set_dldo1(3300);//​[FPGA BK7][Adjustable] +  axp152.set_dldo1(3300);//​[FPGA BK7][Adjustable] 
-    axp152.set_dldo2(3300);//​[FPGA BK5][Adjustable]+  axp152.set_dldo2(3300);//​[FPGA BK5][Adjustable]
  
   MX_GPIO_Init();​   MX_GPIO_Init();​
   MX_DAC1_Init();​   MX_DAC1_Init();​
-    ​LED_ON; +  MX_SDMMC1_SD_Init();​ 
-    dac1.set_voltage(1.2);//输出1.2V电压 +  MX_TIM3_Init();​ 
-  while (1) +  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) 
 +  
 +   }
 } }
 +
  
 </​code>  ​ </​code>  ​
-=== 2、输出电压函数 === +=== 2、HAL_DAC_SetValue函数 ===
-  * 通过求出对应的DAC值,写入DOR寄存器使DAC1通道一输出要求的电压值。 +
-<code c> +
-void set_voltage(double voltage) +
-{    +
-    unsigned short int temp; +
-    temp = voltage * 4095 / 2.5; //​求出所设电压对应DOR寄存器的值 +
-    HAL_DAC_SetValue(&​hdac1,​ DAC_CHANNEL_1,​ DAC_ALIGN_12B_R,​ temp);//12 位右对齐数据格式设置 DAC 值  +
-    HAL_DAC_Start(&​hdac1,​ DAC_CHANNEL_1);​ //​输出要求电压 +
-+
-</​code>​  +
-=== 3、HAL_DAC_SetValue函数 ===+
 <code c> <code c>
 HAL_DAC_SetValue(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data) HAL_DAC_SetValue(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data)
行 210: 行 257:
  
 </​code> ​ </​code> ​
-=== 4、DAC初始化函数 ===+=== 3、DAC初始化函数 ===
 <code c> <code c>
 void MX_DAC1_Init(void) void MX_DAC1_Init(void)
行 230: 行 277:
   }   }
 } }
 +
  
 </​code> ​ </​code> ​
-==== 实验步骤 ====+ 
 +==== 五、实验步骤 ====
   - 把仿真器与iCore4T的SWD调试口相连(直接相连或者通过转接器相连);   - 把仿真器与iCore4T的SWD调试口相连(直接相连或者通过转接器相连);
-  - iCore4T通过Micro USB线计算机相连,为iCore4T供电;+  - iCore4T与扩展底板相连,为扩展板供电;
   - 打开Keil MDK 开发环境,并打开本实验工程;   - 打开Keil MDK 开发环境,并打开本实验工程;
   - 烧写程序到iCore4T上;   - 烧写程序到iCore4T上;
   - 也可以进入Debug 模式,单步运行或设置断点验证程序逻辑。   - 也可以进入Debug 模式,单步运行或设置断点验证程序逻辑。
-==== 实验现象 ==== +==== 六、实验现象 ==== 
-  * 用电压表测量iCore4T底板的ARM IO扩展的DAC口有1.2V电压输出+  * 用示波器测量iCore4T底板的DAC引脚可以看到2Vpp 1KHz的正弦波,如下图 
 +{{ :​icore4t:​icore4t_arm_hal_25_15.jpg?​direct&​600 |}}
  
icore4t_25.1601017688.txt.gz · 最后更改: 2020/09/25 15:08 由 fmj