我有一个设备,它有数字i / o,模拟i / o。我发送到设备下面的命令进行通信。设备有gpio模块。我的设备文档是here
写入数字输入:gpio set/clear x
从数字输出中读取:gpio read x
从数字输出中读取:adc read x
(x:密码)
如何创建正弦波/方波并计算幅度?要创建方波:
期间=(t1 - t0)
这是方波吗?
答案 0 :(得分:1)
看起来你的例子确实是方波
如果write to device low mode(t0)
将输出引脚设置为低电平且write to device low mode(t1)
设置为高电平或反向电压,则周期为睡眠总和+设置 GPIO 状态的时间。不知道为什么你有时间在 GPIO 设置行内,而不是在睡眠中...(可能是平台依赖的东西?)
去犯罪浪潮
使用 DAC 或 PWM + 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大小
<强> [注释] 强>
您可以将此修改为您的目的,例如make sintab[][]
一个2D数组,其中第一个索引表示振幅,第二个索引是ix
。在较旧的平台(MCU&#39; s)上,您可以将 PWM 序列直接编码到sintab
端,等等......
您可以预先计算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 ,并且仍然具有来自数字引脚的模拟输出。它的工作原理如下:
输出值是每个时间块的累积能量/电压,因此您可以生成方波信号
输出H越多,输出值越大。这仍然是数字输出,但如果连接任何非线性器件,如电容器或线圈,则energy inertia
将导致H电压降至某个水平,具体取决于方波比。最常见的是 RC 过滤器( R 是串行的, C 与地面平行)。如果你想驱动一些线圈(电机),那么你不需要过滤器。这种使用通常会产生在机械附近经常听到的高音(PWM频率)......
PWM 频率必须足够高(比sinwave频率高很多倍)
带有幅度和频率设置的 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;
}
}