AVR-GCC是否可以正确使用16位AVR I/O寄存器? [英] Does AVR-GCC properly work with 16-bit AVR I/O registers?

查看:116
本文介绍了AVR-GCC是否可以正确使用16位AVR I/O寄存器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

众所周知,对于16位I/O寄存器(计时器,ICR/OCR,ADC ...)的高低部分的原子和同时读/写,AVR使用影子临时寄存器.例如.在ATmega8上读取TCNT1:

It's known that for atomic and simultaneous reading/writing high and low part of 16-bit I/O registers (timer-counters, ICR/OCR, ADC...) AVR uses a shadow temporary register. E.g. reading TCNT1 on ATmega8:

uint8_t tl, th;
tl = TCNT1L;   // tl <- TCNT1L, avr_temp <- TCNT1H (atomic)
th = TCNT1H;   // th <- avr_temp

(此处avr_temp是AVR临时影子寄存器).因此,例如,先阅读TCNT1H是错误的.

(Here avr_temp is the AVR temporary shadow register). So, it's wrong to read TCNT1H first, for example.

将AVR-GCC与以下代码一起使用是否安全?

Is it safe to use AVR-GCC with the code like the following?

uint16_t ticks;
ticks = TCNT1;
TCNT1 = 0x1234;

AVR-GCC会始终为这些操作生成适当的代码吗?

Will AVR-GCC always generate proper code for these operations?

(似乎是否"(GCC如何知道访问由TCNT1指向的内存使用了AVR影子寄存器?),但是avr-libc定义了宏TCNT1以及TCNT1H,TCNT1L和 avr-libc常见问题解答建议直接使用TCNT1.我很困惑.)

(It seems to be "no" (how GCC knows that accessing to memory pointed by TCNT1 uses AVR shadow register?), but avr-libc define macro TCNT1 as well as TCNT1H, TCNT1L and avr-libc' FAQ recommend to directly use TCNT1. I'm confused.)

我测试了AVR-GCC v4.7.2,它似乎总是能生成正确的代码.即使我写了"TCNT1 | = 1",它也会用-O3产生正确的代码:

I tested AVR-GCC v4.7.2, and it seems to generate correct code always. Even if I write 'TCNT1 |= 1' it produce proper code with -O3:

$ avr-gcc -std=c99 -mmcu=atmega8 -S -O3 -o - 1.c
...
in r24,0x2c     // TCNT1L
in r25,0x2c+1   // TCNT1H
ori r24,1
out 0x2c+1,r25
out 0x2c,r24
...

即使使用普通的16位变量更改TCNT1,代码也相同.因此,"GCC如何知道访问TCNT1所指向的存储器使用了AVR影子寄存器?" -在默认情况下,当访问任何 16位变量时,似乎总是假定影子寄存器 .

The code is the same even if I change TCNT1 with an ordinary 16-bit variable. So, "how does GCC know that accessing memory pointed by TCNT1 uses the AVR shadow register?" -- it seems by default to suppose the shadow register always when accessing any 16-bit variable.

推荐答案

我不知道它怎么知道,但是我已经直接在许多程序中使用TCNT1了,没有问题. 您链接的常见问题解答建议您采用这种方式,就像我读过的每个教程一样.

I don't know how it knows, but I've used TCNT1 directly in dozens of programs without issue. The FAQ you linked suggests you do it that way, as does every tutorial I've read.

常见问题解答的目的是确保在两个寄存器的写入之间不会发生中断.尽管avr-gcc会生成按正确顺序访问它们的代码,但不能保证它们之间不会发生中断:您必须注意这一点.

The point the FAQ is making is to assure an interrupt can't happen between the writing of the two registers. Though avr-gcc will generate code that accesses them in the correct order, it can't guarantee an interrupt won't happen between them: you must take care of that.

这篇关于AVR-GCC是否可以正确使用16位AVR I/O寄存器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆