Change the Prescaler Division of de Main Clock in ATtiny817

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

Hello everyone! I'm doing a little project with an ATtiny817 and I have a problem when setting the clock. As some will know and as the datasheet says on page 80, after a reset of the micro the CLK_MAIN is configured as the internal oscillator of 16 / 20MHZ (according to the FUSES, in my case 20MHz) and with a prescale with a factor of division equal to 6:

 

 

My problem is that when I start my program, in the main function I change the prescale to 2, since I am interested in having 10MHz, but the changes are not carried out. This I checked on the oscilloscope with a PWM signal and doing the corresponding debugging from Atmel Studio. Here I show you a screenshot of the value of the record, MCLKCTRLB = 0x11, when I want its value to be MCLKCTRLB = 0x01.

 

CLKCTRL.MCLKCTRLA=0b00000001;	 // The CLKOUT pin is disable and the source for de main clock is "16/20MHz internal oscillator"
	CLKCTRL.MCLKCTRLB=0x01;	 // The prescaler is enable and the prescale is "/2"

 

 

I hope you can lend me a hand because I have no idea why the changes are not carried out. Thank you very much in advance. A greeting.

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

In your datasheet screenshot, there is "Related Links"; one of those links is "CCP - Configuration Change Protection" - so what's that all about, then ?

 

EDIT

 

Clarify datasheet screenshot

Last Edited: Fri. Sep 15, 2017 - 11:08 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi awneil and thanks for your interest. The CCP part says this:

 

 

 

I think that the problem is not here...... :/. What do you think? 

 

Thank you very much

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

Rodri_Go11 wrote:
I think that the problem is not here

Why do you think that?

 

Have you followed the highlighted instructions?

 

You haven't shown your code, so nobody has any idea what you're actually doing!

 

Time to show a minimum, complete, compilable example that illustrates the problem.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include <avr/io.h>
#include "atmel_start.h"

#define ENABLED		1
#define DISABLED	0
#define FCLK_MAIN	20000	//KHz
#define PRESCALE	6	

int main(void)
{
	//VARIABLES
	int PWM_per, PWM_duty_cycle,  peripheral1_en, peripheral2_en, driver_en, iL_max, dac_data, iL_max_error, PWM_freq_maxError;
	float PWM_frequency, dac_data_aux, PWM_per_aux, duty_cycle_aux;
	
	//Inicializamos variables que sean necesarias
	 PWM_freq_maxError = 0;
	 iL_max_error = 0;
	
	//*************************   PARÁMETROS   ****************************//
	PWM_frequency	=	13;				// KHz. (Valor mínimo igual a la Fclk/prescala=Fclk_peripheral)
	PWM_duty_cycle	=	50;				// En tanto por ciento (0-100%)
	iL_max			=	8260;			
	peripheral1_en	=	ENABLED;		// 1-Enabled; 0-Disabled
	peripheral2_en	=	DISABLED;		// 1-Enabled; 0-Disabled
	driver_en		=	ENABLED;		// 1-Enabled; 0-Disabled
	
	
	CLKCTRL.MCLKCTRLA=0b00000001;	 // The CLKOUT pin is disable and the source for de main clock is "16/20MHz internal oscillator"
	CLKCTRL.MCLKCTRLB=0x01;			// The prescaler is enable and the prescale is "/2"
	
	//***********************FREQUENCY**************************//
	
	
	PWM_per_aux = (FCLK_MAIN/(PRESCALE*PWM_frequency))-1;
	PWM_per = (int) PWM_per_aux;

	//********************DAC************************//

	dac_data_aux=iL_max/32.39; 
	dac_data=(int)dac_data_aux;
	//***********************************************//
	 
	atmel_start_init(dac_data, PWM_per, PWM_duty_cycle, peripheral1_en, peripheral2_en, driver_en);
	
    while (1) 
    {
    }
}

This is my main function. thank you!

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

So where do you "unlock" the Configuration Change Protection, then?

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

 have edited the code by adding the relative lines to the CPP and I have executed and the output remains unchanged. I have read out there that the problem may be that (http://www.avrfreaks.net/forum/t...), but I am still unsuccessful and the MCLKCTRLB registry still maintains its value. :( 

#include <avr/io.h>
#include "atmel_start.h"

#define ENABLED		1
#define DISABLED	0
#define FCLK_MAIN	20000	//KHz
#define PRESCALE	6	

int main(void)
{
	//VARIABLES
	int PWM_per, PWM_duty_cycle,  peripheral1_en, peripheral2_en, driver_en, iL_max, dac_data, iL_max_error, PWM_freq_maxError;
	float PWM_frequency, dac_data_aux, PWM_per_aux, duty_cycle_aux;
	
	//Inicializamos variables que sean necesarias
	 PWM_freq_maxError = 0;
	 iL_max_error = 0;
	
	//*************************   PARÁMETROS   ****************************//
	PWM_frequency	=	13;				// KHz. (Valor mínimo igual a la Fclk/prescala=Fclk_peripheral)
	PWM_duty_cycle	=	50;				// En tanto por ciento (0-100%)
	iL_max			=	8260;			
	peripheral1_en	=	ENABLED;		// 1-Enabled; 0-Disabled
	peripheral2_en	=	DISABLED;		// 1-Enabled; 0-Disabled
	driver_en		=	ENABLED;		// 1-Enabled; 0-Disabled
	
	CCP = CCP_IOREG_gc;
	//CPU_CCP=0xD8;
	
	CLKCTRL.MCLKCTRLA=0b00000001;	 // The CLKOUT pin is disable and the source for de main clock is "16/20MHz internal oscillator"
	CLKCTRL.MCLKCTRLB=0x01;			// The prescaler is enable and the prescale is "/2"
	
	//***********************FREQUENCY**************************//
	
	
	PWM_per_aux = (FCLK_MAIN/(PRESCALE*PWM_frequency))-1;
	PWM_per = (int) PWM_per_aux;

	//********************DAC************************//

	dac_data_aux=iL_max/32.39; 
	dac_data=(int)dac_data_aux;
	//***********************************************//
	 
	atmel_start_init(dac_data, PWM_per, PWM_duty_cycle, peripheral1_en, peripheral2_en, driver_en);
	
    while (1) 
    {
    }
}

 

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

Rodri_Go11 wrote:

I think that the problem is not here...... :/. What do you think? 

 

Thank you very much

 

10.3.5 Configuration Change Protection
This peripheral has registers that are under Configuration Change Protection (CCP). In order to write to
these, a certain key must be written to the CPU.CCP register first, followed by a write access to the
protected bits within four CPU instructions.
It is possible to try writing to these registers any time, but the values are not altered.
The following registers are under CCP:
Table 10-2. CLKCTRL - Registers under Configuration Change Protection
Register Key
CLKCTRL.MCLKCTRLB IOREG
CLKCTRL.MCLKLOCK IOREG
CLKCTRL.XOSC32KCTRLA IOREG
CLKCTRL.MCLKCTRLA IOREG
CLKCTRL.OSC20MCTRLA IOREG
CLKCTRL.OSC20MCALIBA IOREG
CLKCTRL.OSC20MCALIBB IOREG
CLKCTRL.OSC32KCTRLA IOREG

As you can see these registers are IOREG, so they are protected by the CCP.

It is also stated in the clock register descriptions: 

Property: Configuration Change Protection

You set CPU.CCP = 0xD8; before writing to the registers within 4 instructions.

 

CLKCTRL.MCLKCTRLA=0b00000001;	 // The CLKOUT pin is disable and the source for de main clock is "16/20MHz internal oscillator"
CLKCTRL.MCLKCTRLB=0x01;			// The prescaler is enable and the prescale is "/2"

MCLKCTRLA = 0x0 for 16/20MHz internal oscillator.

 

Planning to start testing the tiny817 myself this weekend, it's not as simple as the other AVR's unfortunately.

But I really like some of the things I see in the datasheet!

 

 

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

Just tested setting clock on a ATtiny817

 

CPU_CCP = 0xD8;
CLKCTRL_MCLKCTRLA = CLKCTRL_CLKSEL_OSC20M_gc;
CPU_CCP = 0xD8;
CLKCTRL_MCLKCTRLB = 0x1;

Confirmed as 10MHz

 

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

Rodri_Go11 wrote:
adding the relative lines to the CPP and I have executed and the output remains unchanged

	CCP = CCP_IOREG_gc;
	//CPU_CCP=0xD8;

	CLKCTRL.MCLKCTRLA=0b00000001;	 // The CLKOUT pin is disable and the source for de main clock is "16/20MHz internal oscillator"
	CLKCTRL.MCLKCTRLB=0x01;			// The prescaler is enable and the prescale is "/2"

canbeany1 wrote:
Just tested setting clock on a ATtiny817

CPU_CCP = 0xD8;
CLKCTRL_MCLKCTRLA = CLKCTRL_CLKSEL_OSC20M_gc;
CPU_CCP = 0xD8;
CLKCTRL_MCLKCTRLB = 0x1;

Confirmed as 10MHz

 

Spot the difference!

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

Better to use _PROTECTED_WRITE()

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

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

meolsen wrote:

Better to use _PROTECTED_WRITE()

 

I need to read the manual better.

Tusen takk for den! laughyes

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

meolsen wrote:
_PROTECTED_WRITE()

 

AVR Libc Reference Manual wrote:

Write value value to IO register reg that is protected through the Xmega (sic) configuration change protection (CCP) mechanism

Someone needs to update that to clarify that the "Xmega" there now includes some "ATtiny" models ...

 

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

awneil wrote:

meolsen wrote:
_PROTECTED_WRITE()

 

AVR Libc Reference Manual wrote:

Write value value to IO register reg that is protected through the Xmega (sic) configuration change protection (CCP) mechanism

Someone needs to update that to clarify that the "Xmega" there now includes some "ATtiny" models ...

 

 

That's true. I got a hint of it when adding the ATtiny817 from device packs, .o and .a were in a folder named "avrxmega2".