top of page

6. Configure the Operation Frequency

This tutorial is to configure the operation frequency without going to the fuse setting.

The CKDIV8 Fuse determines the initial value of the CLKPS bits. If CKDIV8 is unprogrammed, the CLKPS bits will be reset to “0000”. If CKDIV8 is programmed (factory default), CLKPS bits are reset to “0011”, giving a division factor of 8 so that the operation frequency is only 1MHz while the CPU frequency is 8MHz. This can be changed through the program without going to the fuse setting.


Example 1: Clock Prescaler Select

CLKPS[3:0]                 Clock Division Factor

     0000                                      1

     0001                                      2

     0010                                      4

     0011                                      8

     0100                                     16

     0101                                     32

     0110                                     64

     0111                                     128

     1000                                     256

 

In order to change the operation frequency, the Clock Prescaler Register CLKPR need to be set. 

 

Example 2: Clock Prescaler Register

    Bit                    7                  6          5            4                  3                  2                   1                   0

CLKPR:          CLKPCE            -           -           -             CLKPS3       CLKPS2       CLKPS1       CLKPS0      

 

The CLKPCE bit must be written to logic one to enable change of the CLKPS bits. The CLKPCE bit is only updated when the other bits in CLKPR are simultaneously written to zero. CLKPCE is cleared by hardware four cycles after it is written or when CLKPS bits are written.

 

Example 3: Set the clock prescaler to 1


#define F_CPU 8000000ul //This may be required for setting the clock Prescaler

#include <avr/io.h>

 

int main(void)

{

   CLKPR = 1 << CLKPCE;

   CLKPR = 0; //set clock Prescaler to 1

 

   DDRB |= 1 << 1 | 1 << 2; //Set OC1A and OC1B pins (PB1 and PB2 in ATmega328P) as an output

   TCCR1A |= 1 << WGM11; //set fast PWM Mode with TOP at ICR1

   TCCR1B |= 1 << WGM12 | 1 << WGM13; //set fast PWM Mode with TOP at ICR1

   TCCR1A |= 1 << COM1A1 | 1 << COM1A0; //Set to inverting mode on OC1A

   TCCR1A |= 1 << COM1B1 | 1 << COM1B0; //Set to inverting mode on OC1B

   TCCR1B |= 1 << CS10; //Set the prescaler to 1

   ICR1 = 1999; // Set TOP value, the PWM frequency is 8,000,000/2000 = 4000 Hz

   OCR1A = ICR1 - 1500; //Pulse goes up after 500 counts

   OCR1B = ICR1 - 500; //Pulse goes up after 1500 counts

   while (1) {}                                     

}

 


Another way is to include <avr/power.h> and use the corresponding command. This tutorial will not dig up into this method. All standard AVR header files are available at https://www.nongnu.org/avr-libc/user-manual/modules.html.

 

Example 4: Alternative way to set the clock prescaler to 1


#include <avr/power.h> 

#include <avr/io.h>

#include <avr/interrupt.h>

 

int main(void)

{

   clock_prescale_set(clock_div_1); //set the clock prescaler to 1

 

   DDRB |= 1 << 1 | 1 << 2; //Set OC1A and OC1B pins (PB1 and PB2 in ATmega328P) as an output

   TCCR1A |= 1 << WGM11; //set fast PWM Mode with TOP at ICR1

   TCCR1B |= 1 << WGM12 | 1 << WGM13; //set fast PWM Mode with TOP at ICR1

   TCCR1A |= 1 << COM1A1 | 1 << COM1A0; //Set to inverting mode on OC1A

   TCCR1A |= 1 << COM1B1 | 1 << COM1B0; //Set to inverting mode on OC1B

   TCCR1B |= 1 << CS10; //Set the prescaler to 1

   ICR1 = 1999; // Set TOP value, the PWM frequency is 8,000,000/2000 = 4000 Hz

   OCR1A = ICR1 - 1500; //Pulse goes up after 500 counts

   OCR1B = ICR1 - 500; //Pulse goes up after 1500 counts

   while (1) {}                                     

}

 


The results are verified though ATmega 328P. In example 3, #define F_CPU 8000000ul is not required when the PWM output is from OCR1A/OCR1B pin; however, #define F_CPU 8000000ul may be required when the PWM output is other I/O pins.

 

 




©2020 by Pulin Global

bottom of page