- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
要设置或清除寄存器中的位,我使用以下代码:
template<int... pos, class Int>
static constexpr void write_one(Int& i)
{
using expand = int[];
expand{0,((i |= (Int{1} << pos)), 0)...};
}
template<int... pos, class Int>
static constexpr void write_zero(Int& i)
{
using expand = int[];
expand{0,((i &= ~(Int{1} << pos)), 0)...};
}
它工作正常。为了测试它的效率,我写了 2 个测试函数:
// The most efficiency
while(1){
PORTB |= (1 << PB0);
PORTB &= ~(1 << PB0);
}
// This is the one I want to measure
while(1){
Bit::write_one<PB0>(PORTB);
Bit::write_zero<PB0>(PORTB);
}
当我用示波器测量时间时,第二个需要更多时间,所以我分解代码得到以下内容:
; This is the first one (of course, the most efficient)
000000c8 <_Z12testv>:
ce: 28 9a sbi 0x05, 0 ; 5
d0: 28 98 cbi 0x05, 0 ; 5
d2: fd cf rjmp .-6 ; 0xce <_Z12testv+0x6>
; The second one
000000c8 <_Z12testv>:
; The compiler optimize perfectly write_one<PB0>(PORTB)
ce: 28 9a sbi 0x05, 0 ; 5
; but, look what happens with write_zero<PB0>(PORTB)!!!
; Why the compiler can't write "cbi"???
; Here is the problem:
d0: 85 b1 in r24, 0x05 ; 5
d2: 90 e0 ldi r25, 0x00 ; 0
d4: 8e 7f andi r24, 0xFE ; 254
d6: 85 b9 out 0x05, r24 ; 5
d8: fa cf rjmp .-12 ; 0xce <_Z12testv+0x6>
我正在使用带有 -O3 标志的 avr-g++ 4.9.2。
最佳答案
template<int... pos, class Int>
static constexpr void write_one(Int& i)
{
using expand = int[];
expand{0,((i |= (Int{1} << pos)), 0)...};
}
template<int... pos, class Int>
static constexpr void write_zero(Int& i)
{
using expand = int[];
expand{0,((i &= ~(Int{1} << pos)), 0)...};
}
I
Bit::write_one<PB0>(PORTB);
Bit::write_zero<PB0>(PORTB);
int[2] { 0, ((i |= (Int{1} << pos)), 0) }
int[2] { 0, 0 } // a tmp that is a nop
(i |= (Int{1} << pos))
(i |= (decl_type(PORTB){1} << int { PB0 }))
PORTB 看起来像是一个可变的 uint5_t 可能值 0-31 ( AVR ),值为 0x5
(i |= ( uint5_t{1} << int {0}))
1 和 0 是文字/constexpr,所以它给出 1。
i |= 1
哪些代码生成
sbi 0x5, 0 // set port 5 bit 0
expand{0,((i &= ~(Int{1} << pos)), 0)...};
遵循相同的逻辑给出
(i &= ~(1))
给出代码
d0: 85 b1 in r24, 0x05 ; 5
d2: 90 e0 ldi r25, 0x00 ; 0 <---------- this value is not used nor set any flags???
d4: 8e 7f andi r24, 0xFE ; 254 (i &= ~(1))
d6: 85 b9 out 0x05, r24 ; 5
因此结论必须是 AVR 的代码生成中存在错误,因为它会生成虚假指令。
对ldi的解释
关于c++ - 如何优化 C++ avr 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49828829/
前言 众所周知,对于 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
我是一名优秀的程序员,十分优秀!