UART interrupt causes reset seizures

Go To Last Post
72 posts / 0 new

Pages

Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am having a problem receiving UART data using the interrupt vector on a mega16. If I send data to the UART, the avr resets after a random amount of time and does this as long as data keeps streaming to the port (in this case, from a GPS receiver). I've stripped away most of my other code and I am still experiencing the problem.

My code:

int main(void)
{
    avr_init();
	osd_init();
	printf("\nINIT DONE");
	_delay_ms(10);
	
	get_gps_data();
	
    for(;;)
	{
//loop forever
	}
    
    return(0);
}

static void avr_init(void)
{
	CSHIGH;		//pull MAX7456 CS high
	
	DDRA=0x00;	//all in, for adc
	DDRB=0xBF;	//MISO in, all the rest out
	DDRC=0xFF;	//all output
	DDRD=0x02;	//PD0=UART RXD (in), PD1=UART TXD (out)
	
	change_uart_baud(DEBUG_BAUDRATE);	//set debug baud rate
	uartInit();			//initialize uart
	select_uart(DEBUG_UART);	//set the 4052 mux to route the uart to the debug port
	
	printf("\x1b[1J\x1b[fPWR ON");
	printf("\n UART INIT");
	
	SpiMasterInit();	//initialize SPI
	printf("\n SPI INIT");
	
	sei();		//enable all interrupts
	
    return;
}

And here's the standard ISR code:

ISR(USART_RXC_vect)
{
	uint8_t data;
	data = UDR;
}

The OSD that you see in the code is a MAX7456 on-screen display IC and is controlled over the SPI port. You can also see that I've multiplexed the UART so there's a port for debugging and a port for the GPS receiver. Anyway I can't even get serial data in right now. It ought to be really simple, and I'm thinking this must be a simple problem, but I just can't figure it out. Any ideas?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You will be better off polling the input than having an ISR that eats and throws away any incoming RX.

Otherwise you need to use some working interrupt code.

In fact you probably need some code that works throughout.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Perhaps it is a stack overflow problem?

How much RAM does your AVR have and how much does the compiler report is being used?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Perhaps I’m confused but where are you putting the data received in UDR, It’s seems a local variable declared in a Interrupt Service.
May be you need a global variable and remember if you are optimizing with –Os declare as volatile the variables shared with the ISR.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
You will be better off polling the input than having an ISR that eats and throws away any incoming RX.

Well I'm dumping UDR into a local variable just to get the interrupt code to work first. I'm really not in the business of writing useless programs ;)

Quote:
How much RAM does your AVR have and how much does the compiler report is being used?

That's a good question. How do I check this when compiling with WinAVR? I'm using a Mega16 so I have 1024B of SRAM to work with, but not sure how much is being used.

Quote:
Otherwise you need to use some working interrupt code.

This is precisely what I am trying to do.

Quote:
May be you need a global variable and remember if you are optimizing with –Os declare as volatile the variables shared with the ISR.

I'll try that tomorrow morning and post back. Tis 12:30 AM right now, and I'm tirrred :wink:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Resets" after a while are often indicative of a small memory leak that slowly eats through available memory until something disastorous happens but "resets" can also occur if an enabled interrupt source fires without a handling ISR being made available (because all the vectors ottherwise point to vector_default: and there it has a JMP 0). So could it be that you've accidentally set an IE bit?

(we can't tell as there's bits of the code - the init routines - that you haven't shown)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you are using WinAVR through AVR Studio, the default settings will show a memory usage summary at the end of the compile. For example:

AVR Memory Usage
----------------
Device: atmega128

Program:     636 bytes (0.5% Full)
(.text + .data + .bootloader)

Data:         28 bytes (0.7% Full)
(.data + .bss + .noinit)

If you are using some other method to build, you can use the "avr-size" program to get the same information. For example, execute:

avr-size -C program.elf

You may be using more RAM than you think. Statements such as

printf("\nINIT DONE");

... will store the string in RAM, not just flash. Check out this tutorial if you want to know how to store the strings only in flash.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay I ran avr-size and got this:

AVR Memory Usage
----------------
Device: Unknown

Program:    2228 bytes
(.text + .data + .bootloader)

Data:         83 bytes
(.data + .bss + .noinit)

And here are my inits:

static void osd_init(void)
{
	osd_write(VM0_W,_BV(1));		//reset osd in case the cpu was reset but the osd was left on
	_delay_ms(100);					//wait for osd to finish resetting
	osd_write(VM0_W,_BV(3));		//enable OSD with auto sync
	
	osd_write_from_eeprom();		//write initial screen layout from eeprom
	
	select_camera(0);	//set 4051 mux to first camera
	
	printf("\n OSD INIT");
	
	return;
}

void SpiMasterInit(void)
{
    unsigned char tmp;
    
    if (bit_is_clear(DDRB, 0))	//Check whether PB0 is an input. 
	{
        PORTB |= _BV(0);		//If yes, activate the pull-up. 
    }

    DDRB |= _BV(1) | _BV(2);	//Switch SCK and MOSI pins to output mode. 
	PORTB |= _BV(3);			// Enable MISO pull-up. 
    SPCR = _BV(SPE) | _BV(MSTR);	//Activate the SPI hardware. 
	SPSR = _BV(SPI2X);	//double spi speed (if FOSC=16MHz, SPI CLK=8MHz)
 
    // Clear status flags. 
    tmp = SPSR;
    tmp = SPDR;
	
	return;
}

static void uartInit(void)
{
	UBRRH = (myubrr>>8);
    UBRRL = myubrr;
    UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
    UCSRC = (1<<URSEL)|(3<<UCSZ0);
    stdout = &mystdout; //Required for printf init
	
	return;
}

I tried dumping UDR to a global volatile variable, declared as "volatile uint8_t data;", but this did not change anything.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Check if you have any unwanted interrupts enabled:

ISR (BADISR_vect)
{
    // switch LED on here
}

If the LED lights up, you know that you have somewhere in your code an interrupt enabled but no ISR defined for it. Sometimes a simple typo in the interrupt vector name causes this trouble.

Regards
Sebastian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sebastian: I added that ISR as below:

ISR(BADISR_vect)
{
    PORTC|=_BV(5);	// switch LED on here
} 

but no joy :cry:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What behaviour of the AVR do you see when you say that the controller resets?

Regards
Sebastian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Check the reset source:

int main(void)
{
    PORTA = MCUCSR;
    MCUCSR = 0;
    DDRA = 0xFF;
    _delay_ms (2000);
    
    avr_init();
   osd_init();
   printf("\nINIT DONE");
   _delay_ms(10);
   
   get_gps_data();
   
    for(;;)
   {
        //loop forever
   }
   
    return(0);
}

After a reset the AVR will display for 2s the reset source on PORTA:
PA0==1 => Power On Reset
PA1==1 => External Reset
PA2==1 => Brownout Reset
PA3==1 => Watchdog Reset
PA4==1 => JTAG Reset
All zero => Software Reset

Maybe you have power supply problems.

Regards
Sebastian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

PORTA = MCUCSR;
    MCUCSR = 0;
    DDRA = 0xFF;
    _delay_ms (2000); 

Okay I stuck that code in, with the delay at 10s to give me time to check it with a multimeter, and got some truly strange results. It "resets" at the same rate as before -- no 10s delay. Which to me suggests that it's not "resetting" but rather it is running from avr_init onward.

Quote:
What behaviour of the AVR do you see when you say that the controller resets?

Every time the avr is powered on it sends this to the serial port of my pc (first clearing the terminal window with command '\x1b[1J\x1b[f'):

PWR ON
 UART INIT
 SPI INIT
 OSD INIT
INIT DONE

So when it "resets" I see this sequence repeated in the terminal window and also the video output from the on-screen display IC (MAX7456) flickers on the TV suggesting that osd_init() has been called.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Print the reset flags value instead (after uart init). Depending on what version of libc you are using, _delay_ms(2000) may not be what you think it is.

You could also just init the uart only, sei(), then sit in a loop, and in the rx irq, just do a UDR=UDR to echo. Send a bunch of data to the uart and see if it keeps working. If it keeps working, your problem would appear to be elsewhere.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Based on your avr-size results, you should have plenty of space for the stack.

Maybe it is a problem with the watch dog timer. Are you sure the fuse isn't set to enable the watch dog timer? Even if the fuse is not set, the watch dog can become enabled unexpectedly do to the way the power supply behaves.

Checking the reset flags as suggested by other posters would help shed some light on the problem.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In the case original poster doesn't know, the reset flag being discussed for your mega16 is the MCUCR register.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

curtvm wrote:
_delay_ms(2000) may not be what you think it is.
Long delays up to 6.5535s are possiblewith the latest _delay_ms macros.
kc0wys wrote:
Okay I stuck that code in, with the delay at 10s
That won't work. You have to call the delay macro two times to get 10s:
_delay_ms (5000);
_delay_ms (5000);
Can you add some LEDs to PA0 ... PA4? That's much easier than checkinng the IO via a Multimeter.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Can you add some LEDs to PA0 ... PA4? That's much easier than checkinng the IO via a Multimeter.

I just hooked up some LEDs and stuck the MCUCSR code into avr_init as so:

void avr_init(void)
{	
	CSHIGH;		//pull MAX7456 CS high
	
	DDRA=0x00;	//all in, for adc
	DDRB=0xBF;	//MISO in, all the rest out
	DDRC=0xFF;	//all output
	DDRD=0x02;	//PD0=UART RXD (in), PD1=UART TXD (out)
	
	PORTA = MCUCSR;
    MCUCSR = 0;
    DDRA = 0xFF;
    _delay_ms (2000); 
	
	change_uart_baud(DEBUG_BAUDRATE);	//set debug baud rate


And nothing. None of the LEDs light up. I also put the code in other places in the software, I tried putting it at the beginning of main() and at the end of avr_init() but it makes no difference. Which means software reset? If it is, in fact, a reset.

None of this is making any sense to me. I've tried hooking my PC up to the UART instead of the GPS receiver and banging on the keyboard in TeraTerm. The "resets" are totally random. It may happen after the second keystroke or the 2000th keystroke, it doesn't matter. But the "resets" do not happen at all if no data is sent to the UART. I really don't get this. :?

As for the fuses, the only fuses programmed are BOOTSZ0, BOOTSZ1 and SPIEN.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just a silly question but did you independently verify the operation of the LEDs on PORTA before trying to use them as a diagnostic tool? The common mistake made wit PORTA on a lot of AVRs is that folks who aren't using ADC often think they don't need to connect AVcc and in that case the PORT simply doesn't work. So I'd make sure all 8 LEDs can be both turned on and turned off in main() and then later use them as a diagnostic indicator.

But as this is a mega16 would you not consider using JTAG? It makes the finding of this kind of elusive reset thing so much easier. You can use a $50 Dragon or even one of the $30+ clones of the original JTAGICE (as one of the few devices it supported was mega16)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, PORTA works. About JTAG, I may look into that eventually.

As another test, I just changed the code to echo the input

data = UDR;   //get uart data
   UDR=data;

and I also commented out osd_init() so it should never be called. So I again hooked the AVR up to my PC and banged on the keyboard in a terminal and watched the output. I got some really strange results. It called osd_init() a few times (again, this should NEVER happen under normal circumstances because it is never called in the program) which, correct me if I'm wrong, means it's not a reset, right? It's just skipping around the program.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just a moment. Your code above has:

   DDRA=0x00;   //all in, for adc 
   PORTA = MCUCSR; 

Surely you meant:

   DDRA=0xFF;   //all out, for LEDs 
   PORTA = MCUCSR; 

???

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you look closely there are 2 DDRAs, the one you mentioned, which comes first and is a leftover from old code, and

   PORTA = MCUCSR;
    MCUCSR = 0;
    DDRA = 0xFF; 

Needless to say, removing the first didn't change anything. Good observation, though. I am known to make silly mistakes :wink:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay so I wrote a new program completely with nothing but the UART interrupt code. Here it is:

#include 
#include 
#include 
#include 

//UART stuff:
#define FOSC 16000000
#define BAUD 4800
#define MYUBRR FOSC/16/BAUD-1

static int uart_putchar(char c, FILE *stream);
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);

static uint8_t uart_mux;
volatile uint8_t data;

ISR(USART_RXC_vect)
{
	data = UDR;	//receive byte
	UDR = data;	//echo byte
}

static int uart_putchar(char c, FILE *stream)
{
    if (c == '\n') uart_putchar('\r', stream);
  
    loop_until_bit_is_set(UCSRA, UDRE);
    UDR = c;
    
    return 0;
}

void uartInit(void)
{
	UBRRH = (MYUBRR>>8);
    UBRRL = MYUBRR;
    UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
    UCSRC = (1<<URSEL)|(3<<UCSZ0);
    stdout = &mystdout; //Required for printf init
	
	return;
}

int main(void)
{
	DDRD=0x02;	//PD0=UART RXD (in), PD1=UART TXD (out)
	DDRC=0xFF;	//all output
	
	uartInit();	//initialize uart
	
	uart_mux=0;	//select GPS
	
	PORTC&=0x01;	//clear camera bits and buffer, but don't touch the radio ppt bit
	
	//make sure vars aren't more than 2 bits long:
	uart_mux&=0x03;
	
	PORTC|=(uart_mux<<1);	//write the bits to the port
	PORTC|=_BV(6);	//clk high
	PORTC&=~_BV(6);	//clk low
	
	_delay_ms(2000);	//wait 2s so we know it has reset itself
	
	printf("  \x1b[1J\x1b[fHELLO.\n");
	
	sei();	//enable interrupts
	
	for(;;)
	{
		//loop forever
	}
	
	return(0);
}

It does the same thing. It resets after a random number of characters have been sent to the port in a row.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
with nothing but the UART interrupt code
Still too much stuff. Go minimal.
#include 
#include 
ISR(USART_RXC_vect){
    uint8_t temp=UDR;
    UDR = '.';
}
int main(void){   
    UBRRL = 207; //4800/16mhz
    UCSRB = (1<<TXEN);
    UDR=(MCUCSR&0x1F)+'0';
    while(UCSRA & (1<<UDRE));    
    UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);    
    sei();
    while(1);
    return(0);
}

then work your way up.

edit- I added a little code here, so you can 'detect' resets. All output will be '.' when receiving, and the reset flags (readable ascii) should stick out.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay I tried that, it sends a '1' when I first power the AVR, but it doesn't echo anything I send it. So I stuck a UDR='x'; after while(UCSRA & (1<<UDRE)); and tried that. It still sent a '1' but not 'x'. So it's hanging on that while statement as if it doesn't know it finished sending.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
while(!(UCSRA & (1<<UDRE)));

sorry

or remove that line.

I think I put that there so a non-reset reset would still make sure that reset byte gets transmitted (showing a non-reset reset). But its not quite correct, as I think it would actually then be needed before the tx, not after. Or something. Not real important, as with that simple code I don't see how you get a non-reset reset anyway.

Last Edited: Mon. Jul 7, 2008 - 05:19 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
PORTC|=(uart_mux<<1);   //write the bits to the port 

Does post shifting left work too?? I would use

PORTC|=(1<<uart_mux);   //write the bits to the port 

but wadoino...

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

curtvm wrote:

while(!(UCSRA & (1<<UDRE)));

sorry

Oh ha I didn't catch that. After fixing it I gave it a whirl. Here's the terminal output (the 2 is after burning to the avr):

Quote:
2x..............................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
...........................................0x...................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
...................0x......................................................

As you can see, these "resets" aren't predictable. The number of characters between "resets" appears to be random.

Quote:
I would use
Code:
PORTC|=(1<<uart_mux); //write the bits to the port

The reason it's uart_mux<<1 is because I need to shift uart_mux, which is 2 bits long, left one. 1<<uart_mux would shift 1 left however many times uart_mux is, which is anything between 0 and 3 inclusive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1. Does the compiler know which microcontroller you are using? There should be an include there somewhere, I think. (Sorry. ASM guy myself).

2. What is your BOD fuse setting? BOD = brown out detector.

If you think education is expensive, try ignorance.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I don't see how you get a non-reset reset anyway.
I shouldn't have mentioned that.

It looks like the reset flags are clear, so somehow you are getting a 'non-reset reset'. I suppose its possible if the brownout fuse is not used, you could get power low enough to cause problems, but not low enough where it trips the power on reset. I'm not sure if the BORF will set when brownout is not used (I don't think so). So maybe enable brownout to the highest level, and see if you get the brownout flag. Or not.

Maybe attach your lss listing from the simple program above. Don't know what could be wrong, though.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

UDR=(MCUCSR&0x1F)+'0';

I think this is not correct because the value has a range of 0-31. Though it shouldn't make any difference here.

But what makes me really wonder is the fact that you never clear the MCUCSR but read '0' after the first unwanted reset.

Quote:
To make use of the Reset Flags to identify a reset condition, the user should read and then reset
the MCUCSR as early as possible in the program. If the register is cleared before another reset
occurs, the source of the reset can be found by examining the Reset Flags.

curtvm wrote:
I suppose its possible if the brownout fuse is not used, you could get power low enough to cause problems, but not low enough where it trips the power on reset.
I think so too. Your AVR is running at its max frequency. If the power supply drops below 4.5V the behaviour of the AVR is unpredictable because the CPU might execute instructions incorrectly.

Regards
Sebastian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I think this is not correct because the value has a range of 0-31
that is simply to get that flag register into ascii readable form (don't want unreadable codes coming at us, and don't want to make a hex2ascii function). Decoding is 'manual'. That's why Windows has the Character Map accessory app. '0' is easy, '2' is easy. Throw in the JTRF or WDRF and it gets a little harder.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Non-reset reset", eh?

--Program runs amok, ends up on 0xff unused area of flash and merrily marches along until it wraps and takes the reset vector branch at 0
--Some mechanisms for uncaught interrupt vectors will invoke the reset vector code if they occur
--Some bootloaders jump to 0 when they want to leave the bootloader

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
"Non-reset reset", eh?
That's why I call it a 'non-reset reset' (much easier to say than describing every possible scenario). It looks like a reset, but its not. With no reset flags set, the OP is getting one.

I think its safe to assume the simple app is not jumping 'out of bounds' and I doubt he is getting bad interrupts. The stack must be working, as the irq does work. Which pretty much leaves a power problem (no rules to follow, so avr can do as it pleases). Maybe.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm assuming the watchdog timer isn't enabled. :o :roll:

If you think education is expensive, try ignorance.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To clear things up, I actually did add MCUCSR=0; after it is read, which is why MCUCSR was 0 after the first "non-reset reset". Otherwise, yes, it would read 2 over and over.

I have switched power supplies and get the same results. The first supply was actually running at 5.7V at the supply and 5.2V at the AVR itself, this one is at 5.1V at the AVR. That huge drop of 0.5V seems fishy to me, esp. since the wires are only about 3 ft (1 m ;)) long. I'll look into power supply issues and post back shortly. Hang on...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you don't have brownout enabled, enable it (4V). At least you will then see the BORF flag ('4') if it is a power problem. Probably.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
The reason it's uart_mux<<1 is because I need to shift uart_mux, which is 2 bits long, left one.
:oops: I see :oops:

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just did that, but same story. As a side-note, I have noticed some more strange behavior. The AVR does not always start (as in, sends 'nx' where n is MCUCSR) when I give it power the first time. I have to switch the power on and off a few times to get it to start. Then I realized that the only time the AVR starts is when all the outputs on the 74HCT374 are low. So I disconnected the 374 from VCC and now the AVR starts every time. But the "non-reset reset" problem still persists...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh wait I'm an idiot, of course it doesn't "start" when the 374 reads anything but 0, I've multiplexed the UART. LOL epic fail... :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So what do we know about the board? We have had a few "red herring chase" in the past few weeks where bad design was causing strange problems.

Is this a homemade board? Do you have bypass caps near the chip AND near the regulator?

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry about the triple post, but I'll answer the questions that have accumulated. Thanks for all the help so far, btw :D

1. The MCU type is in the Makefile and I have checked to make sure it is, indeed, atmega16. Rule out incorrect mcu setting.
2. BODLEVEL fuse setting is now 0 (4.5V?), it was 1 (2.5V?). Of course BOD is also enabled. Anyway I've tried it, it makes no difference. I also checked the power rails with my scope. I do see the 16mhz clock interfering, but it is constant and the voltage never fluctuates. I went up to the highest sweep frequency I could, too. Rule out low voltage.

Quote:
Which pretty much leaves a power problem (no rules to follow, so avr can do as it pleases). Maybe.

I tend to disagree about the issue being power. I've been using the exact same set-up for over two months working on code for the MAX7456 on-screen display IC and other software, including using the UART, without any problems. I mean I guess it could be power, but I just see it as unlikely. This is the first time this kind of problem has cropped up.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
So what do we know about the board?

It's a breadboard, three next to each other to be precise. I've got about 3 or 4 0.1uF caps on the power rails spread out and 2 1uF caps also.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay I swapped the 16mhz crystal out for a spare 4.032mhz one, changed UBRRL accordingly, and now it works like a champ. Does this indicate clock instability problems or a power problem to you guys? Maybe I'll have to eat my words yet... :?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Does this indicate clock instability problems or a power problem to you guys?

Silly question but EXACTLY what model of AVR is this (not just the family name but also the suffix letters that show speed/voltage range). Is it possible that this one simply isn't rated for 16MHz operation?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Is it possible that this one simply isn't rated for 16MHz operation?

The thought had crossed my mind and in the first page I found:
Quote:
Okay I ran avr-size and got this:

Code:
AVR Memory Usage
----------------
Device: Unknown

I wonder if that makes a difference to anything. :?

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I may be wrong, but I think that's just because avr-size doesn't know what type of avr I'm using. The makefile clearly has it in it and I set it in PonyProg before burning as well. The AVR I have is, indeed, rated for 16mhz: ATMEGA16-16PU 0602J

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There used to be a fault in one of the older versions of Studio (I believe) where it invokved avr-size -C but was failing to pass the -mmcu= value into it correctly which led to that kind of "Device: Unknown" problem in the size display. Maybe this suggests out of date software?

As for the exact model - that certainly appears to be a 16MHz capable mega16. What capacitors were you using? Maybe it was failing to start oscillating correctly? Also did you have CKOPT set to 0 (programmed) along with the other CKSEL fuses as it'd be required for a crystal that fast.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Maybe this suggests out of date software?

Nope, I updated WinAVR to the newest release just before my first post here. It was one of the first things I checked.

Quote:
What capacitors were you using? ...Also did you have CKOPT set to 0 (programmed) along with the other CKSEL fuses...

All the clock fuses are, indeed, 0. However, the caps I'm using are 22pF and I believe the datasheet calls for 20pF. I can't remember the specific part #, but I bought it from Jameco and all of the ones in stock right now say 20pF... But I wouldn't imagine a difference of 2pF could make that much of a difference...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
All the clock fuses are, indeed, 0.
External Clock (CKSEL=0000)? With internal 36 pF capacitor between XTAL1 and GND (CKOPT=0)?

How about CKSEL=1111 and CKOPT=0 for 16mhz crystal.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Nope, I updated WinAVR to the newest release just before my first post here. It was one of the first things I checked.

I was talking about the version of AVR Studio, not WinAVR. It was Studio that had a bug in the creation of the avr-size command it was building into the Makefile. That, in itself, is not a catastrophic fault but it could be that a later Studio fixes more serious problems.

Pages