I understand that one can patch the original atmega328 arduino bootloader to run with a 20mHz crystal. I have seen the booloader @ http://www.wulfden.org/, do I simply flash the ADABoot_328.hex file with an ISP, replace my crystal with a 20mHz version, and all will go well?
There is a lot more than just the bootloader. In some cases the bootloader will even work without modification. What you need to think about is the timing functions. I believe they are all based on either 8MHz or 16Mhz. So for example the Millis function may not be fully accurate. But yes your board will run at 20MHz with the updates you explain.
OK, thanks for your input. I believe that the ADA bootloader makes up for the timing by modifying the millis() function, so even timing should work. I was only worried about the chip being able to even run with the modded bootloader. I needed that extra 4mHz speed gain for my project (it utilizes an ISR to control PWM frequencies that are relayed to a set of Shift Registers).
I've run chips at 25MHz before... unknowingly put the wrong crystal on the board. Never had any problems. 20 MHz is in spec and you shouldn't have any problems.
I've run chips at 25MHz before... unknowingly put the wrong crystal on the board. Never had any problems. 20 MHz is in spec and you shouldn't have any problems.
Hmm... 25mHz you say? Just wondering, if off the top of your head, do you know what the max specs are for the ATMEGA328? If not, ill snoop around in the datasheet a little bit more, or JFGI.
Also, this may seem like a dumb Q, but the CPU speed is directly affected by the crystal, correct?
Eg, a if 1mHz crystal would run a task in 1 second, a 16mHz crystal would do the same in 1/16 of a second? 25mHz would do it in 1/25 of a second?
Yup... the Max spec'd speed is 20MHz. As far as the 25MHz working, maybe I was just lucky or maybe I just didn't push it enough to find any problems.
The specs just tell you the maximum and/or minimum limits that are guaranteed to work. There is no reason the chips can't surpass these limits. Especially as manufacturing processes get more and more reliable.
OK, great, that makes sense. Maybe I'll get a 25mHz crystal to test it out, its not like it would hurt anything. 20mHz will be my definite fall back tho, it should be fast enough anyway.
If your interisted, heres the code that needs all that speed
It will control the LED's in my comp case fans. Multicolored case, here I come!
#define __dataPin 9
#define __clockPin 10
#define __latchPin 11
#define __numLedsInArray 8
#define __numPinsPerLed 3
#define __maxBrightness 100
int ledPin = 13;
int i=0;
int tcnt2;
int isrCount = 0;
int loopCount=2;
int ledStates[__numLedsInArray][__numPinsPerLed];
int ledNumber = 0;
int ledLoopNum = 0;
int currBuffer = 0;
void setup() {
// initialize the shift reg control pins as outputs:
pinMode(__dataPin, OUTPUT);
pinMode(__clockPin, OUTPUT);
pinMode(__latchPin, OUTPUT);
Serial.begin(9600);
setupTimer();
}
ISR(TIMER2_OVF_vect) {
/* Reload the timer */
TCNT2 = 148; //This seems to not flicker very much. 205 for 4 LEDS, 148 for for 8 LEDS (Must shift out 3 bytes for this to be accurate)
while(ledNumber <= __numLedsInArray-1)
{
while(loopCount<=2)
{
if(ledStates[ledNumber][loopCount] <= isrCount)
{
currBuffer |= (1<<loopCount+(ledNumber*3));
}
else
{
currBuffer &= ~(1<<loopCount+(ledNumber*3));
}
loopCount++;
}
loopCount=0;
ledNumber++;
}
ledNumber=0;
PORTB &= ~(1<<3); //latch low
shiftOutDedicated((byte)(currBuffer>>16)); //A placeholder for a third byte, so I can time this just right. Not currently in use (i need to put in another register) but needed to get the delays and ISR timing correct.
shiftOutDedicated((byte)currBuffer);
shiftOutDedicated((byte)(currBuffer>>8));
PORTB |= (1<<3); //latch high!
isrCount++;
if(isrCount >= 100)
{
isrCount=0;
}
}
void shiftOutDedicated(byte val) //All hardcoded PORTS. I will add #defines that are golbaly changeable later.
{
for (int i = 0; i < 8; i++) {
if(!!(val & (1<<i))) //Is there any way I can evaluate wether to turn the bit on and off without an IF statement? That is, evaluate it while declaring PORTB
{
PORTB |= (1<<1); //Set the dataPin bit //Nothin like cold hard port manipulation
}
else
{
PORTB &= ~(1<<1); //Clear the dataPin bit
}
PORTB |= (1<<2); //Clock pin high
PORTB &= ~(1<<2); //Clear clock pin to low
}
}
void setupTimer() //Set up the timer.
{
unsigned int tcnt2;
TIMSK2 &= ~(1<<TOIE2);
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
TCCR2B &= ~(1<<WGM22);
ASSR &= ~(1<<AS2);
TIMSK2 &= ~(1<<OCIE2A);
TCCR2B |= (1<<CS22) | (1<<CS21) | (1<<CS20); // Set bits
//
//TCCR2B &= ~(1<<CS21); // Clear bit
//TCCR2B &= ~(1<<CS20);
TCCR2B &= ~(1<<CS22); //Clearing only this gives best timing.
TIMSK2 |= (1<<TOIE2);
}
void loop()
{
int ledNumberID = 0;
//This fades in and out the individual colors in 4 LED's. Ya, i could have put it in a loop, but whatev. I was lazy at the time and it does the trick :p
while(ledLoopNum <=2)
{
i=0;
while(i<=100)
{
ledStates[0][ledLoopNum]=i;
i++;
delay(1);
}
i=100;
while(i>=0)
{
ledStates[0][ledLoopNum]=i;
i--;
delay(1);
}
ledLoopNum++;
}
ledLoopNum=0;
while(ledLoopNum <=2)
{
i=0;
while(i<=100)
{
ledStates[1][ledLoopNum]=i;
i++;
delay(1);
}
i=100;
while(i>=0)
{
ledStates[1][ledLoopNum]=i;
i--;
delay(1);
}
ledLoopNum++;
}
ledLoopNum=0;
while(ledLoopNum <=2)
{
i=0;
while(i<=100)
{
ledStates[2][ledLoopNum]=i;
i++;
delay(1);
}
i=100;
while(i>=0)
{
ledStates[2][ledLoopNum]=i;
i--;
delay(1);
}
ledLoopNum++;
}
ledLoopNum=0;
while(ledLoopNum <=2)
{
i=0;
while(i<=100)
{
ledStates[3][ledLoopNum]=i;
i++;
delay(1);
}
i=100;
while(i>=0)
{
ledStates[3][ledLoopNum]=i;
i--;
delay(1);
}
ledLoopNum++;
}
ledLoopNum=0;
}
I think if you just search the forum for "Arduino 20MHz" you would find a lot of discussion and solutions for this. Including several places where my ready to use bootloaders and boards.txt files are linked: http://www.macetech.com/Arduino_20MHz.zip