[AVR C] which register names to use - Page 1
Forum section: electronics / general

author: Simon
author_rank: Unknown
timestamp: September 04, 2018, 08:42:28 pm
content: Looking in the io file for the ATmega4809 I see what appears to be 2 ways of defining register addresses:#define RTC_CTRLA _SFR_MEM8(0x0140)and then there seems to be struct variables that also refor to the same thing like RTC.CTRLAWhich one should I use? I suspect that most of what is in this file is actually part of the middleware for atmel start that I gave up on as it seems incomplete.Am i safe to just write values to RTC_CTRLA ? I'm sure this is all i did in the past.I found this stuff that is not too clear to me:https://www.nongnu.org/avr-libc/user-manual/group__avr__sfr__notes.html

author: ajb
author_rank: Super Contributor
timestamp: September 05, 2018, 01:28:23 am
content: The struct style is more common on more complicated MCUs, I think Atmel started going that direction with the XMega line, and it's quite common on ARMs etc. It's generally a lot more convenient because it makes it easier to retarget different peripheral instances, and you can do things like store a pointer to the peripheral as part of the context for a protocol driver, which simplifies code reuse and improves the decoupling of higher- and lower-level code.But for little 8-bitters it generally doesn't matter so much. I would probably use the structs if they were available because it is a bit nicer and it's what I'm used to with ARM, but the directly defined registers should work just as well. There may be some performance implications between the different approaches, especially given the AVR's architecture, but this is probably not a concern for most applications.

author: Simon
author_rank: Unknown
timestamp: September 05, 2018, 06:08:14 am
content: Well I am starting to wonder, if the registers are now variables what about RAM usage?

author: rjp
author_rank: Regular Contributor
timestamp: September 05, 2018, 06:27:41 am
content: the memory interface to the builtin features on the MCU are not part of the user ram.the constant or the struct definition are just different approaches to addressing the exact same place in the memory model.

author: Simon
author_rank: Unknown
timestamp: September 05, 2018, 06:36:58 am
content: ah of course, doh!

author: T3sl4co1l
author_rank: Super Contributor
timestamp: September 05, 2018, 05:01:09 pm
content: Well, I mean -- theyareRAM, and some scratch registers are actually provided for that purpose (or, there are on some in the family, anyway). And you could use unused (disabled) peripherals as even more RAM if you really needed to. In this way, you can probably "free" up, on the order of 100s of bytes, depending on how much crap you can tolerate (peripherals going batshit from the data you're putting into them, pins emitting patterns and sequences you may not have intended; and possibly more power consumption as a result of this).Also doesn't help that many registers have unimplemented bits that always read zero.You aren't going to be using these in any ordinary compiler, though; it would be for hacks only.Tim

author: westfw
author_rank: Super Contributor
timestamp: September 06, 2018, 08:14:04 am
content: If you have a series of modifications to make to a particular peripheral, like:#include <avr/io.h>Code:void individ_regs() {USART0_CTRLA = 0x12;USART0_CTRLB = 0x34;USART0_CTRLC = 0x56;USART0_CTRLD = 0x78;USART0_BAUDL = 0x9A;USART0_BAUDH = 0;}int main(){individ_regs();VPORTA_OUT |= 8;USART0.CTRLA = 0x12;USART0.CTRLB = 0x34;USART0.CTRLC = 0x56;USART0.CTRLD = 0x78;USART0.BAUDL = 0x9A;USART0.BAUDH = 0;}the second form will end up producing a bit less code, because the compiler is able to load the peripheral base address once and use a sequence of (2 byte) "STD Z+x, rNN" instructions instead of having to implement each store separately with a (4-byte) "STS addr, rNN" instruction:Code:void individ_regs() {USART0_CTRLA = 0x12;b8: 82 e1 ldi r24, 0x12ba: 80 93 05 08 sts 0x0805, r24USART0_CTRLB = 0x34;be: 84 e3 ldi r24, 0x34c0: 80 93 06 08 sts 0x0806, r24USART0_CTRLC = 0x56;c4: 86 e5 ldi r24, 0x56c6: 80 93 07 08 sts 0x0807, r24USART0_CTRLD = 0x78;ca: 88 e7 ldi r24, 0x78cc: 80 93 0a 08 sts 0x080A, r24USART0_BAUDL = 0x9A;d0: 8a e9 ldi r24, 0x9Ad2: 80 93 08 08 sts 0x0808, r24USART0_BAUDH = 0;d6: 10 92 09 08 sts 0x0809, r1da: 08 95 retint main(){individ_regs();dc: 0e 94 5c 00 call 0xb8 ; 0xb8 <individ_regs>VPORTA_OUT |= 8;e0: 0b 9a sbi 0x01, 3 ; 1USART0.CTRLA = 0x12;e2: e0 e0 ldi r30, 0x00e4: f8 e0 ldi r31, 0x08e6: 82 e1 ldi r24, 0x12e8: 85 83 std Z+5, r24USART0.CTRLB = 0x34;ea: 84 e3 ldi r24, 0x34ec: 86 83 std Z+6, r24USART0.CTRLC = 0x56;ee: 86 e5 ldi r24, 0x56f0: 87 83 std Z+7, r24USART0.CTRLD = 0x78;f2: 88 e7 ldi r24, 0x78f4: 82 87 std Z+10, r24USART0.BAUDL = 0x9A;f6: 8a e9 ldi r24, 0x9Af8: 80 87 std Z+8, r24USART0.BAUDH = 0;fa: 11 86 std Z+9, r1 ; 0x09}fc: 80 e0 ldi r24, 0x00fe: 90 e0 ldi r25, 0x00100: 08 95 ret