SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
User avatar
By roach
#10564
Predictably, I'm having trouble with my first AVR application (on an atmega128). Basically, I want to "walk" across 8 LEDs, lighting each one up in sequence (1-8 ), then back down again (8-1), forever. Only one LED should be lit up at a time. I've written both an assembler, and a C (AVR-GCC) version of the code, and neither one works.

details:

1) I have LEDs on each pin of PORTB.
2) PORTB is configured as all output (ie: DDRB=0xFF).
3) the other end of each LCD is connected to VCC (pin 21 of the atmega128).
4) The following fuses are "set" (ie: "checked off" in PonyProg): CKOPT, BOOTSZ1, BOOTSZ0, SUT1, SUT0. (I admit, I'm a little confused when it comes to fuses, so there might be something wrong here.)
5) I'm using the Atmega128 header board from sparkfun, with external 16MHz oscillator on XTAL.
6) no bootloader installed.
7) Here's the C code:
Code: Select all
#define F_CPU 16000000UL	//CPU-freq
#define DELAY_MS 100		//delay between LEDs

#include <util/delay.h>
#include <avr/io.h>

typedef unsigned char u08;
int main(void) 
{
	u08 temp=0xfe;

	DDRB = 0xff;
	PORTB=temp;
	while(1){

		//rotate left
		while (temp & 0x80){		//while high-bit is not 0
			temp=(temp << 1) | 0x01;
			PORTB=temp;
			_delay_ms(DELAY_MS);	//wait
		}

		//rotate right
		while (temp & 0x01){		//while lo-bit is not 0
			temp=(temp >>1) | 0x80;
			PORTB=temp;
			_delay_ms(DELAY_MS);	//wait
		}		
	}
}
Is there some obvious boneheaded thing I'm not thinking of?
By TSPRAP
#10565
Code: Select all
#include <util/delay.h>
I always use <avr/delay.h>.....

EDIT:Never Mind that is a different routine you are using.
By transcendentnb2
#10567
The newest libc with WinAVR has depreciated avr/delay.h

temp=(temp << 1) | 0x01;
...
temp=(temp >>1) | 0x80;


You're ORing when you shouldn't be. I take it you're getting a stream of LEDs walking across, instead of just 1?
User avatar
By roach
#10573
Actually, I'm getting nothing at all. None of the LEDs light up. What do you mean I'm ORing when I shouldn't be?

temp = 1111 1110
temp << 1 = 1111 1100
| 0x01 = 1111 1101

Since DDRB = 0xFF, a zero will bring the pin low, causing it to sink whatever current is coming from VCC (through the LED on that pin). At least I think thtat's what "output" means. Then again, I'm new at this, so...
By prologix
#10576
Code: Select all
while(1){

    //rotate left
    temp = 0x01;
    while ( temp )
        {
        PORTB = temp;
        _delay_ms(DELAY_MS);   //wait
        temp = temp << 1;
        }

    //rotate right
    temp = 0x80;
    while ( temp )
        {
        PORTB = temp;
        _delay_ms(DELAY_MS);   //wait
        temp = temp >> 1;
        }
}
User avatar
By roach
#10577
If I understand correctly, prologix (and there is every possibility that I don't), this is basically the opposite of what I want (there will always be 7 LEDs lit).

Even if my code doesn't do what I want it to, I should be seeing something. Instead, NONE of the LEDs are lighting, which leads me to suspect the problem is not in the code...
By transcendentnb2
#10579
If you're doing negative logic, your code works. If you're doing normal logic, prologix's code works.

Simple question... are your LEDs facing the right direction?

EDIT: So you don't damage anything, put a small resistor in series with each LED.
User avatar
By roach
#10583
transcendentnb2 wrote:If you're doing negative logic, your code works. If you're doing normal logic, prologix's code works.
Right, but either way, I should be seeing SOMETHING, shouldn't I?
Simple question... are your LEDs facing the right direction?
That was actually the first thing I checked :). The GND pin on the LED is tied to the PB pin, and VCC is tied to the VCC pin on the atmega (pin 21).
So you don't damage anything, put a small resistor in series with each LED.
I tried these LEDs naked on a 9V battery, and nothing blew up, so I'm pretty sure they're fine. I'm more concerned about the controller, but since the PB pins (should) output at GND - 5V, and I confirmed the VCC pin is ~5V, I think the controller is safe. (I think...)

I'm pretty sure the problem is either a lack of understanding on how the DDRB and PORTB registers work (ie: if DDRB is set to "all output", and , say, PB0 is set to 1, it should go low, right?), or else something's wrong with my fuse settings (like the AVR starts in the bootloader sector, and never jumps to my actual code, or something). Again, lack of understanding...

What do you mean by "negative" and "normal" logic? Does this have to do with the DDRB values?
By Philba
#10585
I've only done a few AVR projects so this may be obvious but
- did you verify that you actually programmed the device? can you read it back and get the same thing?
- is the uC actually running?

I'd reduce the program to just turning on half the LEDs and then sit in a tight loop. Use a DMM to look at the output of pins. I'd use a scope (10X probe, at least) to see if the xtal is oscillating. check Vcc and so on.
By transcendentnb2
#10588
roach wrote: I tried these LEDs naked on a 9V battery, and nothing blew up, so I'm pretty sure they're fine. I'm more concerned about the controller, but since the PB pins (should) output at GND - 5V, and I confirmed the VCC pin is ~5V, I think the controller is safe. (I think...)
You're basically shorting the uC port pins without the resistor. The LEDs normally drop 2.5-3.5v across them when in use. That means the extra 2.5-1.5v drop is going to be across the microcontroller, producing a lot of current. Even though devices can usually sink an order of magnitude more current than source, you're still running a risk of some damage somewhere and will see a greatly reduced battery life.

The code is fine. Simulate it.
By JonChandler
#10590
To explain transcendentnb2's reply a bit........

LEDs must be used with a series current limiting resistor. General-purpose LEDs typically want about 10 mA of current maximum. A series resistor of 2k - 5k ohms should make this work.
User avatar
By roach
#10592
- did you verify that you actually programmed the device? can you read it back and get the same thing?
Well the write operation in AVRDude performs an auto-verify, so yeah, I'm pretty sure it's actually written.
- is the uC actually running?
How can I tell without some sort of visual cue (ie: one of these fershlugginer LEDs lighting up)?
You're basically shorting the uC port pins without the resistor. The LEDs normally drop 2.5-3.5v across them when in use. That means the extra 2.5-1.5v drop is going to be across the microcontroller, producing a lot of current. Even though devices can usually sink an order of magnitude more current than source, you're still running a risk of some damage somewhere and will see a greatly reduced battery life.
Whoah! Good to know. I'll get right on that. Still doesn't explain why I'm seeing nothing at all, though. Unless I've already burnt out the uC.
The code is fine. Simulate it.
Yeah, it checks out fine in AVR Studio. Simulates the way I would expect.

EDIT:
I'd reduce the program to just turning on half the LEDs and then sit in a tight loop. Use a DMM to look at the output of pins. I'd use a scope (10X probe, at least) to see if the xtal is oscillating. check Vcc and so on.
I've tried all of this, except for the scope (I don't have one, and probably never will, at those prices). I'll re-check the pin output when I get home. I'm using the Atmega128 header board from Spakrfun, so I have to have faith that XTAL et. al. are properly hooked up...

...don't I?
By powool
#10598
If you're not sure the program is working, or that the processor is running, then simplify.

Toggle a single bit off and on, slowly. Use a hard coded delay loop (make sure the compiler doesn't optimize it out).

Or toggle it fast, and see if you get a half bright LED.

Check your LED's again with a resistor against a power supply, e.g. 220 ohm against 3.3V, 330 ohm against 5V. Make sure you didn't fry the LEDs running them wide open at 9 volts.

Check your assumptions, simplify the problem, you'll get there.

BTW, 100MHz Tek 465 scopes on eBay run $100-$200. 465B's maybe a little more. I haven't checked prices lately, they vary up and down according to how many are getting dumped on the surplus market.
User avatar
By roach
#10601
powool wrote:BTW, 100MHz Tek 465 scopes on eBay run $100-$200. 465B's maybe a little more. I haven't checked prices lately, they vary up and down according to how many are getting dumped on the surplus market.
Awesome!! This is still out of my range (right now), but at least I have something to look forward to :)

In case someone else is looking, and can afford it:

http://cgi.ebay.com/ws/eBayISAPI.dll?Vi ... 7595912888
By Philba
#10606
Even with autoverify, I'd try reading back the program to see if it's really really there. I always keep a slightly jaundiced eye on my tools...

I would power up the circuit (fixing the dropping resistor error) and take voltage measurements at every pin. something might turn up.

You don't really need LEDs, you can just use a DMM to see a slow "blink". If i have a spare pin, I use it for a heart beat. With a scope it's particularly useful but it's good with even an LED or DMM.

The reason I suggested to just turn some pins on and other off is that you should see Vcc (or close) on the "on" pins and 0 on the off ones. If you don't even see that there is something very amiss. also, try other pins in case you blew the LED ones.

edit: stupid question - are you compiling for the correct processor?