Как временно изменить частоту МК?

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Нужно именно на некоторе время, без прошивки фьюзов. Как понизить я знаю:

    // переводим МК на пониженную частоту работы 62.5 кГц 
    CLKPR = 1<<CLKPCE;
    CLKPR = 8;

А вот как вернуть все обратно на 16 МГц? 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Tomasina пишет:

А вот как вернуть все обратно на 16 МГц? 

Эм... так?

CLKPR = 1<<CLKPCE;
CLKPR = 0; //делитель 1

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Tomasina, ну логично что :

CLKPR=1<<CLKPCE; CLKPR&=B11110000;

не проверял :)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

dimax пишет:

Tomasina, ну логично что :

CLKPR=1<<CLKPCE; CLKPR&=B11110000;

не проверял :)

с возвратом назад что-то не задалось

Kakmyc
Онлайн
Зарегистрирован: 15.01.2018
CLKPR&=~(1<<CLKPCE);

Просто предделитель наместо поставить пробовал ? 

Весь регистр то зачем обнулять ?

Там есть биты не только множителя.

Почему то некорректно выводит текстом, засунул кодом...

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

наин!!! )))

код проверки такой

int flag = 0;
void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13,HIGH);
// переводим МК на пониженную частоту работы 62.5 кГц 
CLKPR = 1<<CLKPCE;
CLKPR = 8;

}

void loop() {
if(flag >=3 ){
// переводим МК на частоту работы 16mHz
//CLKPR=1<<CLKPCE; 
//CLKPR&=B11110000;  
CLKPR&=~(1<<CLKPCE);
  }
 delay(50); 
   digitalWrite(13,!digitalRead(13));
   flag++;
}

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Kakmyc, дык  CLKPR&=B11110000;   это и есть обнуление только предделителя. Старшие 4 бита не трогаются.

ua6em, может не задалось по какой то сторонней причине? :)

Kakmyc
Онлайн
Зарегистрирован: 15.01.2018

"Не трогаются", это остаются такими же , что и были.

Кто сказал что старшие 4 бита конфигурировали как 1111 ?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

dimax пишет:

Kakmyc, дык  CLKPR&=B11110000;   это и есть обнуление только предделителя. Старшие 4 бита не трогаются.

ua6em, может не задалось по какой то сторонней причине? :)

DIMAX ты же знаешь, если что-то может теоретически пойти не так у меня оно именно так и пойдёт )))
 

Komandir
Offline
Зарегистрирован: 18.08.2018

Kakmyc там & вообщето !

ua6em в 16 строке разрешили изменение предделителя, а где само изменение ???

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

Kakmyc пишет:

"Не трогаются", это остаются такими же , что и были.

Кто сказал что старшие 4 бита конфигурировали как 1111 ?

а кто сказал, что операция & устанавливает их в B1111

Kakmyc
Онлайн
Зарегистрирован: 15.01.2018

Вот так это делается оказывается

int flag = 0;
 void setup() { pinMode(13, OUTPUT);
     digitalWrite(13,HIGH); // переводим МК на пониженную частоту работы 62.5 кГц
     CLKPR = 1<<CLKPCE; 
    CLKPR = 2; }
 void loop() { 
    if(flag >=10 ){ // переводим МК на частоту работы 16mHz //CLKPR=1<<CLKPCE; //
CLKPR=1<<CLKPCE; 
CLKPR=0; } delay(50); digitalWrite(13,!digitalRead(13)); flag++; }

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ua6em, пришлось даташит смотреть. В общем фиг знает, почему так не срабатывает. Но там в регистре больше ничего нет, так что  отключать можно обнулением.

CLKPR=1<<CLKPCE; 
CLKPR=0; 

 

Kakmyc
Онлайн
Зарегистрирован: 15.01.2018

В общем смысл. 

Выставляем бит CLKPSE в лог1.

Действительно в течении 4 тактов.

Поэтому  сразу следом вводим предделитель.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

"яйца подействовали" - )))
 

int flag = 0;
void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13,HIGH);
// переводим МК на пониженную частоту работы 62.5 кГц 
CLKPR = 1<<CLKPCE;
CLKPR = 8;

}

void loop() {
if(flag >=3 ){
// переводим МК на частоту работы 16mHz
CLKPR=1<<CLKPCE;
CLKPR=0; 
//CLKPR&=B11110000;  
//CLKPR&=~(1<<CLKPCE);
//CLKPR&=B11110000; 
  }
 delay(50); 
   digitalWrite(13,!digitalRead(13));
   flag++;
}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

я тут подумал, логическое И с данными видимо в 4 такта процессора не укладывается
 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Вложу свои 5 копеек блинком с замедлением (пишут, что способ офигенно электричество экономит):

#include <util/atomic.h>
/*
  N | CLKPS3 | CLKPS2 | CLKPS1 | CLKPS0 | Clock Division Factor
  0     0        0        0        0            1
  1     0        0        0        1            2
  2     0        0        1        0            4
  3     0        0        1        1            8
  4     0        1        0        0           16
  5     0        1        0        1           32
  6     0        1        1        0           64
  7     0        1        1        1          128
  8     1        0        0        0          256
*/
#define DIVISION_FACTOR_MIN    0x00
#define DIVISION_FACTOR_MAX    0x03

const uint8_t ledPin = 13;
const uint32_t long blinkInterval = 250;
const uint32_t long slowdownInterval = 5000;

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  static uint8_t  ledState = LOW,
                  divisionFactor = DIVISION_FACTOR_MIN;
  static uint32_t previousBlinkTime, previousSlowdownTime;

  uint32_t nowTime = millis();

  if (nowTime - previousBlinkTime > blinkInterval) {
    previousBlinkTime = nowTime;
    ledState = !ledState;
    digitalWrite(ledPin, ledState);
  }

  if (nowTime - previousSlowdownTime > slowdownInterval) {
    previousSlowdownTime = nowTime;
    divisionFactor = (divisionFactor + 1) % DIVISION_FACTOR_MAX;
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
      CLKPR = (1 << CLKPCE);
      CLKPR = divisionFactor;
    }
  }
}