This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

programming atmega



WHAT IS DIFFERENCE BETEEN THE BELOW TWO PROGRAMMES,AND WHAT IS THE NEED FOR MASKING , IS IT NECESSAERY TO DO SO!!!!!!!!!!!!
[[[[[
PORTB |= 1 << PINB0;
_delay_ms(100);
PORTB &= ~(1 << PINB0);
_delay_ms(100);

PORTB ^= 1 << PINB0;
_delay_ms(100);
]]]]]
.
.
..
.
.
.
.
.
.
[[[[[
DDRA=0xFF;
while(1)
{
PORTA=~PORTA;
_delay_ms(1000);
}
]]]]]]]]]]]

  • Wrong forum. You want the AVR Freaks.

  • While this is definitely the wrong forum (this is the TI MSP430 forum and you're asking a question about Atmel ATMega), the question is rather common to both (while the names of the registers differ).

    anirudh reddy said:
    WHAT IS DIFFERENCE BETEEN THE BELOW TWO PROGRAMMES

    Both, MSP430 adn ATMega, have no bit-addressable port pins. The port pins are grouped to eight port pins controlled by one register, one by each bit inside the register(s) connected with these pins.

    The first program inverts one bit of the Port B. The 'PINB0th' bit of PORTB. I guess it is BIT0, so PINB0 has the value 0 and the term 1<<PINB0 resolves to the value 1, BIT0 of a byte.

    The second program inverts ALL bits of PORTA, thus toggling eight port pins at the same time.

    The first program uses teh ^= operator, whcih does an exclusive oder of all bits. Since the second parameter is 0x01, BIT0 is toggled whiel all otehr bits stay the same.

    The second program assignes the inversion of the current value of PORTA to PORTA. It is logically the same as PORTA ^= 0xFF. Which probably would be the shorter and faster way in thsi case.

  • Jens-Michael Gross said:

    The first program inverts one bit of the Port B. The 'PINB0th' bit of PORTB. I guess it is BIT0, so PINB0 has the value 0 and the term 1<<PINB0 resolves to the value 1, BIT0 of a byte.

     Hi Jens, Anirudh, first program set one or more bit if BITB0 is different from zero, if it is bit zero then value is 1 and after shift it evaluate to 2 so it set BIT1 or I think something embedded in the mask BITB0 multiplied by 2.

     After 100mS the bit set on previous step get reset.

     What is done really to portb depend on value of mask value.

     I don't know nothing about atmega, I thrashed all away together with PIC a long time ago when I switched to MSP, my note is on a C programming result ;)

  • Jens-Michael Gross said:

    The second program assignes the inversion of the current value of PORTA to PORTA. It is logically the same as PORTA ^= 0xFF. Which probably would be the shorter and faster way in thsi case.

    While that's true for the MSP430 with its orthogonal address modes and Von Neumann architecture, for the AVR both approaches should result in the same read-modify-write instruction sequence, with only the modify part differing. I also don't know much about AVR, so just an observation from the microarchitectural view.
    Tony 
  • Roberto Romano said:
    first program set one or more bit if BITB0 is different from zero

    Not at all. It is exactly 1 bit toggled, because '1' is exactly one bit.

    The term '1<<BITB0' is the same as 1 * 2BITB0. Most likely, BITB0 is 0, BITB1 is 1, BITB2 is 2 etc. This notation was common in the ATMega project I've seen so far (and I adopted it for my own ATMega128 projects) However, I didn't use constants like BITB0 when I can as well spare the 'BITB' part. :) But of course I hat things liek 1<<LED1 (where LED1 was e.g. 5 for bit 5 of the port)

    Roberto Romano said:
    I thrashed all away together with PIC a long time ago when I switched to MSP,

    Didn't the PIC have bit-addressable port registers? The 8051 did for sure.

    TonyKao said:
    While that's true for the MSP430 with its orthogonal address modes and Von Neumann architecture

    This has nothing to do with orthogonal address modes (there is only one address mode used) and von-Neumann-Architecture (the access is to data memory in both cases and it doesn't count whether the instruction is in unified memory space or code memory space).

    It may have some impace considering that the MSP has a constant generator, so the 0xff is not required to be an explicit part of the instruction. But at the bottom line, it depends on the smartness of the compiler. The ^=0xff instruction is litterally an XOR #0xff,PORTA. The PORTA = ~PORTA, however, might be worst case parsed to MOV 0, y; SUB PORTA,y; MOV y, PORTA; Which of course may (but possibly won't) be reduced to the same XOR instruction. It all depends on the compiler, not the processor.

    And the fact that code size ad execution speed are different for the same source code on IAR, MSPGCC and CSS, tells that not all compilers are equally smart. But I agree that hsi case is a very simple case for proper code optimization.

  • The MSP430 can get the data/address directly from the "instruction " (the word following), whereas for Harvard you usually need a separate load.

    Also I take the orthogonal architecture to imply that (nearly) all instructions can use the same address modes, which is not the same as a load-store arch like most other RISCs. Actually that makes the MSP430 rather CISC-like, except for all the other stuff :)

    So for example PORTA = ~PORTA would result (presumably) on AVR a load of the address of the port, a load of the port register data, a not on the data, and a store. However for PORTA ^= 0xff, you need load of port address, load of register data, load of constant address, load of constant data, xor of the two, and then finally the store. Whereas for the MSP430 the two would be the same (and yes partly due to the constant generator).

    Tony

  • BTW, I think some MSP430 cross c-compilers will not generate "mov &src,&des;" but rather "mov &src,Rn; mov Rn,&des;"

  • old_cow_yellow said:

    BTW, I think some MSP430 cross c-compilers will not generate "mov &src,&des;" but rather "mov &src,Rn; mov Rn,&des;"

    That would be weird indeed. It may be that the compiler is using an optimization model based on some other (maybe generic) register-memory architecture that does not allow direct memory-memory operations.

  • TonyKao said:
    whereas for Harvard you usually need a separate load

    It has nothing to do with Harvard, but rather with the "one-instruction, one word" approach for a pipelined (!) RISC implementation, as parameter words won't fit the pipelining approach.

    However, I just compiled

      PORTF^=0xff;
      PORTF = ~ PORTF;

    with the AVRGCC and got the following result:

    lds r24,98
    com r24
    sts 98,r24

    lds r24,98
    com r24
    sts 98,r24
    (5 words, >=5 cycles)

    So on AVRGCC, the compiler is smart enough to see that both instructions are equivalent.
    Same for MSPGCC (on P1IN):

    F2E3 0002         inv.b    &0x200 + 0x00  (2 words, 4 cycles)
    (actually xor.b #0xffh, &0x200+0x00)

    The AVR obviously has instructions with different length, so it cannot use straight pipelining.
    As a result, the only advantage it can take from Harvard architecture is the larger address space.
    Reducing the instruction set (resulting in less capable instructions and therefore larger code) is no advantage for the ATMega.
    Also, the ATMega has a specific instruction for building the complement value while the MSP, thanks to the constant generator, can do it with the normal XOR isntruction.
    (AVRGCC wastes one processor register, r1,  to have at least a '0' constant available)

    Well, back to the original topic: at least for MSPGCC/AVRGCC the two notations are identical.
    Can't test it for GCC or IAR.

  • Ah jeez, I had naively conflated the C code with a straight 1-1 translation to assembly without regard to compiler optimization. My bad.

    Well, at least now you see why I much prefer writing high-level code for a good compiler than mucking around with assembly myself. Although, with someone like you, who needs optimizing compilers? ;)

    Tony

  • TonyKao said:

    BTW, I think some MSP430 cross c-compilers will not generate "mov &src,&des;" but rather "mov &src,Rn; mov Rn,&des;"

    That would be weird indeed. It may be that the compiler is using an optimization model based on some other (maybe generic) register-memory architecture that does not allow direct memory-memory operations.

    [/quote]

    Did PDP-11 use such an other (maybe generic) register-memory architecture? The compiler I mentioned (edited) could be traced to PDP-11.

  • old_cow_yellow said:

    Did PDP-11 use such an other (maybe generic) register-memory architecture? The compiler I mentioned (edited) could be traced to PDP-11.

    AFAIK PDP-11 uses the PC-relative address mode for immediate and absolute operands, as opposed to MSP430 which has both immediate and absolute addressing built-in directly into the instruction set. I think that may explain what's going on here if the compiler was a straight port from PDP-11 to the MSP430.

**Attention** This is a public forum