I need some help with this one! I am a NewBee in the AVR world, but have been writing machine code since the days of DIGITAL COMPUTER and the PDP8. Remember, — every time you turned the machine on, you needed to toggle in a bootloader. Anyway, the problem at hand. My need is for a 50% duty cycle square wave. Only six (6) cycles, then fall through to a 10 ms delay, and return, forever! How simple could it be! If I use a “for” loop with PORTB |= xxx and PORTB &= ~xxx, It works just fine. No where near the desired 50% duty cycle, but it works. The following snippet of “in line” asm code is intended to mimic the “for” loop, and I should be able to tweak the duty cycle. If I look at the listing, it shows that compiler did exactly what I expected it to do. Then why does it not work at all ???
The processor is a POLOLU Baby “O”, with a Atmega168. I am using a IBM ThinkPad, running WindowsXP, Pro, if that matters!
//ASM test routine.
#include <stdint.h>
#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
int main(void) {
DDRB = 0x20; // Set data direction register,.
while(1) {
asm(" ldi r16, 0x20");
asm("L1: sbi 3,5");
/*
asm(" nop"); // Note A
asm(" nop");
asm(" nop");
asm(" nop");
*/
// asm(" cbi 3,5"); // Note B
// asm(" sbi 3,5");
asm(" cbi 3,5");
asm(" lsr r16");
asm(" lsr r16");
asm(" brne L1");
_delay_ms(.1);
} // End of "while".
} // End of "main"
The intent: To load a single bit in r16, (ldi r16, 0x20), to set PORTB bit 5 high, (sbi 3,5), to set bit 5 low, (cbi 3,5), to shift r16 by one bit, (lsr r16), to branch to L1, until r16 is zero, then exit. HOW SIMPLE. It just WON’T WORK!!! My scope shows only three (3) cycles! Not six, as desired, and, they are not 50% duty cycle, but for now, that is OK, the lsr and btne instructions will take a little extra time. To verify that the code is really manipulating PORTB pin 5, I enable the code shown as note B. Eureka, I now have six cycles. (I should have 12 cycles). Next, I enable the code shown as note A. I would expect to have the high side of the first cycle widened, the high side of the second cycle unchanged, the high side of the third cycle widened, and so on. But NO, ALL the cycles have a widened high side, and by exactly the same amount! HOW CAN THAT BE?