1

我有一个设备,它有数字 I/O、模拟 I/O。我向设备发送以下命令进行通信。设备具有 gpio 模块。我的设备文档在这里

写入数字输入:gpio set/clear x
从数字输出gpio read x
读取:从数字输出读取:adc read x
(x:引脚编号)

如何创建正弦波/方波并计算幅度?创建方波:

  • 打开设备
  • 睡觉
  • 写入设备低模式(t0)
  • 睡觉
  • 写入设备高模式
  • 睡觉
  • 写入设备低模式(t1)

期间 = (t1 - t0)

这是方波吗?

4

1 回答 1

2

看来你的例子确实是方波

如果write to device low mode(t0)将输出引脚设置为低电平和write to device low mode(t1)高电平或反向,则周期是睡眠的总和 + 用于设置GPIO状态的一些时间。不知道为什么您在GPIO设置线中有时间而不是在睡眠中......(可能与平台有关?)

去罪波

使用DACPWM + RC 滤波器和一些预先计算的幅度表,其中索引周期性地增加。

BYTE sintab[32]={ 128,...,255,...,128,...,0,....,127  };

编码:128是零,255+10-1;现在只需添加一些索引:

int ix=0'

偶尔(可能在某个计时器上)增加它并将输出设置为新值:

ix=(ix+1)&31;

如果到达结束,31只会导致重新从开始循环索引(sintab 的大小必须为 2)。周期是定时器频率/sintab 大小

[笔记]

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

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

sintab[ix]=128.0+127.0*sin(float(2.0*M_PI*ix)/32.0);

或者,如果您的平台支持足够快,sin您可以直接使用上面的行,而不需要实际的数组...

[编辑1]

因为sinwave你可以只使用0/1状态。如果您需要模拟输出并且:

  1. 你有 DAC(数模转换器)

    然后将实际幅度发送给它,这样dac write sintab[ix];将为您在输出引脚上创建模拟电压。

  2. 您没有任何备用 DAC,而是使用 PWM 脉冲宽度调制

    避免使用DAC并且仍然具有来自数字引脚的模拟输出是一个老派的技巧。它是这样工作的:

    输出值是每个时间块的累积能量/电压,因此您可以生成方波信号

    • 比率 1:1 表示周期的一半是 H,其余的周期是 L
    • 比率 2:1 表示周期的 2/3 为 H,其余为 L

    输出为H的时间越多,输出值越大。这仍然是数字输出,但如果您在其上连接任何非线性设备,如电容器或线圈,energy inertia则会导致 H 电压下降到取决于方波比的某个水平。最常见的是RC滤波器(R是串联的,C是与地并联的)。如果你想驱动一些线圈(电机),那么你不需要滤波器。这种使用通常会产生在机械附近经常听到的高音(PWM频率)......

    图像

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

具有幅度和频率设置的PWM的一些代码:

const int timer_T=1;        // used timer interval [ms]
const int PWM_max=10;       // PWM max amplitude+1 
int PWM_s=0;                 // PWM actual step
int PWM_t=0;                 // PWM actual time

int PWM_a=3;                 // PWM amplitude <0,PWM_ratio_max)
int PWM_T=200;               // PWM period [ms]

void OnTimer()
 {
 int PWM_T0=PWM_T/PWM_max; // PWM step period must be >=1 !!!
 PWM_t+=timer_T;
 if (PWM_t>=PWM_T0)
  {
  if (PWM_s<=pwm_a) gpio set x; else gpio clear x;
  PWM_s++; if (PWM_s>=PWM_max) PWM_s=0;
  PWM_t-=PWM_T0;
  }
 }
于 2014-11-15T15:52:18.973 回答