BUG in Mega48? ... was[Mega48: usart problem]

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all,

I have a problem with the below code.

char cmin[3]={'0','0','0'};

while(1)           // do this forever
{

 itoa(cmin,50,10);   //50 is our test number, base 10 
//cmin={0x35, 0x30, 0x00}

 i=0;
 while(cmin[i]!=0)  // test to see if we have reached the null(last) char in the string
  { 
   A=cmin[i];                 // Replace A with UDR0 to use usart        
   while(!(UCSR0A &(1<<UDRE0))) ;  //wait until char is sent.
   i++;
  } 
}

The problem is this. If I have a number that ends in 0 (10,20,...) it will drop the 0 when sending over the Usart of the Mega48 but works fine in studio 4.11. However when the number does not end in 0 it will send it over the usart without any issues.

so if I send 49, 50, 51,.. I will get 49,5,51.....

I am using ImageCraft 6.31A as the comipler.

Any ideas what is wrong?

Thanks,
Caleb

Last Edited: Wed. Dec 28, 2005 - 02:54 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Actually, you are supposed to check UDRE0 and make sure its a 1 value before writing to UDR0. It looks like it is not a problem in your simple program, but you should not get into the habit of doing it backwards.

You said that besides the ending in zero problem, it works in AVRstudio 4.11 (an old version). So, I assume you are talking about “works” using the simulator, not Debugwire or ICE50. I suspect it will probably work in the real world outside the simulator. If it turns out to be a simulator problem, try the current version 4.12 build 461. Make sure to uninstall version 4.11 from windows first before installing 4.12.

When testing/debugging in the real world, make sure to use software in the receiving end that can report values that are not alphabetic characters. Sometimes the non-AVR software we use to test with ignores any non-alphabetic value leading us to think it was never sent, when it was really the wrong value was sent.

BTW, it is just a little bit risky to declare an itoa() 3 byte buffer that is only large enough for expected values and is much smaller than the maximum possible value. If you forget or a problem occurs later on, you could easily overwrite memory after the buffer. A 7 byte length buffer (-32767) would be safer.

While rereading your post, it appears I might be confused by when it works and when it does not work. Please clarify where it works and does not not work. Always identify when you are using simulator software, as simulating USART and real time events can be a challenge for simulator software. BTW, windows hyperterm does not have a good reputation for testing/debugging use.

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

Thanks for the pointers about improving my coding practices.

I am using Terminal v1.9b by Bray++, can be found here on AVRFreaks.net.

I will review the datasheet for which order to test for a empty TX/RX reg. before sending data to UDR0.

The code works just fine on a real Mega48 for all numbers that do not end in 0, so "1","2",..., "9", "11",...,"19" and so on. Note these are ASCII strings, not just hex numbers of 0,1, 2, but 0x30 ="0" and 0x31 ="1"

but all numbers that end in "0", "10", "20","30","40","50".... it will drop the 0.

I have checked the code with AVR simulator in AvrStudio, and found that the code works fine, as I would expect the code to work.

But when I program the code on the Mega48 I only get the first byte.
for the ASCII string "50" I only get "5." if I use "51" I get "5" and "1"

Any ideas would be great,

Caleb

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

austca wrote:
but all numbers that end in "0", "10", "20","30","40","50".... it will drop the 0.
Since you are using the ASCII representation I assume you really mean it will drop the “0”.

The code should work. Try a test version without itoa() and just set the cmin string directly with three assignment statements.

cmin[0] = 0x35;
cmin[1] = 0x30;
cmin[2] = 0x00;

This will tell if iota() is really working.

If you have too, try sending 0x35 and then 0x30 with in-line USART Tx code (without the cmin[i] while loop). Unless you were somehow trying to write UDR0 when UDRE0 was zero, I would think you will probably find the USART is not at fault here. However, if a dedicated in line send 0x30 will not get through the USART, the only other possibility besides the USART I can think of would be some strange setting or reaction in BRAY++ (which is reported to be very good for debugging use). If it still looks like the USART, go through your USART setup code just to make sure, but if you had setup problems then I would not expect it to send 0x35, which it does send (no real chance, but it is good to be through).

A RS-232 protocol analyzer or logic analyzer are the only tools that would be better than BRAY++ for something very odd like this.

Beyond that I would start thinking strange thoughts about maybe your AVR part got a bad static zap (I have never heard of any other complaint about not being able to send 0x30) and is partly damaged, maybe your USART timing between the AVR and BRAY is right on the edge and 0x30 always messes up (not very likely), a complier bug or ????.

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

Well a short update.

I have tested the code a bit more and now have just

char cmin[8];

 itoa(cmin,5100,10);

UDR0=cmin[0];  TXwait(); // wait for byte to be sent.... or wait before next...
UDR0=cmin[1];  TXwait();
UDR0=cmin[2];  TXwait();
UDR0=cmin[3];  TXwait();

and my input into Bray++ is

0x35 0x31 0x00 0x30

it should be

0x35 0x31 0x30 0x30

when I test this on VMLAB I get what I would expect and when I test with AVRStudio I get the same as VMLAB.

I added a test to the code like this

char cmin[8];
 itoa(cmin,5100,10);

UDR0=cmin[0];  TXwait(); // wait for byte to be sent.... or wait before next...
UDR0=cmin[1];  TXwait();
UDR0=cmin[2]=0x30;  TXwait();
UDR0=cmin[3];  TXwait();

and I get what I would expect. So I would conclude that the itoa function is not work correctly on the avr. Bad chip?

Ok, I was just working a bit more... decided to check the chip... would be nice if the real board had a DIP instead of the TQFP.

I pulled out the trust STK500 that happened to have a mega48 on it.. been on it a while now.. nearly a year and programmed it up.. all is well with the code. Time to get out the soldering iron and take a mega48 out and replace it!

Thanks for the comments.

Caleb

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

Now comes the question, why only 0x30 hex would not work on the chip... all the rest of 4k of code works fine. All of the code has worked fine for two years on a mega8. I guess this was just a bad one. It is funny this bit of code was the only bug in the program....hmm guess I need to build more boards to test on:)

Well I think this case is closed.

Caleb

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

Check with your complier supplier. You may have an old itoa() library version with bugs or they may also have the same problem. The Mega48 complier support may have brought in a new library, so the old Mega8 code working is not an indication that there is no problem.

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

Ok, I am going to bring this thread back to life.

I have continued with my study of this problem, itoa(...) does not work correctly with all numbers. Inparticular, all numbers ending in 0, 10, 20, 30,... the 0 is droped.

I have now tested on two TQFP Mega48's date code 0514A. I get the same results on these chips. note that all numbers not ending in 0 this code works fine for, so 9, 11, ...,19, 21, ...

I have tested on a PDIP date code 0437A and the code works correctly for all numbers(19,20,21). I use the same hex code, running on internal 8Mhz osc. So I am going to get new chips, both dip and tqfp of the mega48 and mega88.

Has any one else found such funny bugs between PDIP and TQFP packages? I wonder if this is a bug in the newer mega48's?

Well off to Digikey to order new chips....

Caleb

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

Please post the smallest test program that you can reproduce the problem. Scratch that--the complete listing would be needed, and itoa() is going to be a fairly extensive library routine--we'd all need the whole magilla which would be like half a K.

Compiler Wars Round 57? :) I don't have problems with itoa() in CodeVision. [end the year right with another round.]

Remember that a Mega48 or Mega88 don't know spit about itoa().

If I had to make a guess, you are borderline on UART errors using the internal oscillator. Different chips will have different speeds. Try with a real crystal to verify.

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

Bug in Mega48? Yes, all in my code I loaded into the chip:)

Well the one line of code that I had wrong was "declaring" a "extern Key;" vs. "extern char Key;" and the first byte, "0" of the itoa() function(itoa look up table) was getting over written. I guess the compiler had been updated over the nearly two years to use a new itoa() function and thus my "bug"showed up. Well I relearned alot I had not used in a while;)

This case is finialy close, for good! :)

Caleb