What's the difference between a "Single Channel Counter" (Timer2 on ATMega168) and the other timers?
2011-11-18 by Cat C
Yahoo Groups archive
Index last updated: 2026-04-28 22:41 UTC
Thread
2011-11-18 by Cat C
Hi, I'm trying to understand what "Single Channel Counter" means as a "Feature". Timers 0 and 1 don't mention being that, but as far as I can tell this is not about how many Output Compare units they have, 'cause they all have 2... Thanks, Cat [Non-text portions of this message have been removed]
2011-11-19 by Jim Wagner
On Nov 18, 2011, at 1:32 PM, Cat C wrote: > > Hi, > I'm trying to understand what "Single Channel Counter" means as a "Feature". > Timers 0 and 1 don't mention being that, but as far as I can tell this is not about how many Output Compare units they have, 'cause they all have 2... > Thanks, > Cat > > [Non-text portions of this message have been removed] > > It took some time to find the "feature" list you referenced, Its at the start of the Timer2 section. That seems to be the only place where "single channel" occurs in the whole document. That timer has no input capture, but DOES have an external clock input. It IS able to provide a variable-frequency, variable-dutycycle PWM using the two compare modules, using one to control TOP. but Timer0 seems to be able to do that also. Stumps me.... Jim Wagner Oregon Research Electronics [Non-text portions of this message have been removed]
2011-11-23 by fireweaver
[1]
While perusing the ATmega168A documentation, I discovered that NOWHERE
is it mentioned
concerning the byte order when a push or pop, call or return instruction
is issued.
So the first question is simple: When I call a subroutine, which byte
of the programme
counter is pushed first: The high byte or the low byte? The important
reason is below.
[2]
The following question is a little more complex:
I sometimes write subroutines (on other CPUs) that take either constant
arguments
or pointers to variables coded inline with the subroutine call.
An example of such a call is shown below:
CALL some_procedure
.dw argument_1 ; constant or pointer argument
.db "some_text",0 ; constant text argument
....
return_point:
What happens is this:
The saved programme counter is popped into an index register. Bytes or
words are
read using the index and the index is incremented accordingly.
When the procedure is finished, the index is already pointing to the
correct return
point, so doing an indirect jump to the contents of the index register
returns you
to the caller. Alternatively, I can push the index back onto the stack
and do a
normal return instruction.
I'm thinking that such code would look like this:
rcall some_procedure
.dw argument_1
.dw argument_2
...
...
some_procedure:
pop ZL ; I'm not sure if this is the right order.
pop ZH ; when the stack is popped, it is back to the
state it
; ; was in before the call.
lsl ZL ; times two because LPM only extracts bytes.
rol ZH ; we lose the high bit so only the lower 32K
; can be addressed
...
procedure code goes here, using LPM reg,Z+ to load the registers
...
adiw Z,1 ; bump return address past last byte of parameters
lsr ZH
ror ZL ; adjust back to word format
ijmp ; return to caller
The question is this: Is this code correct?
Mostly, I use this with output routines that are called on to display
large amounts
of fixed text, such as instructions or help screens.
[3]
I have one final question that has nothing to do with stacks: When
using AVRstudio,
what is the correct programming protocol for use with an Arduino Mega
2560 board?
fireweaver
[Non-text portions of this message have been removed]2011-11-23 by wagnerj@proaxis.com
The Instruction Set document tells you a little more, but not everything. PUSH and POP are single byte operations, so the order is defined by your code. Note that, for large flash memory AVRs, the return addresses will be 3 bytes, not 2! I would simply make a very small test example, assemble it, and run it in the software emulator-debugger. You can see for yourself exactly what is happening with the stack. No great mysteries. Jim Wagner Oregon Research Electronics
> [1] > While perusing the ATmega168A documentation, I discovered that NOWHERE > is it mentioned > concerning the byte order when a push or pop, call or return instruction > is issued. > > So the first question is simple: When I call a subroutine, which byte > of the programme > counter is pushed first: The high byte or the low byte? The important > reason is below. > > > [2] > The following question is a little more complex: > > I sometimes write subroutines (on other CPUs) that take either constant > arguments > or pointers to variables coded inline with the subroutine call. > > An example of such a call is shown below: > > CALL some_procedure > .dw argument_1 ; constant or pointer argument > .db "some_text",0 ; constant text argument > .... > return_point: > > What happens is this: > > The saved programme counter is popped into an index register. Bytes or > words are > read using the index and the index is incremented accordingly. > When the procedure is finished, the index is already pointing to the > correct return > point, so doing an indirect jump to the contents of the index register > returns you > to the caller. Alternatively, I can push the index back onto the stack > and do a > normal return instruction. > > I'm thinking that such code would look like this: > > rcall some_procedure > .dw argument_1 > .dw argument_2 > ... > ... > > some_procedure: > pop ZL ; I'm not sure if this is the right order. > pop ZH ; when the stack is popped, it is back to the > state it > ; ; was in before the call. > lsl ZL ; times two because LPM only extracts bytes. > rol ZH ; we lose the high bit so only the lower 32K > ; can be addressed > ... > procedure code goes here, using LPM reg,Z+ to load the registers > ... > adiw Z,1 ; bump return address past last byte of > parameters > lsr ZH > ror ZL ; adjust back to word format > ijmp ; return to caller > > The question is this: Is this code correct? > > Mostly, I use this with output routines that are called on to display > large amounts > of fixed text, such as instructions or help screens. > > [3] > I have one final question that has nothing to do with stacks: When > using AVRstudio, > what is the correct programming protocol for use with an Arduino Mega > 2560 board? > > fireweaver > > > > > [Non-text portions of this message have been removed] > >
2011-11-23 by fireweaver
Does the AVR studio simulator truly mimic the AVR hardware exactly as far as push and pop order? If it does, I suppose I could try that instead and do the final smoke test when I get my hardware.
On 11/23/2011 3:16 PM, wagnerj@proaxis.com wrote: > The Instruction Set document tells you a little more, but not everything. > PUSH and POP are single byte operations, so the order is defined by your > code. Note that, for large flash memory AVRs, the return addresses will be > 3 bytes, not 2! > > I would simply make a very small test example, assemble it, and run it in > the software emulator-debugger. You can see for yourself exactly what is > happening with the stack. No great mysteries. > > Jim Wagner > Oregon Research Electronics > >> [1] >> While perusing the ATmega168A documentation, I discovered that NOWHERE >> is it mentioned >> concerning the byte order when a push or pop, call or return instruction >> is issued. >> >> So the first question is simple: When I call a subroutine, which byte >> of the programme >> counter is pushed first: The high byte or the low byte? The important >> reason is below. >> >> >> [2] >> The following question is a little more complex: >> >> I sometimes write subroutines (on other CPUs) that take either constant >> arguments >> or pointers to variables coded inline with the subroutine call. >> >> An example of such a call is shown below: >> >> CALL some_procedure >> .dw argument_1 ; constant or pointer argument >> .db "some_text",0 ; constant text argument >> .... >> return_point: >> >> What happens is this: >> >> The saved programme counter is popped into an index register. Bytes or >> words are >> read using the index and the index is incremented accordingly. >> When the procedure is finished, the index is already pointing to the >> correct return >> point, so doing an indirect jump to the contents of the index register >> returns you >> to the caller. Alternatively, I can push the index back onto the stack >> and do a >> normal return instruction. >> >> I'm thinking that such code would look like this: >> >> rcall some_procedure >> .dw argument_1 >> .dw argument_2 >> ... >> ... >> >> some_procedure: >> pop ZL ; I'm not sure if this is the right order. >> pop ZH ; when the stack is popped, it is back to the >> state it >> ; ; was in before the call. >> lsl ZL ; times two because LPM only extracts bytes. >> rol ZH ; we lose the high bit so only the lower 32K >> ; can be addressed >> ... >> procedure code goes here, using LPM reg,Z+ to load the registers >> ... >> adiw Z,1 ; bump return address past last byte of >> parameters >> lsr ZH >> ror ZL ; adjust back to word format >> ijmp ; return to caller >> >> The question is this: Is this code correct? >> >> Mostly, I use this with output routines that are called on to display >> large amounts >> of fixed text, such as instructions or help screens. >> >> [3] >> I have one final question that has nothing to do with stacks: When >> using AVRstudio, >> what is the correct programming protocol for use with an Arduino Mega >> 2560 board? >> >> fireweaver >> >> >> >> >> [Non-text portions of this message have been removed] >>
2011-11-24 by Jim Wagner
I don't know that it does, but its a core operational detail that I would expect some care to have been applied. Jim Wagner On Nov 23, 2011, at 1:33 PM, fireweaver wrote: > > Does the AVR studio simulator truly mimic the AVR hardware exactly as > far as push and pop order? > If it does, I suppose I could try that instead and do the final smoke > test when I get my hardware. > > On 11/23/2011 3:16 PM, wagnerj@proaxis.com wrote: > > The Instruction Set document tells you a little more, but not everything. > > PUSH and POP are single byte operations, so the order is defined by your > > code. Note that, for large flash memory AVRs, the return addresses will be > > 3 bytes, not 2! > > > > I would simply make a very small test example, assemble it, and run it in > > the software emulator-debugger. You can see for yourself exactly what is > > happening with the stack. No great mysteries. > > > > Jim Wagner > > Oregon Research Electronics > > > >> [1] > >> While perusing the ATmega168A documentation, I discovered that NOWHERE > >> is it mentioned > >> concerning the byte order when a push or pop, call or return instruction > >> is issued. > >> > >> So the first question is simple: When I call a subroutine, which byte > >> of the programme > >> counter is pushed first: The high byte or the low byte? The important > >> reason is below. > >> > >> > >> [2] > >> The following question is a little more complex: > >> > >> I sometimes write subroutines (on other CPUs) that take either constant > >> arguments > >> or pointers to variables coded inline with the subroutine call. > >> > >> An example of such a call is shown below: > >> > >> CALL some_procedure > >> .dw argument_1 ; constant or pointer argument > >> .db "some_text",0 ; constant text argument > >> .... > >> return_point: > >> > >> What happens is this: > >> > >> The saved programme counter is popped into an index register. Bytes or > >> words are > >> read using the index and the index is incremented accordingly. > >> When the procedure is finished, the index is already pointing to the > >> correct return > >> point, so doing an indirect jump to the contents of the index register > >> returns you > >> to the caller. Alternatively, I can push the index back onto the stack > >> and do a > >> normal return instruction. > >> > >> I'm thinking that such code would look like this: > >> > >> rcall some_procedure > >> .dw argument_1 > >> .dw argument_2 > >> ... > >> ... > >> > >> some_procedure: > >> pop ZL ; I'm not sure if this is the right order. > >> pop ZH ; when the stack is popped, it is back to the > >> state it > >> ; ; was in before the call. > >> lsl ZL ; times two because LPM only extracts bytes. > >> rol ZH ; we lose the high bit so only the lower 32K > >> ; can be addressed > >> ... > >> procedure code goes here, using LPM reg,Z+ to load the registers > >> ... > >> adiw Z,1 ; bump return address past last byte of > >> parameters > >> lsr ZH > >> ror ZL ; adjust back to word format > >> ijmp ; return to caller > >> > >> The question is this: Is this code correct? > >> > >> Mostly, I use this with output routines that are called on to display > >> large amounts > >> of fixed text, such as instructions or help screens. > >> > >> [3] > >> I have one final question that has nothing to do with stacks: When > >> using AVRstudio, > >> what is the correct programming protocol for use with an Arduino Mega > >> 2560 board? > >> > >> fireweaver > >> > >> > >> > >> > >> [Non-text portions of this message have been removed] > >> > > [Non-text portions of this message have been removed]
2011-11-24 by fireweaver
I made the assumption that the simulator was correct (I've read chatter to the effect that it has problems) but it seems that I have answered my own question about push and pop order, to wit: On my ATmega168A, On calls and interrupts, push low PC first, then high PC. On returns, pop high PC, then low PC. I'm going to guess that this is the standard pattern for all AVRs. It seems like a trivial matter, but in any case, Atmel needs to mention that in their datasheets, considering that this can be useful information for those of us who work in assembler. fireweaver
On 11/23/2011 10:31 PM, Jim Wagner wrote: > I don't know that it does, but its a core operational detail that I would expect some care to have been applied. > > Jim Wagner > > On Nov 23, 2011, at 1:33 PM, fireweaver wrote: > >> Does the AVR studio simulator truly mimic the AVR hardware exactly as >> far as push and pop order? >> If it does, I suppose I could try that instead and do the final smoke >> test when I get my hardware. >> >> On 11/23/2011 3:16 PM, wagnerj@proaxis.com wrote: >>> The Instruction Set document tells you a little more, but not everything. >>> PUSH and POP are single byte operations, so the order is defined by your >>> code. Note that, for large flash memory AVRs, the return addresses will be >>> 3 bytes, not 2! >>> >>> I would simply make a very small test example, assemble it, and run it in >>> the software emulator-debugger. You can see for yourself exactly what is >>> happening with the stack. No great mysteries. >>> >>> Jim Wagner >>> Oregon Research Electronics >>>
2011-11-24 by Don Kinzer
--- In AVR-Chat@yahoogroups.com, fireweaver <firewevr@...> wrote: > On calls and interrupts, push low PC first, then high PC. That is correct. Note, too, that on devices with more than 128K of flash (e.g. mega2560 or xmega128A1) the third, most significant, byte of the PC is pushed last. I've always thought that this order was odd for the AVR since the return address ends up in big-endian form in RAM. Don Kinzer ZBasic Microcontrollers http://www.zbasic.net
2011-11-25 by fireweaver
I'm new to the AVR, but it does seem to be a bit odd. I was trying to keep ZH:ZL in sync with PCH:PCL and this is what seems to work. fireweaver
On 11/24/2011 11:02 AM, Don Kinzer wrote: > --- In AVR-Chat@yahoogroups.com, fireweaver<firewevr@...> wrote: >> On calls and interrupts, push low PC first, then high PC. > That is correct. Note, too, that on devices with more than 128K of flash (e.g. mega2560 or xmega128A1) the third, most significant, byte of the PC is pushed last. > > I've always thought that this order was odd for the AVR since the return address ends up in big-endian form in RAM. > > Don Kinzer > ZBasic Microcontrollers > http://www.zbasic.net > > >