CPU clock speed settings, where can I find it? And how to change it?

Hello :slight_smile:

How are you friends,

Now I'm working to run a little project with Pro Micro board, to measure the length of IR remote signals.

This won't necessarily affect my project because the board is already running on 16MHz which is cool.

But for curiosity, I want to know where to find CPU clock speed settings, where changing it would easy just by changing the numbers.

You have to play with the Fuse bits for the Micro and then tweak the bootloader and runtime to handle the new frequency. There is no single place to change it.

Yeah - with the Micro and other ones that have built-in USB it's particularly tricky. I think USB imposes restrictions on what you can do with it if you want the USB to work.

There is definitely no support for non-standard CPU speeds included with the official board package.

There are three things needed to support alternate CPU speeds:

  • The fuses must be configured to match the desired clock source (ie, internal approx 8mhz vs external crystal). This means the board definition package (colloquially called a "core") must support that configuration option, and you select the desired options, connect an ICSP programmer, and do 'burn bootloader' (whether or not you're using a bootloader).

  • The board definition package must have a board definition matching the desired speed

  • The crystal used must match the desired speed (if running off a crystal), and the power supply voltage must be high enough that the desired speed is within spec (see datasheet).

ADDITIONALLY:

  • If you are using a bootloader for serial programming, rather than uploading via ICSP, you need a bootloader built for the desired speed.

  • If the chip has native USB, there are additional complications/restrictions that must be considered (I'm not familiar with the details here).

With some microcontrollers, there are board definition packages that already support almost any clock combination you could want, including bootloaders where appropriate. This is the case for the ATmega328/p (and smaller atmega x8 series chips) (via hansibul's minicore), the atmega1284/p (and smaller atmega x4 series chips) (via hansibul's mightycore), and most attiny's (via my ATTinyCore - though I don't provide bootloaders on chips where I don't think using a bootloader makes sense)

For any clock source you may use prescaler to divide the clock frequency by 2, 4, 8... running everything slower.
If you are using internal RC oscillator you can use its callibration register to change its speed in small steps from ~4MHz to ~16 MHz (typical).

When you change main clock everything runs slower/faster. Unless you do something about it everything dependant on time will be ruined: USB communication, timing functions etc.

OK

Thank you all for responding.

Well, my main goal is essentially not to change the clock speed as in Arduino it'd be difficult with Arduino many .h files. So, finding the place to do the modification would be difficult too.

My main goal is actually I want to measure IR VS1838B sensor signal coming to the pro micro.

I read about this project in a website and the post developer mentioned that there are different ways to decode and measure the IR signals according to IR protocols.

So what I want to do is to measure a 9ms signal at the pro micro pin configured as an input.

The code in the website is for PIC microcontroller with speed at 8MHz so the instruction speed is 8MHz/4 is 500ns. And I want to do this project with the pro micro at 16MHz and instruction speed is 62.5ns.

So I did a small test with the while technique and it didn't work, so I don't know what to do as the while condition didn't detected.

This is my snippet:

void setup() {
  // put your setup code here, to run once:
DDRB = 0x00;
DDRD = 0x20;
  uint32_t ir_code;
  uint16_t address;
  uint8_t command, inv_command;
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
nec_remote_read();
PORTD |= (1<<PD5);
_delay_ms(500);
PORTD &= ~(0<<PD5);
_delay_ms(500);
}

void nec_remote_read()
{
  uint8_t count =0,i;
  // checking the 9ms pulse
  Serial.println("Hello i'm going in the while condition"); 
  while ((PINB0==0))
  {
    count++;
    Serial.println(count);    
    _delay_us(50);
  }
}

So this was an X-Y problem. You don't need to change the clock speed at all for this, just use micros() - or if you need it more accurate than that, use a hardware timer (probably timer1) configured for input capture (this is exactly what input capture is made for)

Your code is almost solid problems, too.

The while loop you're using, you're expecting it to run in 50us, but you're sending a character over serial at 9600 baud, so each character takes ~1ms to send. Arduino has an output buffer on the UARTs, but I think it's only 128 bytes, and when that filled up, printing to the serial port becomes a blocking operation, leading the while loop to slow down by about a factor of 20....

This is probably not doing what you want it to - which isn't clear: uint8_t count =0,i;

Your code also doesn't seem to do anything to detect the start of the pulse...

PINB0 will always be 0. It's just a #define. PINB is the register. PINB0 is a constant that represents the bit within that register corresponding to B0 - that's the 0th bit. You would read it by doing (PINB&(1<<PINB0)).

When writing to PORTx registers, the bit names are PORTxn (ex, PORTD5), not PD5.

Here's a quick untested/off the top of my head bit of code that shows what my first approach would be to something like this.

void setup() {
Serial.begin(9600); 
pinMode(
}

void loop() {

if !(PINB&(1<<PINB0)) { //equivilent to PINB&1
unsigned long start=micros();
Serial.println("starting now");
while (!(PINB&(1<<PINB0))); //sit here busywaiting until the pin goes high again. 
unsigned long end=micros();
Serial.print("Pulse length was: ");
Serial.println(end-start);
}
}

Also, you should use code tags too.