- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试使用 Teensy 2.0 微 Controller (基于 ATMEGA32U4 8 位 AVR 16 MHz)设置两个定时器中断例程,以独立控制两个伺服电机
经过多次试验 - 我能够在端口 C 的引脚 7 上设置一个,但是
这里是设置代码:
int main(void)
{
DDRE = 0xFF;
TCCR1A |= 1 << WGM12; // Configure timer 1 for CTC mode
TCCR1B = (1<<WGM12) | (1<<CS11) ;
OCR1A = 1000; // initial
TIMSK1 |= 1 << OCIE1A; // Output Compare A Match Interrupt Enable
sei(); // enable interrupts
// ...code that sets pulseWidth based on app logic variable.
// Not showing as its not important
}
ISR(TIMER1_COMPA_vect)
{
if (0 == pulseWidth)
{
return;
}
static uint8_t state = 0;
int dutyTotal = 20*1000;
if (0 == state)
{
PORTC |= 0b10000000;
OCR1A = pulseWidth;
state = 1;
}
else if (1 == state)
{
PORTC &= 0b01111111;
OCR1A = dutyTotal - pulseWidth;
state = 0;
}
}
最佳答案
虽然在不了解您的应用程序的更多信息的情况下很难给出明确的答案(例如,什么样的伺服/电机,- 我猜模型 RC 类型与 1-2ms pule?)有两种方法可以解决这个问题:
首先,在您的代码中,您似乎是通过切换 PC7 手动生成 PWM 信号。您可以通过增加状态数量来添加另一个输出 - 您需要比伺服系统数量多一个来提供设置脉冲重复频率的间隙。当您需要驱动大量 Helm 机时,这是一种常用技术,因为大多数 RC Helm 机不关心脉冲相位或频率(在限制范围内),只关心脉冲宽度,因此您可以在另一个在不同的输出上,同时只使用一个像这样的定时器(在一种伪代码状态图中):
State 0:
Turn on output 1
Set timer TOP to pulse duration 1.
Go to state 1:
State 1:
Turn off output 1
Turn on output 2
Set timer TOP to pulse duration 1.
Go to state 2:
State 2:
Turn off output 2
Set timer TOP to pulse duration 3.
Go to state 0:
“脉冲持续时间 3”设置 PRF(脉冲重复频率)。如果你想要花哨,您可以将其设置为 1/f-pd1-pd2,以提供恒定频率。
[“TOP”是 AVR 的说法,用于设置计时器的回绕(溢出)速率。参见数据表。 ]
其次,如果您只使用两个 Helm 机,还有一种更简单的方法 - 使用定时器的硬件 PWM 功能。 AVR 定时器有一个内置的 PWM 功能,可以为您进行引脚切换。 mega32 上的 Timer1 有两个 PWM 输出引脚,这对你的两个伺服系统来说效果很好,然后你根本不需要(不一定)需要中断处理程序。如果您直接使用 PWM 驱动电机(例如通过 H 桥),这也是正确的解决方案。
为此,您需要将定时器置于 PWM 模式并启用 OC1A 和 OC1B 输出引脚,例如
/*
* Set fast PWM mode on OC1A and OC1B with ICR1 as TOP
* (Mode 14)
*/
TCCR1A = (1 << WGM11) | (1 << COM1B1) | (1 << COM1A1);
TCCR1B = (3 << WGM12);
/*
* Clock source internal, pre-scale by 8
* (i.e. count rate = 2MHz for 16MHz crystal)
*/
TCCR1B |= (1 << CS11);
/*
* Set counter TOP value to set pulse repetition frequency.
* E.g. 50Hz (good for RC servos):
* 2e6/50 = 40000. N.B. This must be less than 65535.
* We count from t down to 0 so subtract 1 for true freq.
*/
ICR1 = 40000-1;
/* Enable OC1A and OC1B PWM output */
DDRB |= (1 << PB5) | (1 << PB6);
/* Uncomment to enable TIMER1_OVF_vect interrupts at 50Hz */
/* TIMSK1 = (1 << TOV1); */
/*
* Set both servos to centre (1.5ms pulse).
* Value for OCR1x is 2000 per ms then subtract one.
*/
OCR1A = 3000-1;
OCR1B = 3000-1;
免责声明 - 此代码片段可以编译,但我尚未在实际设备上对其进行检查,因此您可能需要仔细检查寄存器值。在 http://www.atmel.com/Images/doc7766.pdf 查看完整的数据表
此外,您的代码中可能有一些拼写错误,TCC1A 中不存在位 WGM12(您实际上设置了位 3,即 FOC1A -“强制比较”,请参见数据表。)此外,您正在编写 DDRE启用端口 E 上的输出,但切换端口 C 上的引脚。
关于c - 使用 AVR 设置多个定时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19344723/
前言 众所周知,对于 16 位 I/O 寄存器(定时器计数器、ICR/OCR、ADC...)的原子和同时读/写高和低部分,AVR 使用影子临时寄存器。例如。在 ATmega8 上读取 TCNT1: u
我想使用 avr-gcc 将全局变量绑定(bind)到未使用的 I/O 寄存器(例如 PORTB),以减少代码大小。我在AVR的应用笔记AVR035中学到了这个技巧(第 14 页)。 在应用笔记中,他
我有一个项目,其中 ATtiny2313V 控制 7x5 LED 矩阵以显示滚动文本。为了显示文本,我构建了一个字体,它与程序的其余部分一起存储在闪存中。 整个程序,包括整个字体,占用 1106 字节
我尝试使用 this Code/Guide在 ATmega1284p 上。 我遇到的问题是链接器不工作,执行后出现以下错误消息(代码为 ATmega88 构建良好): avr-ld -o main.
我原以为 8 位 AVR 平台不需要任何对齐。但是,我在 an LLVM commit 中发现了以下评论: The previous data layout caused issues when de
我想生成一个具有可变频率和固定占空比 (50%) 的 PWM 信号。频率应在 0-25KHz 之间变化。这是用于 ATMEGA32U4 微 Controller 的,我正在使用 Atmel Studi
我想生成一个具有可变频率和固定占空比 (50%) 的 PWM 信号。频率应在 0-25KHz 之间变化。这是用于 ATMEGA32U4 微 Controller 的,我正在使用 Atmel Studi
当我尝试使用 AVR studio 4 调试一小段代码时,出现此错误: Build failed... No build tools defined. 有人能给我一些建议吗? 最佳答案 在 AVRSt
我有一个设置为 CodeVision AVR 项目的遗留代码。我想迁移到 AVR Studio 甚至更好的 NetBeans(使用 AVR 工具链或 WinAVR)。 有什么想法吗? 最佳答案 你应该
我在以 AVR 为目标的 C 中遇到毫秒延迟循环的问题。我在从 Ubuntu 存储库获得的 Linux 上使用 avr-gcc 4.7.0,我也有尝试了新编译的 4.7.2。目标硬件是 XMEGA12
如何启用或禁用 IDE 的自动完成功能 AVR-Studio 5或 AVR-Studio 4 ?我是否必须编辑一些安装文件才能做到这一点? 视频中AVR Studio 5: How to use th
我正在尝试用 Arduino Eclipse 插件替换 Arduino IDE。下载所需的一切并尝试编译最简单的“Hello World”程序后,我在 eclipse 中遇到以下错误: 调用时: wh
我继承了一个链接到一个库的应用程序,该库可能是用 gcc3 构建的。或者也许使用 imagecraft 编译器。这些信息现在已经消失在天堂般的位域中,我只剩下一个 libXXX.a 库来链接我的应用程
我正在尝试通过 USBASP 编程器将一些数据从 PC 发送到 ATmega328P 芯片。 它能够通过 SPI 传输最多 4 个字节。这 4 个字节可以在 USB Setup Packet 中设置(
我正在使用 ATMEGA128 与另一台设备进行通信。为此,我使用带有 ATMEGA128 的 SPI 作为从机。我使用 SS、SCK 和 MOSI 引脚。我面临的问题是,当我必须下载程序时,我必须断
我有以下汇编代码: __asm__ __volatile__ ( "1: subi %0, 1" "\n\t" "brne 1b" : "=d" (__count)
大家好! 我的 DIY 洒水器和鱼缸自动化的 AVR 取得了很好的进展,但我遇到了一个问题,这让我很烦恼。 哪个 if 语句在 AVR 上运行得更快?(在更少的时钟周期内)多少? if(temp_se
我见过的所有示例 AVR 程序都以如下代码开头: .org $0000 rjmp Reset ; ... Reset: ; Start of program 如果我不使用任何中
我正在使用avr-gcc 4.8.2对Atmel ATtiny13a微 Controller 进行编程。 这是我的C代码: #include #include int main(void) {
所以,我使用的是 ATMega168与 NerdKits使用两个中断 INT0 和 INT1 设置并连接一个 LCD。我想附上 Grove Heart Rate Monitor ,我已附加到 PCIN
我是一名优秀的程序员,十分优秀!