Making a pulse with Assembly using IDE

Hi guys;

I am trying to code assembly within my IDE sketch. I tying to figure out those sites : Inline Assembler Cookbook and Arduino Playground - AVR and the datasheet of the ATMega328.

Here my code and I hope you guys will help me out. Sorry for the "noob" question.

void setup()
{
  pinMode(12, OUTPUT); 
 __asm__("LDI r16,0x10\n\t"); // set data to send to port B B00010000 = 16 = Ox10
 __asm__("LDI r17,0x0\n\t"); // set data to send port B = 0
}

void loop()
{
  // send a pulse to pin 12  --- program not compiling
  __asm__("OUT PORTB,r16\n\t"
          "nop\n\t"
          "OUT PORTB,r17\n\t"
          "nop\n\t"
          "JMP ????\n\t"); // I want to jump to OUT PORTB, r16 
  
  /* Here I want to do : The assembly code  
  
  main :    ldi r16, $10
              ldi r17, $0
  stloop :  out PORTB, r16
            nop
            out PORTB, r17
            nop
            jmp stloop
 */           

}

I change my code and it work, but I still don't know how to "jump" to OUT port b, r16. Maybe I need an address location to jump like asm("JMP 0x????\n\t"); Maybe take the Program Counter value ?

I use while(1==1) I change the PORTB to 0x05 <-- The port address/register location - Register summary - page 423 ( see ATMega328_Data_Sheet.pdf from Atmel web site )

Here my code and I add a picture of the wave form to prove it work.

Quick question : What is the \n\t ?

/* Program compile and tested. But it is not compiling when I use 
__asm__("OUT PORTB, r16\n\t"); I know the system need a data so I use 
the register location for Port B

*/

void setup()
{
  pinMode(12, OUTPUT); 
 __asm__("LDI r16,0x10\n\t"); // set data to send to port B B00010000 = 16 = Ox10
 __asm__("LDI r17,0x0\n\t"); // set data to send port B = 0
}

void loop()
{
  // send a pulse to pin 12  
  while(1==1)
  {
  __asm__("OUT 0x05,r16\n\t"
          "nop\n\t"
          "OUT 0x05,r17\n\t"
          "nop\n\t"
          "OUT 0x05,r16\n\t"
          "nop\n\t"
          "OUT 0x05,r17\n\t");
  }       
        //  "JMP ????\n\t"); // I want to jump to OUT PORTB, r16 
  
  /* Here I want to do : The assembly code  
  
  main :    ldi r16, $10
            ldi r17, $0
  stloop :  out PORTB, r16
            nop
            out PORTB, r17
            nop
            jmp stloop
 */           

}

What is the \n\t ?

\n = newline
\t = tab

it takes care that formatting is correct for the assembler I guess. First position is for labels, second for operands, rest for registers or so. :wink:

loop() itself is called endlessly so you don't need the while (1==1), so something like below should work to (no assembly expert either )

void setup()
{
  pinMode(12, OUTPUT); 
 __asm__("LDI r16,0x10\n\t"); // set data to send to port B B00010000 = 16 = Ox10
 __asm__("LDI r17,0x0\n\t"); // set data to send port B = 0
}

void loop()
{
 __asm__("OUT 0x05,r16\n\t"
          "nop\n\t"
          "OUT 0x05,r17\n\t"
          "nop\n\t");
}

@robtillaart

Thank for replying. thank to tell me about \n\t. The reason I put while(1==1) { } , thank to johnwasser --> post http://arduino.cc/forum/index.php/topic,72049.0.html, the pulse is faster. I did that program without while(1==1) <-- like the program in your post, and the off delay after the 2 pulses is longer. So therefore I put the while(1==1) and it loop faster ( shorter off delay ). But I still don't know how to make more faster using the JMP instruction ( I know , it is a bit like a "GOTO" statement )

Anyway, it was my first attempt to use asm inside the IDE program. It was interresting. The asm instruction came from the Atmel website file name : ATmegainstruction.pdf and also ATmega328_Data_Sheet.pdf to understand the registers and address location of the ports.

It work. 8)

Thanks for the code robtillaart.It worked for me & was really interesting.

If you just need fast pulsing, you can use the on-chip timers for frequencies up to f_cpu/2. Saves writing in assembler (buerk!) and the CPU is free to do something else.

@tim7

Hum...timers... I have to look into it. Can you tell me a place to look ? and examples ?

@nayana

robtillaart code will simply give you a short pulse and a long delay because it have to go throught loop() again, my orginal code simply give you 2 short pulse and a small delay because I use while(1==1),it take less time to go through "that" loop, if you try my code ( check it with a scope ) and re-wrote my code without the while(), you will see the difference. ( Hope you are using a scope for this experiment. ) My code is in Assembler using the inline feature of the Arduino IDE.

I use LDI register, Byte to load into a register, use OUT Port#, register , to transfer the register value into that port # and NOP is simply Do Nothing.

It was a learning experience and to use ATMega328 Assembler.