文章目录

  • 前言
  • 一、干扰电简介
    • 1.适应症
    • 2.禁忌症
    • 3.操作
    • 4.用法举例1
    • 5.用法举例2
    • 6.注意事项
    • 7.原理
  • 二、知识梳理
    • 1.设备原理
    • 2.DAC简介
    • (1)框图
    • (2)DAC的功能
    • (3)STM32的DAC特点
    • (4)参考电压
    • (5)数模转换及输出通道
    • (6)触发源及 DHRx 寄存器
    • 3.DAC 初始化结构体
    • (1)结构体DAC_InitTypeDef
    • (2)成员DAC_Trigger
    • (3)成员DAC_WaveGeneration
    • (4)成员DAC_LFSRUnmask_TriangleAmplitude
    • (5)成员DAC_OutputBuffer
    • 4.DAC 输出正弦波实验
    • (1)方法
    • (2)编程要点
    • (3)正弦波与寄存器的关系
    • (4)输出的转换
    • (5)通过python制作正弦波数据表
    • (6)下位机程序的编写
    • ①创建dac.h,设置好相关的宏定义,添加如下代码
    • ②创建dac.c,添加如下代码完成DAC GPIO 和模式配置
    • ③定时器配置及计算正弦波的频率
    • ④DMA配置
    • ⑤主函数的编写
    • ⑥验证
  • 源代码分享链接

前言

近期准备升级干扰电治疗仪,对于前期的准备工作做一个简单的汇总和梳理,文章中可能会有不正确的说法,仅供参考。

一、干扰电简介

1.适应症

干扰电疗法适用于神经炎、神经痛、神经根炎、肌萎缩、扭伤、肩周炎、肌纤维鞘炎、肌劳损、关节炎、雷诺病、手足发绀症、胃下垂、习惯性便秘等。

2.禁忌症

急性化脓性炎症,有出血倾向,局部有金属固定物,体内植入心脏起搏器者。

3.操作

将选好之两组电极妥善固定于治疗部位,并使两组电流交叉在病灶处。治疗电极有衬垫电极、手套电极及抽吸电极3种,可按医嘱选用。

4.用法举例1

腰骶神经根炎治疗法 将一组面积为30~50cm衬垫电极分别置于左下及右上腰骶部,另一组同等面积电极分别置于右下及左上腰骶部。定频输出90Hz,变频输出90~100Hz,各治疗10min,1/d。

5.用法举例2

胃下垂治疗法 将一组面积为 100cm电极分别置于左腹及右腰部,另一组同等面积衬垫电极置于右腹及左腰部。定频输出1~5Hz,变频输出40—100Hz,各10min,1/d。

6.注意事项

①两组电极不得互相接触,衬垫应湿透并紧密接触皮肤。衬垫勿置于皮肤破损处。
②电流不可穿过心脏、脑、孕妇下腹部。
③有金属异物的局部,不可进行此种疗法。

7.原理

①是频率为4000±100Hz的正弦电流。治疗时用四个电极,将两路频率相差100Hz的中频率交流电(一路频率固定4000Hz,另一路为4000±100Hz,其频率可每15秒变动一次,变动范围可调)交叉地输入人体,在机体深部产生一个差频电流。
②在电极下输入时是中频,交叉干扰后就将得0~100Hz的低频,这种低频不是外界输入,而是内部产生的,且还含有中频的成份。这种深处“内生”的低频调制的脉冲频电刺激克服了低频电流不能深入组织内部的缺陷,且可应用较大的电流强度。这是干扰电疗法最突出的特点,所以它兼有中频和低频电疗的特点。
③仪器工作过程中无化学反应(无电解作用),电极可简化,操作较简便。

二、知识梳理

1.设备原理

通过百度可以发现干扰电疗法的主要原理为驱动mcu产生正弦波,推测主要运用DAC功能,在这个基础上增加人机交互,如参数的显示、调整。由于博主主要负责嵌入式软件,目前阶段在此主要记录DAC的软件相关知识点。

2.DAC简介

(1)框图

(2)DAC的功能

DAC 为数字/模拟转换模块,故名思议,它的作用就是把输入的数字编码,转换成对应的模拟电压输出,它的功能与 ADC 相反。在常见的数字信号系统中,大部分传感器信号被化成电压信号,而 ADC 把电压模拟信号转换成易于计算机存储、处理的数字编码, 由计算机处理完成后,再由 DAC 输出电压模拟信号,该电压模拟信号常常用来驱动某些 执行器件,使人类易于感知。如音频信号的采集及还原就是这样一个过程。

(3)STM32的DAC特点

STM32 具有片上 DAC 外设,它的分辨率可配置为 8 位或 12 位的数字输入信号,具有 两个 DAC 输出通道,这两个通道互不影响,每个通道都可以使用 DMA 功能,都具有出错检测能力,可外部触发。

(4)参考电压

与 ADC 外设类似,DAC 也使用 VREF+引脚作为参考电压,在设计原理图的时候一般把 VSSA接地,把 VREF+和 VDDA 接 3.3V,可得到 DAC 的输出电压范围为:0~3.3V。
如果想让输出的电压范围变宽,可以在外部加一个电压调理电路,把 0~3.3V 的 DAC 输出抬升到特定的范围即可

(5)数模转换及输出通道

框图中的数字至模拟转换器 x是核心部件,整个 DAC 外设都围绕它而展开。它以左边的 VREF+作为参考电源,以 DAC 的数据寄存器“DORx”的数字编码作为输入,经过它转换得的模拟信号由右侧的“DAC_OUTx”通道输出。其中各个部件中的x是指设备的标号,在 STM32 中具有 2 个这样的 DAC 部件,每个DAC有1个对应的输出通道连接到特定的引脚,即:PA4-通道 1,PA5-通道 2,为避免干扰,使用 DAC 功能时,DAC 通道引脚需要被配置成模拟输入功能(AIN)。

(6)触发源及 DHRx 寄存器

在使用 DAC 时,不能直接对上述 DORx 寄存器写入数据,任何输出到 DAC 通道 x 的数据都必须写入到 DHRx 寄存器中(其中包含 DHR8Rx、DHR12Lx 等,根据数据对齐方向和分辨率的情况写入到对应的寄存器中)。也就是说我们准备好的正弦波数组要填入这个寄存器当中。
数据被写入到 DHRx 寄存器后,DAC 会根据触发配置进行处理,若使用硬件触发,则 DHRx 中的数据会在 3 个 APB1 时钟周期后传输至 DORx,DORx 随之输出相应的模拟电压到输出通道;若 DAC 设置为外部事件触发,可以使用定时器(TIMx_TRGO)、EXTI_9 信号或软件触发(SWTRIGx)这几种方式控制数据 DAC 转换的时机,例如使用定时器触 发,配合不同时刻的 DHRx 数据,就可以实现 DAC 输出正弦波的功能。

3.DAC 初始化结构体

(1)结构体DAC_InitTypeDef

DAC 相关的各种配置封装到了结构体 DAC_InitTypeDef 中, 它主要包含了 DAC_CR 控制寄存器的各寄存器位的配置。

1)typedef struct
2){3)  /*DAC 触发方式 */
4)  uint32_t DAC_Trigger;
5)  /*是否自动输出噪声或三角波 */
6)  uint32_t DAC_WaveGeneration;
7)  /*选择噪声生成器的低通滤波或三角波的幅值 */
8)  uint32_t DAC_LFSRUnmask_TriangleAmplitude;
9)  /*选择是否使能输出缓冲器 */
10) uint32_t DAC_OutputBuffer;
11)}DAC_InitTypeDef;

(2)成员DAC_Trigger

本成员用于配置 DAC 的触发模式,当 DAC 产生相应的触发事件时,才会把 DHRx 寄 存器的值转移到 DORx 寄存器中进行转换。本结构体成员可以选择的触发模式如下:
1.硬件触发(DAC_Trigger_None),DHRx 寄存器内的数据会在 3 个 APB1 时钟周期内自动转换到DORx 进 行 转 换 ;
2.定时器触发模式(DAC_Trigger_T2/4/5/6/7_TRGO),使用定时器 2、4、5、6、7 控制 DHRx 寄存器的数据按时间转移到 DORx 中进行转换,利用这种方式可以输出特定的波形;
3.EXTI_9 触发方式(DAC_Trigger_Ext_IT9),当产生 EXTI_9 事件时(如 GPIO 中断事件), 触发转换 ;
4.软件 触发模式( DAC_Trigger_Software ),在本模式下, 向 DAC_SWTRIGR 寄存器写入配置即可触发信号进行转换。

(3)成员DAC_WaveGeneration

本成员用于设置是否使用 DAC 输出伪噪声或三角波(DAC_WaveGeneration_None/Noise/Triangle),使用伪噪声和三角波输出时,DAC 都会把 LFSR 寄存器的值叠加到 DHRx 数值上,产生伪噪声和三角波,若希望产生自定义的输出时,直接配置为 DAC_WaveGeneration_None 即可。

(4)成员DAC_LFSRUnmask_TriangleAmplitude

本成员通过控制 DAC_CR 的 MAMP2 位设置 LFSR 寄存器位的数据,即当使用伪噪声或三角波输出时要叠加到 DHRx 的值,非噪声和非三角波输出模式下,本配置无效。使用伪噪声输出时LFSR=0xAAA,MAMP2 寄存器位可以屏蔽 LFSR 的某些位,这时把本结构体成员赋值为DAC_LFSRUnmask_Bit0~DAC_LFSRUnmask_Bit11_0 等宏即可; 使用三角波输出时, 本结构体设置三角波的最大幅值 , 可选择为 DAC_TriangleAmplitude_1~ DAC_TriangleAmplitude_4096 等宏,DAC 在 DHRx 值的基础上升,幅值达到 MAMPx 设置的最大幅度时下降,形成三角波的输出。

(5)成员DAC_OutputBuffer

本结构体成员用于控制是否使能 DAC 的输出缓冲 (DAC_OutputBuffer_Enable/Disable),使能了 DAC 的输出缓冲后可以减小输出阻抗, 适合直接驱动一些外部负载。

4.DAC 输出正弦波实验

(1)方法

DAC 配合 TIM 定时器,可以输出随时间变化的电压如正弦波。

(2)编程要点

1)计算获取正弦波数据表;
2)根据正弦波数据表的周期内点数和周期计算定时器触发间隔;
3)初始化 DAC 输出通道,初始化 DAC 工作模式;
4)配置触发 DAC 用的定时器;
5)配置 DMA 自动转运正弦波数据表。

(3)正弦波与寄存器的关系

要输出正弦波,实质是要控制 DAC 以 v=sin(t) 的正弦函数关系输出电压,其中 v 为电压输出,t 为时间。而由于模拟信号连续而数字信号是离散的,所以使用 DAC 产生正弦波时,只能按一定时间间隔输出正弦曲线上的点,在该时间段内输出相同的电压值,若缩短时间间隔,提高单个周期内的输出点数,可以得到逼近连续正弦波的图形,若在外部电路加上适当的电容滤波,可得到更完美的图形。
上图为32个点,下图为128个点。


由于正弦曲线是周期函数,所以只需要得到单个周期内的数据后按周期重复即可,而单个周期内取样输出的点数又是有限的,所以为了得到呈 v=sin(t) 函数关系电压值的数据通常不会实时计算获取,而是预先计算好函数单个周期内的电压数据表,并且转化成以 DAC 寄存器表示的值。

(4)输出的转换

如图 sin 函数值的范围为[-1: +1],而 STM32 的 DAC 输出电压范围为[0~3.3]V,按12位 DAC 分辨率表示的方法,可写入寄存器的最大值为 2^12 = 4096,即范围为[0:4096]。所以实际输出时,会进行如下处理:

a.抬升 sin 函数的输出为正值:v = sin(t)+1 ,此时,v 的输出范围为[0:2];

b.扩展输出至 DAC 的全电压范围: v = 3.3*(sin(t)+1)/2 ,此时,v 的输出范围为[0:3.3], 正是 DAC 的电压输出范围,扩展至全电压范围可以充分利用 DAC 的分辨率;

c.把电压值以 DAC 寄存器的形式表示:Reg_val = 2^12/3.3 * v = 2^11*(sin(t)+1),此时,存储到 DAC 寄存器的值范围为[0:4096];

d.在 sin(t)的单个周期内,取 32 个点进行电压输出已经能较好地还原正弦波 形,所以在 t∈[0:2π]区间内等间距根据上述 Reg_val 公式运算得到 32 个寄存器值, 即可得到正弦波表;

e.控制 DAC 输出时,每隔一段相同的时间从上述正弦波表中取出一个新数据进行输出, 即可输出正弦波。改变间隔时间的单位长度,可以改变正弦波曲线的周期。

(5)通过python制作正弦波数据表

我使用的python3.7,因为需要显示图像和计算,还需要安装两个外部库
1)安装matplotlib库
a.Win+R输入cmd进入到CMD窗口下,执行python-m pip install -U pip setuptools进行升级。

b.输入python -m pip install matplotlib进行自动的安装,系统会自动下载安装包(因为网络问题可能会报错,多试几次即可)

c.进入到python idle中,运行import matplotlib,如果没有报错,就证明安装完成。

2)安装numpy库
a.Win+R输入cmd进入到CMD窗口下,执行pip3 install numpy scipy matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple

b.进入到python idle中,运行from numpy import *,再运行eye(4),出现如下结果就证明安装成功。

3)运行程序获取正弦波数据表

"""
运行结果:
命令行中会打印计算得的各点数据,
在当前目录下会生成py_dac_sinWav.c文件,包含上述数据,
并且会弹出描绘曲线的对话框。
"""import matplotlib.pyplot as plt
import numpy as np
import math#修改本变量可以更改点数,如16、32、64等
POINT_NUM = 32pi = math.pi#一个周期 POINT_NUM 个点,n是周期内x轴点的集合
n = np.linspace(0,2*pi,POINT_NUM)#计算POINT_NUM个点的正弦值,a是周期内y轴点的集合
a = map(math.sin,n)r =[]
#对y进行转换
for i in a:#调整幅值至在0~2区间i+=1       #按3.3V电压调整幅值i*= 3.3/2   #求取dac数值,12位dac LSB = 3.3V/2**12 ri = round(i*2**12/3.3) #检查参数if ri >= 4095:ri = 4095#得到dac数值序列r.append( ri )print(list(map(int,r)))#写入序列到文件
with open("py_dac_sinWav.c",'w',encoding= 'gb2312') as f:print(list(map(int,r)),file= f)#绘图
plt.plot(n,r,"-o")
plt.show()

a.Python 脚本的实现原理就是前面介绍的正弦波数据表的制作过程,运行后,该脚本把 得到的正弦波表数据输出到目录下的 py_dac_sinWav.c 文件中

b.代码生成的正弦波数据表
[2048, 2460, 2856, 3218, 3532, 3786, 3969, 4072, 4093, 4031, 3887, 3668, 3382, 3042, 2661, 2255, 1841, 1435, 1054, 714, 428, 209, 65, 3, 24, 127, 310, 564, 878, 1240, 1636, 2048]

c.代码描绘的曲线图

(6)下位机程序的编写

①创建dac.h,设置好相关的宏定义,添加如下代码

//DAC DHR12RD寄存器,12位、右对齐、双通道
#define DAC_DHR12RD_ADDRESS      (DAC_BASE+0x20)

此处定义的宏 DAC_DHR12RD_ ADDRESS 是寄存器 DHR12RD 的地址,该寄存器是 12 位右对齐的双通道寄存器,在本实验中将会使用 DMA 把正弦波数据表的点数据赋值到该寄存器中,往该寄存器赋值后的数据会在 DAC 被触发的时候搬运到 2 个 DAC 转换器,然后在这 2 个通道中输出,以 12 位右对齐的数据表示的这两个通道的电压。与 DAC 控制相关的引脚固定是 PA4 和 PA5,就不使用宏定义了,在代码中直接使用引脚号操作。

②创建dac.c,添加如下代码完成DAC GPIO 和模式配置

static void DAC_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;DAC_InitTypeDef  DAC_InitStructure;/* 使能GPIOA时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    /* 使能DAC时钟 */   RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);/* DAC的GPIO配置,模拟输入 */GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4 | GPIO_Pin_5;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOA, &GPIO_InitStructure);/* 配置DAC 通道1 */DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO;                     //使用TIM2作为触发源DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;   //不使用波形发生器DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;   //不使用DAC输出缓冲DAC_Init(DAC_Channel_1, &DAC_InitStructure);/* 配置DAC 通道2 */DAC_Init(DAC_Channel_2, &DAC_InitStructure);/* 使能通道1 由PA4输出 */DAC_Cmd(DAC_Channel_1, ENABLE);/* 使能通道2 由PA5输出 */DAC_Cmd(DAC_Channel_2, ENABLE);/* 使能DAC的DMA请求 */DAC_DMACmd(DAC_Channel_2, ENABLE);
}

在 DAC_Config 函数中,完成了 DAC 通道的 GPIO 的初始化和 DAC 模式配置。其中 GPIO 按照要求被配置为模拟输入模式(没有模拟输出模式),在该模式下才能正常输出模拟信号。

配置 DAC 工作模式时,则使用了 DAC_InitTypeDef 类型的初始化结构体,把 DAC 通 道 1 和 2 都配置成了使用定时器 TIM2 触发、不使用波形发生器以及不使用 DAC 输出缓冲的模式。

初始化完 GPIO 和 DAC 模式后,还使用了 DAC_Cmd、DAC_DMACmd 函数使能了通道以及 DMA 的请求。由于本实验中对 DAC1 和 2 的操作是同步的,所以只要把 DMA 与 DAC 通道 2 关联起来即可,当使用 DMA 设置通道 2 的数据值时,同时更新通道 1 的内容(DHR12RD寄存器是32位的。给通道2赋值32位的数据,高16位就是通道1的数据)。

③定时器配置及计算正弦波的频率

初始化完 DAC 后,需要配置触发用的定时器,设定每次触发的间隔,以达到控制正 弦波周期的目的。
添加定时器的配置代码

static void DAC_TIM_Config(void)
{TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;/* 使能TIM2时钟,TIM2CLK 为72M */RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);/* TIM2基本定时器配置 */// TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = (562-1);                                        //定时周期 140  TIM_TimeBaseStructure.TIM_Prescaler = 0x0;                                 //预分频,不分频 72M / (0+1) = 72MTIM_TimeBaseStructure.TIM_ClockDivision = 0x0;                         //时钟分频系数TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;    //向上计数模式TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);/* 配置TIM2触发源 */TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);/* 使能TIM2 */TIM_Cmd(TIM2, ENABLE);}

因为前面的 DAC 配置了 TIM2 当触发源,所以这里将对 TIM2 进行配置。TIM2 的定时周期被配置为 562,向上计数,不分频。即 TIM2 每隔 562*(1/72M)秒就会触发一次 DAC 事件,作 DAC 触发源使用的定时器并不需要设置中断,当定时器计数器向上计数至指定的值时,产生 Update 事件,同时触发 DAC 把 DHRx 寄存器的数据转移到 DORx,从而开始进行转换。

根据定时器的配置,可推算出正弦波频率的计算方式:
a.STM32 系统时钟周期为1/72000000 (72m)

b.预分频系数选择不分频,定时器2的单个时钟周期依然为1/72000000

c.定时器2的定时周期配置为562,则触发周期为562/72000000

d.根据正弦波单个周期的点数32,求出正弦波单个周期为32*562/72000000

e.正弦波的频率为72000000/562/32=4003.5587,约等于4000,是干扰电疗法所用到4000±100hz频率。

④DMA配置

实验的数据使用DMA搬运,尽量减少对mcu时间的占用,添加DMA配置代码

//正弦波单个周期的点数
#define POINT_NUM 32/* 波形数据 ---------------------------------------------------------*/
const uint16_t Sine12bit[POINT_NUM] = {2048    , 2460  , 2856  , 3218  , 3532  , 3786  , 3969  , 4072  ,4093   , 4031  , 3887  , 3668  , 3382  , 3042  ,   2661    , 2255  , 1841  , 1435  , 1054  , 714       , 428       , 209       , 65        , 3         ,24     , 127       , 310       , 564       , 878       , 1240  , 1636  , 2048
};uint32_t DualSine12bit[POINT_NUM];static void DAC_DMA_Config(void)
{   DMA_InitTypeDef  DMA_InitStructure;/* 使能DMA2时钟 */RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);/* 配置DMA2 */DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12RD_ADDRESS;                 //外设数据地址DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&DualSine12bit ;              //内存数据地址 DualSine12bitDMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;                                           //数据传输方向内存至外设DMA_InitStructure.DMA_BufferSize = POINT_NUM;                                                                 //缓存大小为POINT_NUM字节  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;               //外设数据地址固定  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                    //内存数据地址自增DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;  //外设数据以字为单位DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;                 //内存数据以字为单位 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                                                    //循环模式DMA_InitStructure.DMA_Priority = DMA_Priority_High;                                          //高DMA通道优先级DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                                        //非内存至内存模式  DMA_Init(DMA2_Channel4, &DMA_InitStructure);/* 使能DMA2-14通道 */DMA_Cmd(DMA2_Channel4, ENABLE);
}void DAC_Mode_Init(void)
{uint32_t Idx = 0;  DAC_Config();DAC_TIM_Config(); /* 填充正弦波形数据,双通道右对齐*/for (Idx = 0; Idx < POINT_NUM; Idx++){DualSine12bit[Idx] = (Sine12bit[Idx] << 16) + (Sine12bit[Idx]);}DAC_DMA_Config();
}

在上述代码中 , 定义了由脚本得到的正弦波数据表 Sine12bit 变量 , 一共为 POINT_NUM(32)个点。在 DAC_Mode_Init 函数中,调用了前面介绍的 DAC_Config 和 DAC_TIM_Config 初始化 DAC 和定时器,然后在 for 循环中把单通道的正弦波数据表 Sine12bit 复制扩展成为双通道的DualSine12bit,扩展后的数据将会直接被 DMA 搬运 至 DAC 的 DHR12RD 寄存器中。 [27:16]是通道2的数据,[11:0]是通道1的数据,数组DualSine12bit的每个数据,高16位给通道2,低16位给通道1。

复制完数据后,DAC_Mode_Init 调用下面的 DAC_DMA_Config 函数初始化 DMA,配置的重点是要设置好 DHR12RD 寄存器的地址,正弦波数据的内存地址(注意是双通道数 据 DualSine12bit),DMA 缓存的个数(即单个周期的正弦波点数)以及 DMA 工作在循环模式。

经过这样的配置后,定时器每间隔一定的时间就会触发 DMA 搬运双通道正弦波表的一个数据到 DAC 双通道寄存器进行转换,每完成一个周期后 DMA 重新开始循环,从而达到连续输出波形的目的。

⑤主函数的编写

int main(void)
{/*初始化DAC,开始DAC转换*/DAC_Mode_Init();while(1);
}

主函数调用 DAC_Mode_Init完成所有的初始化后就可以通过示波器测量到4000hz左右的正弦波。

⑥验证



可以通过增加周期内的正弦点数提升波形质量,下图是一个周期内128个点的波形,需要修改正弦波数组和定时器的周期


源代码分享链接

本文主要参考书籍:STM32库开发实战指南,STM32F10x-中文参考手册,相关百度百科
链接:https://pan.baidu.com/s/1EM1ADanuDnwtcWcRrprSfw
提取码:ooha

工程笔记阶段1-DAC正弦波实验相关推荐

  1. ZYNQ FPGA实验——DAC FIFO实验

    文章目录 前言 一.添加AXI4-Stream Data FIFO IP核 二.添加PLL IP核 三.添加DDS IP核 四.添加VIO IP核 五.添加ILA IP核 六.编写测试程序 七.管脚分 ...

  2. 51单片机 | DAC数模转换实验

    文章目录 一.DAC介绍 2.DAC 工作原理 二.PWM介绍 三.硬件设计 四.软件设计 1.PWM实现函数 2. 主函数 五.实验现象   这一节来介绍下如何使用 51 单片机输出模拟信号,要让 ...

  3. 字节跳动混沌工程实践之场景化主动实验

    背景 从 2010 年 Netflix 上线 Chaos Mokey 的第一个版本到现在,虽然混沌工程发展已历时十年,但其实只在少数大厂里面有较成熟的落地,对绝大部分研发同学来说,混沌工程还是一个比较 ...

  4. 小米6钉子户们的胜利!复刻机可能要来了,目前已在工程验证阶段

    小米6作为一代神机在米粉心目中的地位颇高,一大批"钉子户"仍在坚守阵地,上周雷军也为小米6提供电池换新服务,得到了米6用户的无数好评,足以见得该机有多么的厉害,在曾经开卖的阶段,一 ...

  5. FPGA系统性学习笔记连载_Day19【综合实验】之【数字钟】【Intel Cycle IV FPGA平台验证】

    FPGA系统性学习笔记连载_Day19[综合实验]之[数字钟][Intel Cycle IV FPGA平台验证] 本系列为FPGA系统性学习学员学习笔记整理分享,如有学习或者购买开发板意向,可加交流群 ...

  6. 【嵌入式硬件芯片开发笔记】4-20mA DAC芯片AD5421配置流程

    [嵌入式硬件芯片开发笔记]4-20mA DAC芯片AD5421配置流程 16位.串行输入.环路供电.4 mA至20 mA DAC 可用于HART协议相关电路 同AD5700配合使用 AD5421的SP ...

  7. 模拟电路笔记(四)正弦波振荡电路

    模拟电路笔记(四)正弦波振荡电路 正弦波振荡电路的组成 自激条件 常用振荡器 正弦波振荡电路的组成 振荡电路是指无外加激励信号条件下,能自行将直流信号转化成交流信号的电路 按输出波形的不同可分为正弦波 ...

  8. vex机器人 亚洲公开赛_VEX机器人亚洲公开赛工程笔记大公开:华硕商用赋能青少年科学梦想...

    原标题:VEX机器人亚洲公开赛工程笔记大公开:华硕商用赋能青少年科学梦想 人工智能的浪潮正以迅雷不及掩耳之势席卷全球,尤其近这两年迸发出超乎预料的活力,掀起了在制造.家居.金融等各行各业的技术革新,也 ...

  9. 中国传媒大学广播电视工程专业各学科课件、笔记、作业答案及实验整理

    中国传媒大学学习资料整理 关于本校的一些学习资料以及课后作业资源真的不太好找,而且很多课程对自己以后职业生涯的帮助非常少,这就会导致自己学习的时候非常痛苦(毕竟没有办法愉快的划水了).并且恰好自己的设 ...

  10. tlc5620输出三角波流程图_[笔记].串型DAC TLC5620生成锯齿波、三角波实验,Verilog版本...

    原理图 时序图 思路 源代码 顶层模块 module tlc5620_test( input CLOCK_50, // 板载50MHz时钟 input RST_N, // output ADC549_ ...

最新文章

  1. 上机7 java异常处理,Java之异常处理【7】
  2. 干货 | 6 种激活函数核心知识点,请务必掌握!
  3. Google和微软哪个更可怕?
  4. tipask二次开发总结_二次开发自我总结
  5. Log4net 配置实例
  6. 引用之函数返回值 函数的返回值为引用类型《三》
  7. 北京大学生物信息学学习(3动态规划进行2序列比对的原理 )
  8. SQLServer2005/2008新的高效分页方法-row_number()over函数的使用
  9. 参数学习/非参数学习算法
  10. 电力线载波通信(PLC)简介
  11. docx文档文字怎么加边框,WORD文档给文字加的边框,如何调大小
  12. 文科专业考计算机专业研究生,跨专业文科生考计算机研究生的经验
  13. 计算机属于机器人相关专业,人工智能属于什么学科门类
  14. 企业信息安全之社工学审计
  15. windows10删除EFI分区(绝对安全)
  16. 用WIN7装oracle10g的步骤
  17. 泸州职业技术学院计算机单招试题,2021年泸州职业技术学院单招语文考试模拟试题库...
  18. xmind可以画流程图吗_xmind8可以画流程图吗
  19. 推荐几本最好的web前端开发技术图书
  20. Springboot+vue火车高铁站订票管理系统

热门文章

  1. 柳神(柳婼)PAT甲级题目链接
  2. 浙大计算机考研分数线2016,2016浙江大学考研复试分数线
  3. 如何实现USB自动挂载?
  4. 你知道怎么用STM32控制舵机吗?
  5. 项目管理中PMO项目管理办公室的价值
  6. inode客户端linux 怎样运行,Ubuntu下安装iNode上网客户端
  7. R:导入其他样式数据的方法
  8. python 教程 w3 school_Python 模块 | w3cschool菜鸟教程
  9. 【Red5流媒体服务器搭建】
  10. 使用zlog实现日志记录