C 在软件上为模拟输入/输出生成方波

C 在软件上为模拟输入/输出生成方波,c,driver,analog-digital-converter,digital-analog-converter,C,Driver,Analog Digital Converter,Digital Analog Converter,我有一个设备,它有数字I/o,模拟I/o。我向设备发送以下通信命令。该设备具有gpio模块。我的设备文档是 写入数字输入:gpio设置/清除x 从数字输出读取:gpio读取x 从数字输出读取:adc读取x (x:pin码) 如何创建正弦波/方波并计算振幅?要创建方波,请执行以下操作: 开放式设备 睡眠 写入设备低模式(t0) 睡眠 写入设备高模式 睡眠 写入设备低模式(t1) 期间=(t1-t0) 这是方波吗?看来你的例子确实是方波 如果write to device low mode(t0

我有一个设备,它有数字I/o,模拟I/o。我向设备发送以下通信命令。该设备具有gpio模块。我的设备文档是

写入数字输入:
gpio设置/清除x

从数字输出读取:
gpio读取x

从数字输出读取:
adc读取x

(x:pin码)

如何创建正弦波/方波并计算振幅?要创建方波,请执行以下操作:

  • 开放式设备
  • 睡眠
  • 写入设备低模式(t0)
  • 睡眠
  • 写入设备高模式
  • 睡眠
  • 写入设备低模式(t1)
期间=(t1-t0)


这是方波吗?

看来你的例子确实是方波

如果
write to device low mode(t0)
将输出引脚设置为low,而
write to device low mode(t1)
设置为high或reverse,则period是休眠+设置GPIO状态的时间之和。不知道为什么您在GPIO设置行中有时间而不在睡眠中。。。(可能与平台有关?)

走向正弦波

使用DACPWM+RC滤波器和一些预先计算的振幅表,其中指数周期性增加

BYTE sintab[32]={ 128,...,255,...,128,...,0,....,127  };
编码:
128
为零,
255
+1
0
-1
;现在只需添加一些索引:

int ix=0'
每隔一段时间(可能在某个计时器上)将其递增,并将输出设置为新值:

ix=(ix+1)&31;
这和
31
正好导致从开始到结束循环索引(sintab的大小幂必须为2)。周期为定时器频率/sintab大小

[notes]

您可以根据自己的目的对其进行修改,例如制作
sintab[][]
二维数组,其中第一个索引表示振幅,第二个索引表示现在的
ix
。在较旧的平台(MCU)上,您可以将PWM序列直接编码到
sintab
end,以此类推

您可以像这样预先计算
sintab
值:

sintab[ix]=128.0+127.0*sin(float(2.0*M_PI*ix)/32.0);
或者,如果您的平台支持足够快的
sin
,您可以直接使用上述行,而无需实际阵列

[edit1]

对于
sinwave
您可以只使用
0/1
状态。如果需要模拟输出和:

  • 您有DAC(数模转换器)

    然后向其发送实际振幅,如
    dac write sintab[ix]将在输出引脚上为您创建模拟电压

  • 您没有任何备用DAC,而是使用PWM脉宽调制

    这是一个老生常谈的诀窍,它可以避免使用DAC,并且仍然具有来自数字引脚的模拟输出。它的工作原理如下:

    sintab[ix]=128.0+127.0*sin(float(2.0*M_PI*ix)/32.0);
    
    输出值是每个时间块的累积能量/电压,因此生成方波信号

    • 比率1:1表示一半周期为H,其余周期为L
    • 比率2:1表示周期的2/3为H,其余为L
    输出时间越长,输出值越大。这仍然是数字输出,但如果在其上连接任何非线性设备,如电容器或线圈,
    能量惯性
    将导致H电压下降到取决于方波比的某个水平。最常见的是RC滤波器(R是串行的,C与接地平行)。如果你想驱动一些线圈(电机),那么你不需要过滤器。这种使用通常会产生高频声音(PWM频率),通常在机器附近听到

    PWM频率必须足够高(比正弦波频率高很多倍)

  • 带有振幅和频率设置的PWM的一些代码:

    const int timer\u T=1;//使用的计时器间隔[ms]
    常数int PWM_max=10;//PWM最大振幅+1
    int PWM_s=0;//PWM实际步长
    int PWM_t=0;//PWM实际时间
    int PWM_a=3;//PWM振幅=1!!!
    PWM_t+=定时器_t;
    如果(PWM\u t>=PWM\u T0)
    {
    如果(PWM_s=PWM_max)PWM_s=0;
    PWM_t-=PWM_T0;
    }
    }
    
    hmm您似乎在为USB到GPIO的简化编写软件,所以这不是直接针对MCU的代码,而是针对PC的代码?而是通过某个驱动程序将数据发送到USB板。您应该添加一些关于它的信息,甚至重新标记也是一个好主意(如果可能,将设备名称添加到标记中)。所以现在我不确定我的答案是否适用于此(可能存在计时问题)您是设备同步IO端口还是异步(您是设置IO切换或读取的时间,还是设置发送命令的时间,然后执行+一些粗略的延迟?)我不明白如何使用sin表。我只能将输出设置为0或1。但是表中的数字是不同的。例如,数字是128,是否应设置为“0”@sdn设备没有仅DAC的ADC,因此您必须选择PWM。首先创建具有可变比率和固定频率(睡眠(t0),睡眠(t1)t0+t1=常数,t0/t1为比率)的功能方波(通过示波器或LED检查)。如果完成,则执行sintab。。。如果你没有示波器,那么如果PWM f是高的,1kHz,正弦波FRQ是低0.1Hz,那么你仍然可以使用LED,那么你应该看到亮度变化…@ SDN在C++中增加了一些PWM的代码(直接在Opera中写,这样就可以有打字),越快的定时器,你可以获得更多的幅度步骤或更高的PWM频率。