Mega48 ????

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I just got my order of mega48's (14x)
I just started writing some assembly code, but it seems like the "OUT" function only works for a very narrow range of adresses.
Can't use it to set the UART baud rate regs, nor the timer setup.
I managed to make it work using ST (y) and setting up the Y register whit the pointer to UBRR0H.

Is this chip really this hard to work whit?
Only able to use the IN/OUT instruction for the IO ports????

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I/O registers (that is, registers that are used to control "peripheral" hardware like timers & ports) are mapped as part of the SRAM space. Some, however, have a second address mapping that works with the "in" and "out" operations.

In the older AVRs with fewer I/O registers, there was room in the I/O address space for all of the registers. That isn't true any more.

Generally, it has been set up so that registers that are not used as often are outside the I/O address space.

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe I should have looked deeper into the manual before I ordered them.. Huh?
Frack... I just wanted a 20MHz chip for my PWM stepper circuits ><

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The in/out command can only address registers from 0-63. With the earlier AVR's this wasn't a problem, but as larger micros were introduced with more features and periferals, they quickly grew above that address limit. As you have discovered. anything above 63 requires the LDx/STx commands. You don't need to use the pointer registers, you could use sts/lds instead. Here's a similar init for a Mega128

        clr     r16
        sts     UBRR1H,r16
        ldi     R16,23                          ;Baud rate = 19.2 Kbps
        sts     UBRR1L,R16
        clr     r16
        sts     UCSR1A,r16                      ;make sure U2X is 0
        ldi     r16,(1<<RXEN)|(1<<TXEN)
        sts     UCSR1B,R16                      ;Enable rcx & tcx, 8-bit mode
        ldi     r16,3<<UCSZ0
        sts     UCSR1C,r16                      ;8-N-1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try using these macros -

	.macro	ini
	.if	@1<0x40
	in	 @0,@1
	.else
	lds	@0,@1
	.endif
	.endm

	.macro	outi
	.if	@0<0x40
	out	@0,@1
	.else
	sts	@0,@1
	.endif
	.endm

Just use "ini" instead of "in" and "outi" instead of "out" in your code, and the macros take care of the instruction format.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
s this chip really this hard to work whit?

Yes ... No ... well ....

Check section 6.2 in the datasheet (SRAM Data Memory)
And section/table 29 (Register summary) ...
And instead of using indirect addressing (ST, Y) You can use direct addressing with STS and LDS:

Uart "driver" for Mega168

init_uart:
  ldi   tempreg, hi8(BAUDRATE)
  sts   _SFR_MEM_ADDR(UBRR0H), tempreg
  ldi   tempreg, lo8(BAUDRATE)
  sts   _SFR_MEM_ADDR(UBRR0L), tempreg

  ldi   tempreg, _BV(RXEN0)|_BV(TXEN0)
  sts   _SFR_MEM_ADDR(UCSR0B), tempreg
ret

uart_tx_byte:
  lds   pollreg, _SFR_MEM_ADDR(UCSR0A)
  sbrs  pollreg, UDRE0
  rjmp  uart_tx_byte
  sts   _SFR_MEM_ADDR(UDR0), tempreg
ret

uart_rx_byte:
  lds   pollreg, _SFR_MEM_ADDR(UCSR0A)
  sbrs  pollreg, RXC0
  rjmp  uart_rx_byte
  lds   tempreg, _SFR_MEM_ADDR(UDR0)
ret

Or You could use C ...

/J

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You don't need a pointer register; direct addressing can be used. Here are a couple of fragments of I/O register init from a CodeVision C startup sequence:

         ;    1782 PORTB=0x01;
0004c2 e0e1      	LDI  R30,LOW(1)
0004c3 b9e5      	OUT  0x5,R30
         ;    1783 DDRB=0x39;
0004c4 e3e9      	LDI  R30,LOW(57)
0004c5 b9e4      	OUT  0x4,R30

PORTB and DDRB are at I/O addresses 0x04 and 0x05 (and are also mapped to SRAM addresses 0x24 and 0x25) and can be reached by the IN/OUT/SBI/etc. instructions.

         ;    1793 DIDR0=0x3B;
0004cd e3eb      	LDI  R30,LOW(59)
0004ce 93e0 007e 	STS  0x7E,R30

DIDR0 cannot be reached by the IN/OUT/SBI/etc. instructions, only via the 0x7e SRAM address. The sequence is one more flash word, one more cycle.

Quote:

Is this chip really this hard to work whit?

I don't find it a lot harder or a lot easier to work with than other microcontroller families. Once familiar, the 32 registers give a lot more "power" than the single-accumulator architectures, even though some have special uses (e.g., pointers, multiply results, flash read result).

This topic can easily become Processor Wars. ;) I guess that you have to use what you feel is best. Many new users are swamped with the combinations of the dozen or so fuse bits that need to be appropriately set to operate in your target configuration. Once experienced the power of being able to configure your single Mega48 in many different ways to become many "models" is greatly appreciated.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

AAAAAHHHH!!!!!
Just when I finished rewriting 60+ lines of I/O ASM code I wrote for the Mega8, using all indirect adressing, you come and tell me about "STS/LDS" !!!!!!!!!
/me feel like yelling! (Also feel pretty stupid)

I really liked that macro-diddy from peret... Really neat trick.
I'm debating to go through my code again to remove the indirect stuff, to free up the Z register (wich is getting a real workout).

theusch wrote:
I don't find it a lot harder or a lot easier to work with than other microcontroller families.

This is the first of the "new and improved" AVR chips I've got my hands on. All my other AVR parts had peripherals that could be accessed through the I/O memory. No fiddling about the SRAM space.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

No fiddling about the SRAM space.

An AVR ASM application without a bunch of LDS/STS somewhere?!? Yeah, I suppose, on a Tiny with no SRAM. But rare.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DukerX wrote:
AAAAAHHHH!!!!!
Just when I finished rewriting 60+ lines of I/O ASM code I wrote for the Mega8, using all indirect adressing, you come and tell me about "STS/LDS" !!!!!!!!!
/me feel like yelling! (Also feel pretty stupid)

He he ... Been there, done that :-)
I wrote a simple UART bootloader for the Mega8, and went through the same thing when I bought a couple of Mega168:s ...
The most annoying thing IMO is that the UART examples in the datasheet for the 48/88/168 are written with IN/OUT and sbis directly on the UCSRnX registers ...+ a note : 'See "About Code Examples" on Page 6' ... So, after a lot of "WTF":s and "Aaaarghs" e.t.c I finally turned to page 6 and: :idea: :oops: ...

Quote:

I really liked that macro-diddy from peret... Really neat trick.
I'm debating to go through my code again to remove the indirect stuff, to free up the Z register (wich is getting a real workout).

You only have to do that once ...

/J