我基于L298N芯片制造了这个电机屏蔽,以控制一个水箱的两个电机.它将引脚5和6用于一个电机,而引脚10和11用于另一个电机.
在尝试添加TSOP 4838以便使用IR遥控器控制油箱时,我注意到在10/11引脚上反向移动电机只能在全速运行 - 即引脚11上的HIGH(255)值.低于该值不会在引脚11上输出任何内容(这些引脚上的测量电压为0 V).
对于遥控器,我使用这个库.该IR接收器连接在引脚2(但销并不重要).问题是库代码本身.启用IR监听的行irrecv.enableIRIn();
是导致问题的原因.我了解到内部Arduino定时器和屏蔽用于PWM的引脚存在冲突.
这是反向驱动电机的代码:
#include <IRremote.h>
// IR receiver configuration
const int irPin = 2;
IRrecv irrecv(irPin);
// Motors configuration
const int mLeftPin1 = 10;
const int mLeftPin2 = 11;
const int mRightPin1 = 5;
const int mRightPin2 = 6;
void setup()
{
// Start IR
irrecv.enableIRIn();
// Setup motors
pinMode(mLeftPin1, OUTPUT);
pinMode(mLeftPin2, OUTPUT);
pinMode(mRightPin1, OUTPUT);
pinMode(mRightPin2, OUTPUT);
// Move left motor in reverse, slower speed …
Run Code Online (Sandbox Code Playgroud) 我尝试使用wiringPi库用softPwm控制伺服,但这使得伺服卡顿.因此,我想使用Raspberry Pi(GPIO18)上的硬件PWM引脚和wiringPi库.但我不明白如何将频率设置为50 Hz并将占空比更改为脉冲宽度范围为0.8 ms至2.5 ms.
我在互联网上找到了以下关系(我不知道它是否正确):
pwmFrequency in Hz = 19.2e6 Hz / pwmClock / pwmRange.
Run Code Online (Sandbox Code Playgroud)
我知道时钟除数最大值约为4000,Raspberry Pi PWM时钟的基频为19.2 MHz.所以这给了我~4,8KHz.
我已经有这些设置,应该给我~50Hz使用以下关系:
//put PWM in mark-space mode, which will give you
//the traditional (and easily predictable) PWM
pwmSetMode(PWM_MODE_MS);
//setting ping GPIO 18 as a pwm output
pinMode(18,PWM_OUTPUT);
//Set clock divisor to 4000
pwmSetClock(4000);
pwmSetRange (10) ;
Run Code Online (Sandbox Code Playgroud)
我没有示波器来测试输出信号以检查什么设置改变了什么.这让我很难自己找到它.
长话短说:任何人都可以告诉我如何使用Raspberry Pi上的硬件PWM控制伺服,脉冲宽度为0.8毫秒到2,1毫秒的占空比.
我正在尝试在ATmega2560上使用硬件PWM,使用TC0(一个8位定时器),在快速PWM模式下.我需要动态调整占空比,这包括零占空比.然而,这似乎并不容易,甚至不可能.引用数据表:
OCR0A寄存器的极值表示在快速PWM模式下生成PWM波形输出时的特殊情况.如果OCR0A设置为BOTTOM,则每个MAX + 1定时器时钟周期的输出将为一个窄峰值.将OCR0A设置为MAX将导致恒定的高或低输出(取决于COM0A1:0位设置的输出的极性).
因此,将OCR0A设置为0(= BOTTOM)实际上不会导致占空比为零,我的测试证实了这一点.还需要采取其他一些方法.
首先,我已经教过如上所述使用OCR0A = MAX特殊情况.结合暂时切换到反转模式,这将导致零占空比.但是,由于COM0A1:0不是双缓冲(并且不与OCR0A同步),如果在输出为高电平时切换模式,这可能会导致输出出现毛刺(在下一次溢出之前它将保持高电平) ).OCR0A改变和模式改变的顺序似乎并不重要,两者都可能出现故障.
我还考虑了另一种解决方案,通过设置COM0A1来关闭PWM:0 = 0.这将立即将输出设置为PORT寄存器中的值,该值为零.但是仍然存在从零输出回到非零占空比的问题.根据我在数据表中的描述,设置COM0A1:0以重新使能PWM将立即将输出引脚切换到PWM的输出,这可能是一个不正确的值,直到下一个比较匹配或定时器溢出.因此,一个小故障.
总体上反转PWM可能是适用的,但是问题恰好变为完全占空比,具有对称问题.
请注意,在通过PORT强制引脚输出时,不能启用PWM波形生成,如数据表中所述:
比较输出模式(COM0x1:0)位有两个功能.波形发生器使用COM0x1:0位在下一个比较匹配时定义输出比较(OC0x)状态.此外,COM0x1:0控制OC0x引脚输出源.
没有办法让PWM运行一个周期左右,并在它准备就绪时切换到它 - 使能PWM立即强制引脚输出.
UPDATE.相位校正(中心对齐)PWM模式没有这个问题,在我的情况下是可以接受的.我已经尝试过并确认它适用于零占空比和全占空比.
我需要一个大约这个形状的GIPO输出信号.(脉冲中的子脉冲)
如何在PI上使用PWM实现?我尝试用RPIO做,但他的古老的GPIO引脚可能不适用于我的Rpi 3 b +.
from RPIO import PWM
servo = PWM.Servo()
servo.set_servo(12, 10000)
PWM.add_channel_pulse(0, 12, start=200, width=2000)
Run Code Online (Sandbox Code Playgroud)
引脚上没有信号.
我很困惑,并希望尝试使用内置库来处理PWM,但我没有发现子循环的可能性.我怎么能从不同的GPIO输出这种形式的信号?
我正在尝试在Arduino Mega(ATmega2560)上启用PWM,但我遇到了一些问题.
首先,我正试图在Ada中编程.我希望将三个Timer3通道与FastPWM一起使用,所以我写道
procedure Main is
begin
-- Nullify Timer3 buffers
TCCR3A := 0;
TCCR3B := 0;
TCCR3C := 0;
-- Waveform Generation Mode
-- Fast PW, 8-bit, TOP = 0x00FF, Update OCR3x at BOTTOM, TOV3 Flag Set on TOP
-- => WGM33|WGM32|WGM31|WGM30 = 0|1|0|1
TCCR3A := TCCR3A or TCCR3A_WGM30;
TCCR3B := TCCR3B or TCCR3B_WGM32;
-- Compare Output Mode:
-- Fast PWM, non-inverting mode
-- => COM3A1|COM3A0|COM3B1|COM3B0|COM3C1|COM3C0 = 1|0|1|0|1|0
TCCR3A …
Run Code Online (Sandbox Code Playgroud) 我已经有一段时间了解如何使用我的atmega32以快速pwm模式控制电机(控制其速度).我需要使用8位Timer0,因为我对其他计数器有其他用途.我想我知道如何为此任务初始化计时器:
void initial_io (void){
DDRC = 0xFF;
DDRB = 0xFF;
PORTA = (1<<PA4)|(1<<PA5);
TCCR0 = (1<<WGM01)|(1<<WGM00); // PWM mode : Fast PWM.
TCCR0 = (1<<CS02)|(1<<CS00); // PWM clock = CPU_Clock/1024
}
Run Code Online (Sandbox Code Playgroud)
但问题就来了.我根本不知道接下来该做什么,在我的主要做什么.
我的确切项目是用加速驾驶遥控车.因此,当我从汽车要求前进时,它必须从固定加速度的停止加速到最大速度.我不知道任何大会,所以如果你能帮助我,请在C中做.任何帮助将不胜感激.
我想生成一个具有可变频率和固定占空比(50%)的 PWM 信号。频率应在 0-25KHz 之间变化。这是针对 ATMEGA32U4 微控制器的,我使用 Atmel Studio 用 C 语言编写它。我确实阅读了数据表,但我无法理解如何进行计算以及应该使用哪种模式。在浏览了不同的教程后,我发现最好使用 CTC 模式。
由于频率是变量,如何选择应使用哪个预分频器?我需要使用中断吗?对于如何设置这些定时器寄存器的任何帮助,我们将不胜感激。
我有一个 STM32F4,我想对一个已与掩码进行“或”运算的 GPIO 端口进行 PWM 处理。
因此,也许我们想要以0b00100010
200khz 进行一段时间的 PWM,但是,10khz 后,我们现在想要进行 PWM 0b00010001
...然后,10kHz 后,我们想要在同一 GPIO 上对其他一些掩码进行 PWM。
我的问题是,如何使用 DMA 做到这一点?我正在尝试触发一个 DMA 传输,该传输将在上升沿设置所有位,然后触发另一个 DMA 传输,该传输将在下降沿清除所有位。
我还没有找到一个好的方法来做到这一点(至少使用 CubeMX 以及我对 C 和 STM32 的有限经验),因为看起来我只有机会在上升沿做一些事情。
我主要关心的问题之一是 CPU 时间,因为尽管我在上面的示例中提到了数百千赫兹,但我想让这个框架非常强大,因为它不会浪费 CPU 资源。这就是为什么我喜欢 DMA 的想法,因为它是专用硬件,可以无意识地将这里的一个单词提升到那里的一个单词之类的东西,而 CPU 可以做其他事情,比如处理 PID 的数字或其他东西。
编辑 为了清楚起见:我有一组 6 个值,可以写入 GPIO。它们存储在一个数组中。我想要做的是设置一个 PWM 定时器来在 PWM 的正宽度期间设置 GPIO,然后我希望在低周期宽度期间将 GPIO 设置为 0b00000000(如果 pwm. 因此,我需要查看上升沿何时,快速写入GPIO,然后查看下降沿何时,并向GPIO写入0。
我想使用 16MHz Arduino Uno (ATMEGA328P) 设置自定义频率 (12Hz) 和占空比 (20%)。
AVR 计算器产生:
ICR1 = 20833
OCR1A = 4167
Run Code Online (Sandbox Code Playgroud)
我已经阅读了大量的论坛和 tuts 但由于某种原因我无法让它工作。
下面是我的代码:
void setup()
{
// PB1 is now an output (Pin9 Arduino UNO)
DDRB |= (1 << DDB1);
// PB2 is now an output (Pin10 Arduino UNO)
DDRB |= (1 << DDB2);
// Set PWM frequency/top value
ICR1 = 20833;
// Set PWM duty cycle
OCR1A = 4167;
// Set inverting mode (start low, go high)
TCCR1A |= (1 << …
Run Code Online (Sandbox Code Playgroud) 关于如何在较新版本的内核上为PWM配置Beaglebone的信息很少。我遵循了BeagleBone Black(v4.14)上的PWM 指令来与PWM芯片接口,但是现在我需要弄清楚每个芯片所连接的引脚。
基于BeagleBone Black文档中的Cape Cape Expansion Headers图像,我知道:
EHRPWM0A
= P9_22
EHRPWM0B
= P9_21
EHRPWM1A
= P9_14
EHRPWM1B
= P9_16
EHRPWM2A
= P8_19
EHRPWM2B
= P8_13
ECAP0
= P9_42
当我运行ls -lh /sys/class/pwm
以查看可用的PWM接口时,我看到:
lrwxrwxrwx 1 root pwm 0 May 6 14:31 pwmchip0 -> ../../devices/platform/ocp/48300000.epwmss/48300100.ecap/pwm/pwmchip0
lrwxrwxrwx 1 root pwm 0 May 6 14:31 pwmchip1 -> ../../devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip1
lrwxrwxrwx 1 root pwm 0 May 6 14:31 pwmchip3 -> ../../devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip3
lrwxrwxrwx 1 root pwm 0 May 6 14:31 pwmchip5 …
Run Code Online (Sandbox Code Playgroud) 我读到“软件 PWM”的驱动程序以某种方式在 PWM-HW 上运行,并在不使用 CPU 的情况下访问所有 GPIO。有人可以解释它是如何工作的吗?Raspberry Pi 中是否有第二个处理器用于 PWM 和 PCM 模块(是否有块图)?
这个问题与我在我的机器人中经常使用的这个优秀的驱动程序有关。
这是解释,不幸的是我不明白......
驱动程序通过设置 DMA 控制块的链接列表来工作,最后一个链接回第一个,因此一旦初始化,DMA 控制器就会连续循环,除非需要更改脉冲宽度,否则驱动程序不需要参与. 对于给定的周期,有两个 DMA 控制块;第一个将单个字传输到 GPIO“清除输出”寄存器,而第二个将一定数量的字传输到 PWM FIFO 以生成所需的脉冲宽度时间。此外,穿插这些控制块的是每个配置的伺服器,用于设置输出。
虽然驱动程序确实使用了 PWM 外设,但它仅使用它来调整 DMA 传输的速度,从而产生准确的延迟。”
以下理解是否正确:
DMA 控制器就像第二个处理器。您可以在其上运行代码。因此,这里使用它与 PWM 块一起控制所有 Raspberry GPIO 引脚的高/低状态。DMA 控制器会连续执行此操作。Raspberry 中可能有不止一个 DMA 控制器,因此 OS Linux 的速度不会因为缺少一个 DMA 控制器而受到太大影响。
我不明白 DMA 和 PWM 究竟是如何协同工作的。