difference between work of 2 atmega8a

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

Good Morning Avrfreaks!

Today I have faced very strange situation while testing some AVR codes.

I was using USART bluetooth communication to read data from mega in COM port on PC, and here is my test code I wrote:

#ifndef F_CPU
#define F_CPU 4000000UL // 4 MHz clock speed
#endif

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

int main(void)
{
	usart_Init();
	_delay_ms(200);
	DDRC = 0xFF; //Makes PORTC as Output
	PORTC= 0xFF; //Turns PORTC to HIGH state
	
	while(1) //infinite loop
	{
		PORTC = 0xFF; //Turns ON All LEDs
		_delay_ms(1000); //1 second delay
		PORTC= 0x00; //Turns OFF All LEDs
		_delay_ms(1000); //1 second delay
		
		transmittData("example",1);
	}
	return 0;
}

TransmittData( array of chars, int) is function written by me, sending chars one by one through UDR. The int number represents the seqence of ending signs that are to be included ( 1 is for including carriage return, without new line to generate 'still line' of data on the PC screen.

 

I've just bought new atmega8A and tried to activate this code on it... however it doesn't work properly:

the whole array of chars with \r included is not interpreted well which generates some strange sign.

As the LED test (on port C) works properly (which means F_CPU is OK) it looked like wrong BAUDRATE value but I have checked it in DS and it is fine.

 

Also I have tried also this code on the other atmega8a and it managed to generate 'still line' "example" on the screen just as I intended,

so it is not the BAUD problem...

 

Do you have any idea what could generate such behaviour?

 

Chris

 

 

This topic has a solution.
Last Edited: Tue. Sep 19, 2017 - 09:08 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes , using the internal RC oscillator. You need better precision when doing uart work, so add a crystal.

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

How have you proven that your chip is working at 4 MHz?

 

Ross McKenzie ValuSoft Melbourne Australia

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

Are you sure that the fuse settings of the 2 chips are identical ?

 

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

Thank you all for quick responses!

@Kartman, I will try it, thank you. 

@vaultsoft, LED Blinks with expected frequency. (if I define F_CPU different than 4Mhz than delay 1000ms does not give expected change every 1 second)

@I have checked both with AvRBurner (despite I've heared AVR burner is not so good software, I dont know how to do it different way) and fuses are almost identical: Low Fuse is the same, High fuse is the same, Lock fuse is the same and calibration is different however I have tryed changing it (without luck, every time it reads the same). For properly working atmega8a calibration fuse is A9A9A9A9 while for the other one instead of 9 I have 8.

 

Chris

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

Look at post #2
Use crystal.
.
MG

I don't know why I'm still doing this hobby

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

Chris_Irathil wrote:
@vaultsoft, LED Blinks with expected frequency. (if I define F_CPU different than 4Mhz than delay 1000ms does not give expected change every 1 second)

Remember that the maximum tolerable error on baud rates is on the order of only a few percent.

 

The LED blink test is good for checking that you don't have a gross error - such as a factor of eight - but isn't going to show up errors that make your baud rate unusable.

 

As @Kartman said in #2, the RC oscillators are not very accurate - so it is entirely possible that the oscillator on one of your chips is (just) close enough, but the other is (just) too far out.

 

EDIT

 

On the meaning of "gross" in this context: http://www.avrfreaks.net/comment...

Last Edited: Fri. Sep 15, 2017 - 01:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did you set the calibration byte for 4 MHz?

 

Mega8 DS:

During Reset, the 1 MHz calibration value
which is located in the signature row high byte (address 0x00) is automatically loaded
into the OSCCAL Register. If the internal RC is used at other frequencies, the calibration
values must be loaded manually. This can be done by first reading the signature row by
a programmer, and then store the calibration values in the Flash or EEPROM. Then the
value can be read by software and loaded into the OSCCAL Register.

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

So what would be the most optimal way to verify my frequency... or rather to set it properly to 4 Mhz? I already did it with AVRBurner I guess... but there is some kind of difference as you suggest so its not exacly 4 mhz... what should I do in this situation? only external oscilator can save me or there is other way?

 

@Visovian, thanks I will try it!

 

Chris

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

what should I do in this situation? only external oscilator can save me or there is other way?

From my experience the internal oscillator with factory calibration byte (as I suggested) is usable for uart at room temperature and stabil Vcc.  

But why not to add a crystal and two little capacitors to avoid the problem.

 

Datasheet:

The calibrated internal RC Oscillator provides a fixed 1.0, 2.0, 4.0, or 8.0 MHz clock. All
frequencies are nominal values at 5V and 25°C.  

At 5V, 25°C and 1.0 MHz Oscillator frequency selected, this calibration gives a frequency
within ± 1% of the nominal frequency. 

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

Skip the TransmittData() function and just send the single byte like "A". It will be much easier to debug.

 

Using character "A" is nice because the binary value is 0100 0001 so if any other characters show up you can check their binary value and determine what the frequency error is. It's almost like having a digital oscilloscope.

/Jakob Selbing

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

Using character 'U' would be better - because it is 0101 0101 ...

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

Visovian wrote:
why not to add a crystal and two little capacitors to avoid the problem

Exactly!

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

@jaksel, @awneil, thanks!

 

I have tried your both solutions to compare:

 

This is result of sending 'A' (each sign is effect of different loop iteration)...

this other sign when copied to google is: 'Á', just terminal has some incorrect interpretation.

this makes some kind of sense as 'A' is 0100 0001 and 'Á'  is 1100 0001. But the ü cant be pasted to google (interpreted as ?? so probably its not the ü from my guess. - terminal is having hard time with some specific signs

 

On the other hand when I send 'U' I receive:

Here again terminal displays strange signs inproperly so this N is accually Ő which makes some similarity to A:

U: 01010101

Ő: 11010101

the similarity is that, the only difference is the 1 instead of 0 in front which would be same error (dec 128)

while this L is interpreted by google as • which has bin representation 10010101.

 

Despite this results show some kind of information about this error I don't really know how to adjust the code to make it work.

Could give some explanation please?

 

Chris

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think you've missed the point of #12.

 

The point is to look at the waveform on an oscilloscope (or logic analyser) - so that you can measure the actual baud rate.

 

Chris_Irathil wrote:

U: 01010101

Ő: 11010101

Looks like your baud rate is close, but not quite right - so every so often the receiver "slips" a bit.

 

This diagram illustrates how a slight baud rate error causes the sampling point to "slip":

https://www.allaboutcircuits.com/technical-articles/the-uart-baud-rate-clock-how-accurate-does-it-need-to-be/

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

Just read the whole thing. So

Chris_Irathil wrote:
what should I do in this situation? only external oscilator can save me or there is other way?
Exactly what is the issue with doing this? It costs about $0.10 for a 4MHz crystal and $0.01 for a couple of 12pF (or whatever) capacitors. That is the true solution. However you were also asked:

Visovian wrote:
Did you set the calibration byte for 4 MHz?
But I did not understand your response. The mega8 has four calibration bytes loaded into it by Atmel when they made/tested the chip. They determined the calibration closest to "on frequency" for the four internal osciallators at 1MHz, 2MHz, 4MHz and 8MHz. They then burned the four optimal values into the chip. When you apply power to one of these old AVRs (no matter whether 1, 2, 4 or 8 MHz internal is selected) the chip auto-loads the calibration for 1MHz. So the auto-loading only really works if you have stuck with the default choice of 1MHz internal. As you have switched to 4MHz you need to do a manual process. Start with your ISP programmer and get it to read the 4 calibration values. Select the one for 4MHz and either add a line to all programs that you write to say:

int main(void ) {
    OSCAL = value_found_for_4MHz;
    // rest of code
}

so you might have found the 4MHz set by Atmel was 0xB3 in which case the code is:

int main(void ) {
    OSCAL = 0xB3;
    // rest of code
}

The alternative (though this is really if you are dealing with multiple AVRs) is to take whatever value you found (0xB3 or whatever) and use ISP to write it back to some location in the chips EEPROM. Then your programs start with something like:

#include <avr/eeprom.h>

int main(void ) {
    OSCAL = eeprom_read_byte(123);
    // rest of code
}

where you previously used ISP to write the 0xB3 (or whatever) to location 123 in the EEPROM.

 

This latter mechanism is basically so the code in 500 different AVR can all be the same but all that changes for each AVR is the value that has been written back to location 123 (or whatever) in their EEPROM.

 

If it's just about one or two mega8's then just go with the direct "OSCAL = N" method where N is the value ISP read as the 4MHz calibration byte.

 

Or easier still, spend the entire $0.12 and get that crystal and two capacitors and use an accurate AVR!

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

@Clawson, thank you for your response. 

Yes I have already ordered oscilator and already have capacitors. I just have wondered if I could fix the problem immediately so I can continue work with my project. 

also I might have described some things in the wrong way but the setting of 4 mhz was fine.

 

I have checked frequency on oscilloscope just as awneil recommended and have found that the accualy frequency of mega is 4.21 Mhz, so after redefining it I got the code working. 

thank you all for the contribution!

 

Chris

 

 

 

 

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

Chris_Irathil wrote:
Yes I have already ordered oscilator (sic?) and already have capacitors.

Note that you don't need an external oscillator - just an external crystal!

 

http://www.avrfreaks.net/comment...

 

http://www.avrfreaks.net/comment...

 

 

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

Chris_Irathil wrote:
so after redefining it I got the code working.
What did you redefine? The F_CPU used to calculate UBRR or did you use the calibration value in OSCCAL?

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

@clawson

I have measured freqency when it was set with fuses to 4Mhz and accual was 4.21 Mhz so what I did was:

 

#define F_CPU 4210000UL

 

and with this update to code the communication started to work.

 

 

Chris