My Pi Description

My Experiences With the Raspberry Pi -- Tracking My Learning -- My Pi Projects

Saturday, January 11, 2014

Gertboard - Changing ATmega328P Resonator Frequency

In my last post about my Camera Remote Controller project, I said I would discuss changing the ATmega resonator frequency.

Why Change The Frequency

Now why would you want to do that? Here is a good reason why: once you program the ATmega microprocessor via the RaspberryPi/Gertboard programmer you can remove the chip from the Gertboard and install it on your own PCB. That is what I did to make my Camera Remote Control project become useful rather than being a collection of loose parts and connections. Freed from the Gertboard you are no longer restricted to using a 12MHz external frequency source. You could power your project from 5V rather than the Gertboard's 3.3V allowing you to use a 16MHz resonator or a 16MHz crystal. Perhaps you found a script that was written for an Arduino that you would like to use. Most Arduinos run on 16MHz not 12MHz.
I got interested in this question because I stupidly ordered a bunch of 10MHz resonators. I did this because I failed to check the schematics and THOUGHT the resonator was 10MHz, not 12MHz. I discovered my error but figured the camera remote would work OK at 10MHz, so I wondered how the frequency is set.

Importance Of Clock Frequency

I guess I should talk about why the clock frequency is important. It's important if you are doing any timing. Timing is accomplished by using one of the Arduino IDE builtin functions such as delay(), delayMicroseconds(), micros(), and millis(), or by writing your own timing functions. It's also a consideration if you want to have a script work exactly the same on and off the Gertboard. If you have a project where the timing is not critical, and speed is not a factor, you could forget about an external clock source and use one of the ATmega internal clock options. More on this later.

Let's Change The Frequency

OK, if I still have your interest, what do you do if you want to change the clock frequency? Where is the clock frequency set? It is not set by programming any of the fuses or by programming any of the ATmega registers. It is set when you compile your script from whatever makefile is in use. Let's be clear about one thing here, I am talking about writing scripts, compiling them, and uploading them using the Arduino IDE. If that is the case, the makefile seems to be hidden from view. At least, I could not find it. However, there is a way to find out what is going on when you compile a script.
Bring up your Arduino IDE and go to "File/Preferences", then enable "Show verbose output during compilation". Compile any script. You will find it takes much, much longer and a lot of messages scroll by at the bottom of the window. You should see calls to avr-g++ and avr-gcc, each with several of parameters. One of those parameters will be "-DF_CPU=12000000". OK now that we see that, how do we change it? To answer that you have to know where the makefile knows that the parameter should be 12000000. It finds that information in the following file:
      /usr/share/arduino/hardware/arduino/boards.txt.
boards.txt contains configuration information for products that can use the Arduino IDE like the Gertboard. You can find sections for the Arduino Uno, the Arduino Nano, the LilyPad and many of others. Heading the file are the two sections for the Gertboard which were probably added by Gordon Henderson. One section is for each of the two ATmega ICs you could use with the Gertboard: the ATmega328 and the ATmega168. Assuming you are using the ATmega328, the line in boards.txt we are looking for is this one:
      gert328.build.f_cpu=12000000L.
To change the frequency, simply change the 12000000 to some other value. But, if you compile a sketch, change the value of f_cpu, and immediately recompile your sketch, you will not see a change (in verbose mode) to the parameters of avr-g++ and avr-gcc. When you recompile the same sketch that you last compiled, the Arduino IDE attempts to speed things up a bit (so it doesn't try your patience), and, apparently, does not look at boards.txt again. So, after changing board.txt, compile a different sketch or kill and restart the IDE. Then, you will see the change to -DF_CPU. As usual, make a backup copy of boards.txt before making any changes.
I tried this out by writing a sketch to toggle an LED on and off at a one minute rate. Changing the clock frequency as described above altered the cycle time in a predictable manner.

Changing The Clock Source

I have not personally tried changing the clock source as described in the following. But, I don't see why it would not work.
If timing is not important and your project does not have to work at lightning speed when you remove your ATmega chip from your Gertboard, and install in in your own hardware, you do not really have to install a resonator or crystal.
Before I continue, I strongly suggest you have a copy of the datasheet (it's hardly a sheet, it's 660 pages) for the microcontroller. You can find it here from Atmel. Make sure you download the first .pdf file under the picture. I'll assume you have this handy in the following discussions.
From Table 9-1 on page 27 you can see that, besides the three external clock options, there are two internal clocks built into the chip: a "Calibrated Internal RC Oscillator", which runs at 8MHz, and an "Internal 128KHz RC Oscillator". The default selection is the 8MHz calibrated oscillator. There is also a prescaller that divides the oscillator by any one of the eight values shown on Table 9-17 on page 37. The default value is to divide by 8. This prescaller will also divide the frequency of any of the external clock choices you may have choosen.
If the default choice is the 8MHz oscillator divided down to 1MHz, how does the Gertboard run at 12MHz? The answer is: The Gertboard does not use the default settings if you followed Gordon Henderson's direction for setting up the ATmega chip before using it. Whenever you use the Gertboard for the first time, or install a new ATmega chip on the Gertboard, you run a program called avrsetup. avrsetup programs several registers within the chip, namely the three fuse registers and a lock byte. We won't be talking about the lock byte because avrsetup just programs the lock byte to its default configuration.
If you are younger than about 50, you might wonder why they are called fuse registers. Miorocontroller chips, as well as other chips, like old PROMS (programmable read only memory), would be programmed by burning out fuseable links within the chip. A popped fuse represented a logic 0 while an intact fuse was a logic 1. Once the chip was programmed and you wanted to revise the information, you threw out the old chip and programmed a new one. I don't think any modern devices have fuses - but the name has endured. Mainly, these registers contain settings you want to setup before you do any serious programming because making changes later could mess up what you already programmed.
avrsetup programs these fuse registers for you by calling a program called avrdude. The three registers are the "Extended Fuse Byte", the "Fuse High Byte", and the "Fuse Low Byte". These are all eight bits in length. You can see what these registers do in section 28.2 starting on page 286. If you compare these registers with avrsetup you can see that the extended and high fuse registers are left at their defaults.
The low fuse register is definitely changed. The default value is 0x62 specifying the 8Hz calibrated oscillator and prescaller set to divide by 8. See Table 28-9 on pages 288 and 289 and Table 9-1 on page 27. avrsetup changes that setting to 0xE7 which selects the "Full Swing Crystal Oscillator", for the 12MHz resonator on the Gertboard, and prescalling set to 1.
Like boards.txt, avrsetup can be changed by the user. But, please, make the changes carefully and make a backup of avrsetup. If you would like to accept the 8MHz calibrated oscillator divided by 8, don't run avrsetup at all because all of the fuse registers and the lock byte will be set to the factory defaults.

No comments:

Post a Comment