在软件上生成用于模拟输入/输出的方波 [英] Generate square wave for analog input/output on software
问题描述
我有一个设备,它有数字量I/O,模拟量I/O.我将以下命令发送到设备进行通信.该设备具有gpio模块.我的设备文件位于此处
I have a device, and it has digital i/o, analog i/o. I send to device below commands for communication.The device has gpio module. My device documantation is here
写入数字输入:gpio set/clear x
从数字输出读取:gpio read x
从数字输出读取:adc read x
(x:密码)
Write to digital input : gpio set/clear x
Read from digital output : gpio read x
Read from digital output : adc read x
(x : pin number)
如何创建正弦/方波并计算振幅?要创建方波:
How can I create sine/square wave and calculate amplitude? To create square wave :
- 打开设备
- 睡觉
- 写入设备低模式(t0)
- 睡觉
- 写入设备高模式
- 睡觉
- 写入设备低模式(t1)
期间=(t1-t0)
这是方波吗?
推荐答案
看来您的例子确实是方波
it seems your example is indeed square wave
如果write to device low mode(t0)
将输出引脚设置为低电平,将write to device low mode(t1)
设置为高电平或反向,则周期为睡眠时间和设置 GPIO 状态所需的时间之和.不知道为什么您有时间在 GPIO 设置行内而不是在睡眠中……(可能与平台有关?)
if write to device low mode(t0)
sets the output pin to low and write to device low mode(t1)
to high or reverse then period is the sum of the sleeps + some time for setting up GPIO state. Don't know why you have times inside the GPIO set lines and not in sleeps ... (may be something platform dependent?)
去犯罪浪潮
使用 DAC 或 PWM + RC滤波器,并使用一些预先计算的幅度表,该表中的索引会定期增加.
use DAC or PWM + RC filter with some precomputed amplitude table in which the index is increasing periodically.
BYTE sintab[32]={ 128,...,255,...,128,...,0,....,127 };
已编码:128
为零,255
为+1
,0
为-1
;现在只需添加一些索引:
encoded: 128
is zero, 255
is +1
and 0
is -1
; now just add some index:
int ix=0'
偶尔(也许在某个计时器上)递增它并将输出设置为新值:
and once in a while (on some timer perhaps) increment it and set the output to new value:
ix=(ix+1)&31;
如果
和31
刚达到结束,则再次导致索引从头开始循环(sintab的大小必须为2的幂).周期是计时器频率/sintab大小
that and 31
just cause tho cycle the index from start again if end reached (sintab must be of size power of 2). The period is timer frequency/sintab size
[notes]
您可以根据自己的目的进行修改,例如将sintab[][]
设为2D数组,其中第一个索引表示幅度,第二个索引表示ix
.在较旧的平台(MCU)上,您可以将 PWM 序列直接编码到sintab
端,如此...
You can modify this to your purpose for example make sintab[][]
a 2D array where first index means amplitude and second is the ix
as now. On older platforms (MCU's) you can encode the PWM sequence directly to sintab
end so on ...
您可以像这样预先计算sintab
值:
You can pre-compute the sintab
values like this:
sintab[ix]=128.0+127.0*sin(float(2.0*M_PI*ix)/32.0);
或者如果您的平台支持足够快的sin
,则可以直接使用上面的行而无需实际的数组...
or if your platform supports fast enough sin
you can use above line directly without the actual array ...
[edit1]
对于sinwave
,您只能使用0/1
状态.如果您需要模拟输出和:
for sinwave
you can use just 0/1
states. If you need analog output and:
-
您有DAC(数模转换器)
然后将实际振幅发送给它,就像dac write sintab[ix];
一样,它将为您在输出引脚上创建模拟电压.
then send the actual amplitude to it like dac write sintab[ix];
that will create the analog voltage on the output pin for you.
您没有任何备用DAC,而是使用PWM脉冲宽度调制
避免使用 DAC 是一个老派的把戏,并且仍然具有来自数字引脚的模拟输出.它是这样的:
it is an old school trick to avoid the need of DAC and still have analog output from digital pin. It works like this:
输出值是每个时间块的累积能量/电压,因此您可以生成方波信号
The output value is the cumulative energy/voltage per time chunk so you generate square-wave signal
- 比率1:1表示一半的时间段为H,其余的时间段为L
- 比率2:1表示周期的2/3为H,其余时间为L
输出为H的时间越长,输出值越大.这仍然是数字输出,但是如果在其上连接任何非线性设备(如电容器或线圈),则energy inertia
会导致H电压下降到一定水平,具体取决于方波比.最常见的是 RC 滤波器( R 是串行的, C 与地面平行).如果要驱动一些线圈(电动机),则不需要过滤器.这种用法通常会在机器附近发出通常会听到的高音调(PWM频率)...
The more time the output is H the bigger output value. This is still digital output but if you connect on it any nonlinear device like capacitor or coil then the energy inertia
will cause to drop the H voltage to some level dependent on the square-wave ratio. Most common is the RC filter (R is serial and C is parallel to ground). If you want to drive some coil (motor) then you do not need the filter. This kind of use usually generate high pitch sound (the PWM frequency) often heard near machinery ...
PWM 频率必须足够高(比正弦波频率高很多倍)
The PWM frequency has to be high enough (many times higher then the sinwave frequency)
PWM 的一些代码,具有幅度和频率设置:
Some code for PWM with amplitude and frequency setting:
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;
}
}
这篇关于在软件上生成用于模拟输入/输出的方波的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!