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
*/
}
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.
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");
}
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.
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.
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.