Hi,I am a newbie.
I am reading timer/counter1 chapter (p115 )of 328p datasheet,I don't understand why use temporary register for high byte,why the low byte doesn't need the temporary register. And it only shows that how to read or write low byte but not mention about accessing the high byte.then the high byte copied to the temporary register.If you only access the low byte,why store the high byte to temporary?
next paragraph "To do a 16-bit write, the high byte must be written before the low byte. For a 16-bit read, the low byte must be read before the high byte." Is there any reason?
Thanks!
Hi,
The temporary register is shared between multiple 16 bit registers so they can be accessed with 8-bit reads. On page 114 it explains you don't do any of this, it's all done by the ATmega itself as it loads that temporary register with the high byte when you do a read of the low byte. You need to read the low byte first therefore to trigger this, as that temporary register would not yet contain what you expect it to if you reversed the read order.
The write operation happens in reverse so that when your low byte is written that triggers loading both halves including the temporary register you've already populated, into the actual 16 bit register.
Note that C takes care of this for you - and using the 16 bit variable of type unsigned int in the example on page 115 the register is read in one action, rather than the two byte read for the assembly example above that.
// from page 115
unsigned int i;
// ...snip...
/* Read TCNT1 into i */
i = TCNT1;
//rather than the equivalent lines in assembly which read the low byte then the high one
; Read TCNT1 into r17:r16
in r16,TCNT1L
in r17,TCNT1H
Hope this helps,
Geoff
But it still can't explain that why use the temporary register.
http://www.atmel.com/images/doc1493.pdf
According to the illustration, it is just an extra move load the high byte to temporary register , and load it to r17. why not just load directly to the r17 in second cycle?
Have a temporary register can't avoid the interrupt problem either if interrupt occurs between two operations.
yangkai:
But it still can't explain that why use the temporary register.
http://www.atmel.com/images/doc1493.pdf
According to the illustration, it is just an extra move load the high byte to temporary register , and load it to r17. why not just load directly to the r17 in second cycle?
Have a temporary register can't avoid the interrupt problem either if interrupt occurs between two operations.
the Timers are 16 bit devices, they count from 0 to 0xFFFF. Instead of assigning two 8bit register addresses for EACH timer, They (ATmel) built the AVR chip with a single shared 'high byte' register.
when you 'read' from one of the timers you get an 8bit value, that 8bit value is the low byte of the 16bit Timer value. When you read the Timer, the hardware stores the current high byte of that Timer in the shared 'high byte' register. So, to read the full 16bit Timer value, you read the Timer register(you get the lower 8bits), then you read the upper 8bits from the shared 'high byte' register. You put those two bytes together to get the 16bit Timer value.
Now writing to the 16bit timer is also a two step process, first you store the upper 8bits in the shared 'high byte' register, then you write the lower 8bits into the Timer register. When you write the 8bit value to the Timer register, the Hardware also copies the current value of the shared 'high byte' register in Timer.
Chuck.
I know it is 16-bit register so have to do 2 operations of read or write ,and they all share one temporary register.
BUT why not just load THE HIGH BYTE directly to the r17 in the second cycle?WHY LOW BYTE COULD ,BUT HIGH BYTE COULDN'T and have to load through the temporary register?
OR does it have a relation between "a single temporary reg. shared with all 16-bit registers" and "high byte only can be accessed through the temporary reg."? Otherwise why you guys keep mentioning that?
Thanks.
I notice that high byte & low byte have to be load to the reg. or write to the Timer/Counterat at the same time. I guess it has some restrictions that cause the reason.
yangkai:
I know it is 16-bit register so have to do 2 operations of read or write ,and they all share one temporary register.
BUT why not just load THE HIGH BYTE directly to the r17 in the second cycle?WHY LOW BYTE COULD ,BUT HIGH BYTE COULDN'T and have to load through the temporary register?
OR does it have a relation between "a single temporary reg. shared with all 16-bit registers" and "high byte only can be accessed through the temporary reg."? Otherwise why you guys keep mentioning that?
Thanks.
Each Write or Read instruction can only move 8bits at a time, the coding examples assume you have a 16bit value in R17:R16.
when you Read TCNT1L, with:
in r16,TCNT1L
the Timer Hardware moves a copy of the current high 8bits from the counter hardware into TCNT1H to guarantee that you will receive a value TCNT1 16bit value. The info in TCNT1H is the Timer1 high 8bits the last time you read the low 8 bits. It is NOT the CURRENT high 8bits of TIMER1.
You can read TCNT1H as many times as you want, It will NEVER change UNLESS you READ TCNT1L.
R17,R16 are just general purpose registers in the CPU. You do NOT have to use them to read the timers.
the following code is valid:
in r01,TCNT1L ; read the low 8bits into general purpose register 1
in r06,TCNT1H ; read the upper 8bits into general purpose register 6
; or if I really don't want to know the low 8 bits, just the upper 8bits
in r01,TCNT1L ; trigger the hardware to update TCNT1H
in r01,TCNT1H ; Actually read the high 8 bits, overwriting the low 8 bits,
Chuck.
atomicity.
That is why.
--- bill