论坛

是否可以在LPC1114上反转PWM输出?

开始于 鲍勃扬姆 2013年8月17日
我正在尝试使用以下功能驱动伺服器,但我搞砸了 EMR寄存器,但我认为这些值基本上会被忽略,因为我已经 MR0 / MR1的PWM输出使能。数据表中说,我们需要阅读一组 使用PWM模式时适用的规则。我知道我可以解决这个问题 使用定时器/比较模块触发中断,然后切换IO引脚 在中断函数中,但是如果没有一种更简单的方法 这样做可能不需要任何处理。现在我的波形倒转了 有效的50Hz伺服脉冲(高1-2ms,低18-19ms)。我找到了一些 在线示例代码,但不适用于这些处理器,LPC17xx似乎有一个 不同的PWM外设(需要手动锁存数据,利用 LPC1114数据手册中未描述的其他位/寄存器)。

无效PWM_init(void)
{
LPC_TMR16B0->TCR = 0; //禁用Timer0
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);
LPC_TMR16B0->EMR = (1<<0)|(1<<1)|(1<<3)|(1<<5)|(1<<10);
LPC_TMR16B0->PR = 11; //在约20ms的时间内将预分频器设置为12

LPC_IOCON->PIO0_8 &= ~0x07;
LPC_IOCON->PIO0_9 &= ~0x07;
LPC_IOCON->PIO0_8 |= 0x02;
LPC_IOCON->PIO0_9 |= 0x02;

LPC_TMR16B0->MR3 = 20000-1;
LPC_TMR16B0->MR0 = 1500;
LPC_TMR16B0->MR1 = 1500;
LPC_TMR16B0->MCR = 0x400;
LPC_TMR16B0->PWMC = 0x0B;

NVIC_EnableIRQ(TIMER_16_0_IRQn); //启用TIMER1中断
LPC_TMR16B0->TCR = 1; //启用Timer16
}

任何帮助都非常欢迎。谢谢-鲍勃

LPC2100系列工程师指南

嗨鲍勃,

设置另一个占空比时,PWM信号工作正常吗?如果
是的,您可能正在硬件上反转信号(可能是在
使用光电或使用晶体管进行信号隔离)。你可以改变
这两种方式:
-在硬件上增加一个晶体管以反转驱动器信号;
-在软件上反转信号。要反转软件,更简单的方法
将您的整个占空比(100%)值减去所计算出的
占空比(例如:对于2ms高和18ms低,您使用的是10%
占空比和反转波形,您需要使用占空比的90%)。
我使用LPC2136 / 38通过PWM控制伺服电机并构建自己的
使用硬件反转的驱动程序(低功耗)。

腱鞘炎

毛罗·伦茨
传真:(55)8115-6944
Skype:mauro_eafs

“将垃圾邮件拒诸门外。阿卡姆(Acam)电子邮件, 补救措施,以利用营地的CCo quando en parar mais de um目的地。”

Em 17/08/2013 12:20,bobryanmm escreveu:
> 无效PWM_init(void)

毛罗

感谢您的回复。我绝对不会在硬件中反转信号。 尽管信号反相,但占空比仍可预期,因此实际占空比 周期是100%所需的百分比(在我的情况下是80-90%)。 EMR寄存器似乎决定了 是否应在比较匹配时设置或清除EM0输出,但有一个注释 如果在PWMC寄存器中启用了PWM,则EMCn不起作用。

“如果匹配输出在PWMCON寄存器中配置为PWM输出 (第18.7.12节),外部匹配寄存器的功能由 PWM规则(第18.7.13节“单边沿控制PWM输出的规则” page 340)."

如果我们在第340页上查找规则,则会得到:
"
18.7.13单边沿控制PWM输出的规则
1.在每个PWM的开始,所有单边沿控制的PWM输出均变为低电平 除非它们的匹配值等于零,否则循环(定时器设置为零)。
2.达到匹配值时,每个PWM输出将变为高电平。如果没有匹配 发生(即匹配值大于PWM周期长度),则PWM 输出持续保持低电平。
3.如果将大于PWM周期长度的匹配值写入匹配项 寄存器,并且PWM信号已经为高电平,那么PWM信号将为 在下一个PWM周期的下一个开始时清除。
4.如果匹配寄存器包含与定时器复位值相同的值(PWM 周期长度),那么PWM输出将在下一个时钟滴答时复位为LOW。 因此,PWM输出将始终由一个时钟滴答宽度为正 脉冲的周期由PWM周期长度决定(即定时器重载 value).
5.如果匹配寄存器设置为零,则PWM输出将变为高电平。 第一次,计时器返回零,并将持续保持高电平。

注意:当匹配输出被选择为用作PWM输出,计时器 匹配控制寄存器MCR中的复位(MRnR)和定时器停止(MRnS)位必须 除匹配寄存器设置PWM周期长度外,设置为0。为了这 寄存器,将MRnR位置1以使能定时器复位 匹配相应匹配寄存器的值。
"

对我来说,这很清楚,规则1和2说输出将设置为低 在定时器复位时,比较匹配时将其设置为高。我已经使用了很多微镜 可以很简单地反转这些输出,但似乎并没有 这种芯片就是这种情况。我知道有很多方法可以解决它,但我只是 想知道是否有人对此限制有见识,或者我是否读错了 the datasheet etc.

再次感谢-鲍勃

---在...中,毛罗·伦茨写道:
>
> 嗨鲍勃,
>
>设置另一个占空比时,PWM信号工作正常吗?如果
>是的,您可能正在硬件上反转信号(可能是在
>使用光电或使用晶体管进行信号隔离)。你可以改变
> 这两种方式:
>-在硬件上增加一个晶体管以反转驱动器信号;
>-在软件上反转信号。要反转软件,更简单的方法
>将您的整个占空比(100%)值减去所计算出的
>占空比(例如:对于2ms高和18ms低,您使用的是10%
>占空比和反转波形,您需要使用占空比的90%)。
>我使用LPC2136 / 38通过PWM控制伺服电机并构建自己的
>使用硬件反转的驱动程序(低功耗)。
>
> 腱鞘炎
>
> 毛罗·伦茨
>传真:(55)8115-6944
> Skype:mauro_eafs
>
>“将垃圾邮件拒诸门外。阿卡姆(Acam)电子邮件, 补救措施,以利用营地的CCo quando en parar mais de um目的地。”
>
>Em 17/08/2013 12:20,bobryanmm escreveu:
> > 无效PWM_init(void)
>

处理反转是软件。例如,如果您想要两毫秒 反向脉冲,将PWM设置为18毫秒。

杰夫

---在l ...中,“ 鲍勃扬姆”写道:
>
>我正在尝试使用以下功能驱动伺服器,但我搞砸了 EMR寄存器,但我认为这些值基本上会被忽略,因为我已经 MR0 / MR1的PWM输出使能。数据表中说,我们需要阅读一组 使用PWM模式时适用的规则。我知道我可以解决这个问题 使用定时器/比较模块触发中断,然后切换IO引脚 在中断函数中,但是如果没有一种更简单的方法 这样做可能不需要任何处理。现在我的波形倒转了 有效的50Hz伺服脉冲(高1-2ms,低18-19ms)。我找到了一些 在线示例代码,但不适用于这些处理器,LPC17xx似乎有一个 不同的PWM外设(需要手动锁存数据,利用 LPC1114数据手册中未描述的其他位/寄存器)。
>
> 无效PWM_init(void)
> {
>LPC_TMR16B0->TCR = 0; //禁用Timer0
> LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);
>LPC_TMR16B0->EMR = (1<<0)|(1<<1)|(1<<3)|(1<<5)|(1<<10);
>LPC_TMR16B0->PR = 11; //在约20ms的时间内将预分频器设置为12
>
> LPC_IOCON->PIO0_8 &= ~0x07;
> LPC_IOCON->PIO0_9 &= ~0x07;
> LPC_IOCON->PIO0_8 |= 0x02;
> LPC_IOCON->PIO0_9 |= 0x02;
>
>LPC_TMR16B0->MR3 = 20000-1;
>LPC_TMR16B0->MR0 = 1500;
>LPC_TMR16B0->MR1 = 1500;
>LPC_TMR16B0->MCR = 0x400;
>LPC_TMR16B0->PWMC = 0x0B;
>
>NVIC_EnableIRQ(TIMER_16_0_IRQn); //启用TIMER1中断
>LPC_TMR16B0->TCR = 1; //启用Timer16
> }
>
>任何帮助都非常欢迎。谢谢-鲍勃
>

在这种情况下,这是可行的,但在某些情况下,这不是因为 在周期结束时会有高脉冲。我继续禁用PWM 在输出上并使用EMC0在比较匹配时清除EM0位,然后触发 并在EM3上进行中断比较匹配,并在我正在设置的中断例程中进行比较 EM0再次变高。.确实可以,但是我更喜欢不使用它 中断或其他处理。阅读数据表后, 时代,我认为这是不可能的。谢谢-鲍勃

---在l ...中,“ ksdoubleshooter”写道:
>
>处理反转是软件。例如,如果您想要两毫秒 反向脉冲,将PWM设置为18毫秒。
>
> 杰夫
>
>---在l ...中,“ 鲍勃扬姆”写道:
> >
> >我正在尝试使用以下功能驱动伺服器,但我搞砸了 使用EMR寄存器,但我认为这些值基本上会被忽略,因为我已经 为MR0 / MR1使能了PWM输出。数据表中说,我们需要阅读一组 使用PWM模式时适用的规则。我知道我可以解决这个问题 使用定时器/比较模块触发中断,然后切换IO引脚 在中断函数中,但是如果没有一种更简单的方法 这样做可能不需要任何处理。现在我的波形倒转了 有效的50Hz伺服脉冲(高1-2ms,低18-19ms)。我找到了一些 在线示例代码,但不适用于这些处理器,LPC17xx似乎有一个 不同的PWM外设(需要手动锁存数据,利用 LPC1114数据手册中未描述的其他位/寄存器)。
> >
> > 无效PWM_init(void)
> > {
> >LPC_TMR16B0->TCR = 0; //禁用Timer0
> > LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);
> >LPC_TMR16B0->EMR = (1<<0)|(1<<1)|(1<<3)|(1<<5)|(1<<10);
> >LPC_TMR16B0->PR = 11; //在约20ms的时间内将预分频器设置为12
> >
> > LPC_IOCON->PIO0_8 &= ~0x07;
> > LPC_IOCON->PIO0_9 &= ~0x07;
> > LPC_IOCON->PIO0_8 |= 0x02;
> > LPC_IOCON->PIO0_9 |= 0x02;
> >
> >LPC_TMR16B0->MR3 = 20000-1;
> >LPC_TMR16B0->MR0 = 1500;
> >LPC_TMR16B0->MR1 = 1500;
> >LPC_TMR16B0->MCR = 0x400;
> >LPC_TMR16B0->PWMC = 0x0B;
> >
> >NVIC_EnableIRQ(TIMER_16_0_IRQn); //启用TIMER1中断
> >LPC_TMR16B0->TCR = 1; //启用Timer16
> > }
> >
> >任何帮助都非常欢迎。谢谢-鲍勃
>

---在l ...中,“ 鲍勃扬姆”写道:
>
>在这种情况下,这是可行的,但在某些情况下,这不是因为 在周期结束时会有高脉冲。

周期来来去去,但循环的开始取决于您。我认为周期 当脉冲变高时开始。我可以将休假时间看作是未来 前沿还是后沿-我的规则。

理查德

LPC1100定时器的PWM模式存在一些问题,极性是 与大多数人期望的相反,并使用相同的值设置匹配寄存器 端子数引起的输出值故障。

以下代码将产生与您最初尝试的完全相同的代码 完成-通过将引脚更改为GPIO来实现极性反转和反偏移 在占空比上传递值0的情况。

#包括
#包括
#包括“ pwm.h”
#包括“ gpio.h”

无效pwm_init(void)
{
SYSAHBCLKCTRL | =(1<<8); //启动定时器16b1
IOCON_PIO1_9= 0 | (0 << 3) | (3 << 6);
IOCON_PIO1_10= 0 | (0 << 3) | (3 << 6);
GPIO1DIR | =((1<< 9) | (1 << 10));
GPIO1_MASKED_RW(((1<< 9) | (1 << 10))) = 0;
TMR16B1TCR = 2; //重置计时器
TMR16B1PR = 2; //预分频器
TMR16B1MR3 = 1000; //匹配寄存器3-设置pwm频率
TMR16B1MCR =(2<<9); //在比赛3重置
TMR16B1PWMC = 0x03; //在mat0和mat1上启用pwm
TMR16B1TCR = 1; //启动计时器
}

无效pwm_output(uint32_t chn,uint32_t duty_cycle)
{
开关(chn)
{
案例0:
如果(duty_cycle== 0)
{
IOCON_PIO1_9&=〜7; // mat0返回io
GPIO1_MASKED_RW(1<<9)= 0; //并设置低
}
其他
{
如果(duty_cycle> 1000)
duty_cycle = 1000;
TMR16B1MR0 = 1000-占空比;
IOCON_PIO1_9|= 1; //p1.9 set to t16b1 mat0
}
打破;
情况1:
如果(duty_cycle== 0)
{
IOCON_PIO1_10&=〜7; // mat1返回io
GPIO1_MASKED_RW(1<<10)= 0; //并设置低
}
其他
{
如果(duty_cycle> 1000)
duty_cycle = 1000;
TMR16B1MR1 = 1000-占空比;
IOCON_PIO1_10|= 2; //p1.10 set to t16b1 mat1
}
打破;
}
}
---在l ...中,“ 鲍勃扬姆”写道:
>
>在这种情况下,这是可行的,但在某些情况下,这不是因为 在周期结束时会有高脉冲。我继续禁用PWM 在输出上并使用EMC0在比较匹配时清除EM0位,然后触发 并在EM3上进行中断比较匹配,并在我正在设置的中断例程中进行比较 EM0再次变高。.确实可以,但是我更喜欢不使用它 中断或其他处理。阅读数据表后, 时代,我认为这是不可能的。谢谢-鲍勃
>
>---在l ...中,“ ksdoubleshooter”写道:
> >
> >处理反转是软件。例如,如果您想要两毫秒 反向脉冲,将PWM设置为18毫秒。
> >
> > 杰夫
> >
> >---在l ...中,“ 鲍勃扬姆”写道:
> > >
> > >我正在尝试使用以下功能驱动伺服器,但我搞砸了 使用EMR寄存器,但我认为这些值基本上会被忽略,因为我已经 为MR0 / MR1使能了PWM输出。数据表中说,我们需要阅读一组 使用PWM模式时适用的规则。我知道我可以解决这个问题 使用定时器/比较模块触发中断,然后切换IO引脚 在中断函数中,但是如果没有一种更简单的方法 这样做可能不需要任何处理。现在我的波形倒转了 有效的50Hz伺服脉冲(高1-2ms,低18-19ms)。我找到了一些 在线示例代码,但不适用于这些处理器,LPC17xx似乎有一个 不同的PWM外设(需要手动锁存数据,利用 LPC1114数据手册中未描述的其他位/寄存器)。
> > >
> > > 无效PWM_init(void)
> > > {
> > >LPC_TMR16B0->TCR = 0; //禁用Timer0
> > > LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);
> > >LPC_TMR16B0->EMR = (1<<0)|(1<<1)|(1<<3)|(1<<5)|(1<<10);
> > >LPC_TMR16B0->PR = 11; //在约20ms的时间内将预分频器设置为12
> > >
> > > LPC_IOCON->PIO0_8 &= ~0x07;
> > > LPC_IOCON->PIO0_9 &= ~0x07;
> > > LPC_IOCON->PIO0_8 |= 0x02;
> > > LPC_IOCON->PIO0_9 |= 0x02;
> > >
> > >LPC_TMR16B0->MR3 = 20000-1;
> > >LPC_TMR16B0->MR0 = 1500;
> > >LPC_TMR16B0->MR1 = 1500;
> > >LPC_TMR16B0->MCR = 0x400;
> > >LPC_TMR16B0->PWMC = 0x0B;
> > >
> > >NVIC_EnableIRQ(TIMER_16_0_IRQn); //启用TIMER1中断
> > >LPC_TMR16B0->TCR = 1; //启用Timer16
> > > }
> > >
> > >任何帮助都非常欢迎。谢谢-鲍勃
> > >
>

使用匹配中断并在ISR中填充内容会导致值勤 cycle jitter.

杰夫

---在l ...中,“ 鲍勃扬姆”写道:
>
>在这种情况下,这是可行的,但在某些情况下,这不是因为 在周期结束时会有高脉冲。我继续禁用PWM 在输出上并使用EMC0在比较匹配时清除EM0位,然后触发 并在EM3上进行中断比较匹配,并在我正在设置的中断例程中进行比较 EM0再次变高。.确实可以,但是我更喜欢不使用它 中断或其他处理。阅读数据表后, 时代,我认为这是不可能的。谢谢-鲍勃
>
>---在l ...中,“ ksdoubleshooter”写道:
> >
> >处理反转是软件。例如,如果您想要两毫秒 反向脉冲,将PWM设置为18毫秒。
> >
> > 杰夫
> >
> >---在l ...中,“ 鲍勃扬姆”写道:
> > >
> > >我正在尝试使用以下功能驱动伺服器,但我搞砸了 使用EMR寄存器,但我认为这些值基本上会被忽略,因为我已经 为MR0 / MR1使能了PWM输出。数据表中说,我们需要阅读一组 使用PWM模式时适用的规则。我知道我可以解决这个问题 使用定时器/比较模块触发中断,然后切换IO引脚 在中断函数中,但是如果没有一种更简单的方法 这样做可能不需要任何处理。现在我的波形倒转了 有效的50Hz伺服脉冲(高1-2ms,低18-19ms)。我找到了一些 在线示例代码,但不适用于这些处理器,LPC17xx似乎有一个 不同的PWM外设(需要手动锁存数据,利用 LPC1114数据手册中未描述的其他位/寄存器)。
> > >
> > > 无效PWM_init(void)
> > > {
> > >LPC_TMR16B0->TCR = 0; //禁用Timer0
> > > LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);
> > >LPC_TMR16B0->EMR = (1<<0)|(1<<1)|(1<<3)|(1<<5)|(1<<10);
> > >LPC_TMR16B0->PR = 11; //在约20ms的时间内将预分频器设置为12
> > >
> > > LPC_IOCON->PIO0_8 &= ~0x07;
> > > LPC_IOCON->PIO0_9 &= ~0x07;
> > > LPC_IOCON->PIO0_8 |= 0x02;
> > > LPC_IOCON->PIO0_9 |= 0x02;
> > >
> > >LPC_TMR16B0->MR3 = 20000-1;
> > >LPC_TMR16B0->MR0 = 1500;
> > >LPC_TMR16B0->MR1 = 1500;
> > >LPC_TMR16B0->MCR = 0x400;
> > >LPC_TMR16B0->PWMC = 0x0B;
> > >
> > >NVIC_EnableIRQ(TIMER_16_0_IRQn); //启用TIMER1中断
> > >LPC_TMR16B0->TCR = 1; //启用Timer16
> > > }
> > >
> > >任何帮助都非常欢迎。谢谢-鲍勃
> > >
>

鲍勃

驾驶伺服器应该很容易,不需要任何中断(除非我 不能完全理解您的问题)。您必须在 计时器以使其运行,但是一旦运行,计时器设备就会生成 waveform for you.

我在Github上的LPC1114上有一些PWM的示例代码,位于: //github.com/engineergorman/lpc1114fn28 //github.com/engineergorman/lpc1114fn28

我正在使用Keil开发环境的免费版本。只是抓住整个 在lpc1114fn28文件夹中,导航到“ pwm”或“ pwmfan”示例,打开并构建它们。 我最近一直在研究BLDC控制,并且一直在修改共享 核心中的标头。因此,如果无法正常构建,请给我发送便条,我会 fix it.

干杯,
克里斯

---在...中,写道:

使用匹配中断并在ISR中填充内容会导致值勤 cycle jitter.

杰夫

---在l ... mailto:l ...中,“ 鲍勃扬姆”写道:
>
>在这种情况下,这是可行的,但在某些情况下,这不是因为 在周期结束时会有高脉冲。我继续禁用PWM 在输出上并使用EMC0在比较匹配时清除EM0位,然后触发 并在EM3上进行中断比较匹配,并在我正在设置的中断例程中进行比较 EM0再次变高。.确实可以,但是我更喜欢不使用它 中断或其他处理。阅读数据表后, 时代,我认为这是不可能的。谢谢-鲍勃
>
>---在l ... mailto:l ...中,“ ksdoubleshooter”写道:
> >
> >处理反转是软件。例如,如果您想要两个 毫秒反转脉冲,将PWM设置为18毫秒。
> >
> > 杰夫
> >
> >---在l ... mailto:l ...中,“ 鲍勃扬姆”写道:
> > >
> > >我正在尝试使用以下功能驱动伺服器,但我搞砸了 使用EMR寄存器,但我认为这些值基本上会被忽略,因为我已经 为MR0 / MR1使能了PWM输出。数据表中说,我们需要阅读一组 使用PWM模式时适用的规则。我知道我可以解决这个问题 使用定时器/比较模块触发中断,然后切换IO引脚 在中断函数中,但是如果没有一种更简单的方法 这样做可能不需要任何处理。现在我的波形倒转了 有效的50Hz伺服脉冲(高1-2ms,低18-19ms)。我找到了一些 在线示例代码,但不适用于这些处理器,LPC17xx似乎有一个 不同的PWM外设(需要手动锁存数据,利用 LPC1114数据手册中未描述的其他位/寄存器)。
> > >
> > > 无效PWM_init(void)
> > > {
> > > LPC_TMR16B0->TCR = 0; //禁用Timer0
> > > LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);
> > > LPC_TMR16B0->EMR = (1<<0)|(1<<1)|(1<<3)|(1<<5)|(1<<10);
> > > LPC_TMR16B0->PR = 11; //在约20ms的时间内将预分频器设置为12
> > >
> > > LPC_IOCON->PIO0_8 &= ~0x07;
> > > LPC_IOCON->PIO0_9 &= ~0x07;
> > > LPC_IOCON->PIO0_8 |= 0x02;
> > > LPC_IOCON->PIO0_9 |= 0x02;
> > >
> > > LPC_TMR16B0->MR3 = 20000-1;
> > > LPC_TMR16B0->MR0 = 1500;
> > > LPC_TMR16B0->MR1 = 1500;
> > > LPC_TMR16B0->MCR = 0x400;
> > > LPC_TMR16B0->PWMC = 0x0B;
> > >
> > >NVIC_EnableIRQ(TIMER_16_0_IRQn); //启用TIMER1中断
> > > LPC_TMR16B0->TCR = 1; //启用Timer16
> > > }
> > >
> > >任何帮助都非常欢迎。谢谢-鲍勃
> > >
> >
>