Всё про ATmega328PB

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

DetSimen пишет:

oleg_kazakof пишет:

Третий раз делаю подписку на эту тему, но кто-то удаляет пост, зачем ?.  Соответственно уведомления не приходят. 

Если пост пустой - я удаляю, не разбираясь, для подписки он или руки не туда дрогнули.  На этом форуме это стандартная практика. 

Дед, до этого момента, если тема меня заинтересовала я ставил - точку(.) и всё уведомления на почту, это по моему и была стандартная практика на этом форуме.

 

sadman41
Offline
Зарегистрирован: 19.10.2016

ua6em пишет:

sadman41 пишет:

Индикацию чего?

визуальную индикацию работы таймеров, светодиод для этого на плате уже есть - LED на пине 13, в идеале 1 короткая вспышка - 0 таймер, две - 1-й и так далее, по кругу на всех доступных таймерах

До сих пор ничерта не понимаю. Перед каждым вызовом добавить for(uint8_t i=0; 3 > i; i++) { digitalWrite(13, HIGH); delay(200); digitalWrite(13, LOW);} что ли?

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

Да как угодно. чтобы работу всех таймеров можно было визуально проверить только одним светодиодом )))

Вот тут я сделал по рабоче-крестьянски, но для того, чтобы проверить все таймера надо изменять номер таймера и заливать прошивку, а это - пять раз, сможешь сделать ХЭД ЭНД ШОЛДЕРС будет великолепно

sadman41
Offline
Зарегистрирован: 19.10.2016

ua6em пишет:

Да как угодно. чтобы работу всех таймеров можно было визуально проверить только одним светодиодом )))

Ну подключайте один светодиод к разным ногам. Или думаете, что я каким-то волшебным способом заставлю T1 меандр выдавать на D13, а не на D9?

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

sadman41 пишет:

ua6em пишет:

Да как угодно. чтобы работу всех таймеров можно было визуально проверить только одним светодиодом )))

Ну подключайте один светодиод к разным ногам. Или думаете, что я каким-то волшебным способом заставлю T1 меандр выдавать на D13, а не на D9?

впрямую нет, но программист, он жеж как бог, не вижу почему это нельзя сделать

bwn
Offline
Зарегистрирован: 25.08.2014

oleg_kazakof пишет:

Дед, до этого момента, если тема меня заинтересовала я ставил - точку(.) и всё уведомления на почту, это по моему и была стандартная практика на этом форуме.

Олег, просто точки, я тоже удаляю, т.к. неясно, человек запостил и потом стер или подписался.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Стандартная практика, на большинстве форумов, внятно, по-русски, написать "подпишусь",  а не плодить посты с точками.  Или я из тьмы выпал? 

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

А ещё лучше написать что-то полезное по теме :)
Есть много чего, что можно исследовать обладателям этого МК, например:
-как "заардуинить" сенсорные кнопки на этом мк.
-тестирование стабильности при разгоне.
-сравнить разные аддоны

 

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

dimax пишет:

А ещё лучше написать что-то полезное по теме :)
Есть много чего, что можно исследовать обладателям этого МК, например:
-как "заардуинить" сенсорные кнопки на этом мк.
-тестирование стабильности при разгоне.
-сравнить разные аддоны

как раз последним и занимаюсь, сравниваю, аддон от pololu выпадает, много косяков

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

продолжаю исследовать аддоны, в аддоне от MiniCore (в нём доступны и другие процессоры) есть возможность установки BOD и опции компилятора LTO, при разрешении последнего к примеру на скетче квона для LCD2004 позволяет экономить память программ до полкилобайта!

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

Проверочный скетч, задействованы все таймеры:
 

// Скетч проверки таймеров для платы на чипе ATmega328PB
#include "ConstTimers.h"

#define TIMER0 0 //здесь указать номер таймера, индикация - мигание LED на пине 13
#define FREQUENCY0 1600
#define TIMER1 1 //здесь указать номер таймера, индикация - мигание LED на пине 13
#define FREQUENCY1 3200
#define TIMER2 2 //здесь указать номер таймера, индикация - мигание LED на пине 13
#define FREQUENCY2 6400
#define TIMER3 3 //здесь указать номер таймера, индикация - мигание LED на пине 13
#define FREQUENCY3 12800
#define TIMER4 4 //здесь указать номер таймера, индикация - мигание LED на пине 13
#define FREQUENCY4 25600

uint8_t t, p;
const byte delta = 1; //отклонение частоты от расчетной в %
unsigned int counter, counter1 = 0;

void setup() {
  constexpr uint8_t prescalerBits0 = prescalerBitsByFrequency(TIMER0, FREQUENCY0);
  constexpr uint16_t timerTicks0 = timerTicksByFrequency(TIMER0, FREQUENCY0, delta);
  static_assert(timerTicks0, "The required frequency is unattainable");

  constexpr uint8_t prescalerBits1 = prescalerBitsByFrequency(TIMER1, FREQUENCY1);
  constexpr uint16_t timerTicks1 = timerTicksByFrequency(TIMER1, FREQUENCY1, delta);
  static_assert(timerTicks1, "The required frequency is unattainable");

  constexpr uint8_t prescalerBits2 = prescalerBitsByFrequency(TIMER2, FREQUENCY2);
  constexpr uint16_t timerTicks2 = timerTicksByFrequency(TIMER2, FREQUENCY2, delta);
  static_assert(timerTicks2, "The required frequency is unattainable");

  constexpr uint8_t prescalerBits3 = prescalerBitsByFrequency(TIMER3, FREQUENCY3);
  constexpr uint16_t timerTicks3 = timerTicksByFrequency(TIMER3, FREQUENCY3, delta);
  static_assert(timerTicks3, "The required frequency is unattainable");

  constexpr uint8_t prescalerBits4 = prescalerBitsByFrequency(TIMER4, FREQUENCY4);
  constexpr uint16_t timerTicks4 = timerTicksByFrequency(TIMER4, FREQUENCY4, delta);
  static_assert(timerTicks0, "The required frequency is unattainable");
  
  pinMode(13, OUTPUT);
  //t=TIMER;

  //if(t==0){
  // p=6;
   pinMode(6, OUTPUT);
   TCCR0A = 0x42;                  // Инвертирование пина 6 по сравнению и режим CTC то OCR0A
   TCCR0B = 0x00 | prescalerBits0;  // Установить СТС режим и делитель частоты
   OCR0A = timerTicks0;             // установить TOP равным timerTicks
 // }

 // if(t==1){
 // p=9;  
  pinMode(9, OUTPUT);
  TCCR1A = bit(COM1A0);                 // Инвертирование пина 9 по сравнению
  TCCR1B = bit(WGM12) | prescalerBits1;  // Установить СТС режим и делитель частоты
  OCR1A = timerTicks1;                   // установить TOP равным timerTicks
 // }

 // if(t==2){
 // p=11;  
  pinMode(11, OUTPUT);
  TCCR2A = 0x42;                   // Инвертирование пина 11 по сравнению и режим CTC то OCR2A
  TCCR2B = 0x00 |  prescalerBits2;  // Установить СТС режим и делитель частоты
  OCR2A = timerTicks2;              // установить TOP равным timerTicks
 // }

//  if(t==3){
 // p = 0;
  pinMode(0, OUTPUT);
  TCCR3A=1<<COM3A0 | 1<<COM3B0; 
  TCCR3B=1<<WGM32 | prescalerBits3;   // Режим СТС WGM3[3:0]=4 или 12
  OCR3A = timerTicks3;                // установить TOP равным timerTicks
//  }

  // if(t==4){
 // p = 1;
  pinMode(1, OUTPUT);
  TCCR4A=1<<COM4A0 | 1<<COM4B0; 
  TCCR4B=1<<WGM42 | prescalerBits4;   // Режим СТС WGM4[3:0]=4 или 12
  OCR4A = timerTicks4;                // установить TOP равным timerTicks
//  }
}

void loop() {
  while(counter1 <10){
  while(digitalRead(6)==LOW);
  counter++;
  while(digitalRead(6)==HIGH);
  if(counter==FREQUENCY0/4){ // BLINK 250 мсек
  digitalWrite(13,!digitalRead(13));
  counter = 0; counter1++;}
  }
 counter1=0;

  while(counter1 <10){
  while(digitalRead(9)==LOW);
  counter++;
  while(digitalRead(9)==HIGH);
  if(counter==FREQUENCY1/8){ // BLINK 250 мсек
  digitalWrite(13,!digitalRead(13));
  counter = 0; counter1++;}
  }
 counter1=0;

while(counter1 <10){
  while(digitalRead(11)==LOW);
  counter++;
  while(digitalRead(11)==HIGH);
  if(counter==FREQUENCY2/4){ // BLINK 250 мсек
  digitalWrite(13,!digitalRead(13));
  counter = 0; counter1++;}
  }
 counter1=0; 

while(counter1 <10){
  while(digitalRead(0)==LOW);
  counter++;
  while(digitalRead(0)==HIGH);
  if(counter==FREQUENCY3/8){ // BLINK 250 мсек
  digitalWrite(13,!digitalRead(13));
  counter = 0; counter1++;}
  }
 counter1=0;  

while(counter1 <10){
  while(digitalRead(1)==LOW);
  counter++;
  while(digitalRead(1)==HIGH);
  if(counter==FREQUENCY4/4){ // BLINK 250 мсек
  digitalWrite(13,!digitalRead(13));
  counter = 0; counter1++;}
  }
  counter1=0;  
 }
  
 
 

И библиотека к нему:
 

#ifndef  CONSTTIMERS_H
#define CONSTTIMERS_H

///////////////////////////////////////////////////////////////////////////////
//
// Модификация недобиблиотеки от ЕвгенийП.
// Выполнена: Ворота, 11.07.2019.
// Проба: UA6EM 12.07.2019 (Atmega328PB, WAVGAT, LGT8FX8P)
// 
// Основные изменения:
// 1. К работе с частотами добавлена работа с периодами/интервалами;
// 2. Добавлено задание максимальной допустимой погрешности количества тактов;
// 3. Появилась возможность выдавать ошибку компиляции в случае выхода за допустимую погрешность;
// 4. Добавлены суффиксы для работы с временными интервалами (на основе другого кода от ЕвгенийП);
// 5. Добавлена поддержка Мега, Леонардо и ATmega32A
// 6. Все «внутренние» функции спрятаны в своё пространство имён.
// 
// ---------------
// 
// Определяются биты конфигурации делителя частоты таймера и количество тактов с данным делителем для 
// получения нужного интервала срабатывания таймера. Интервал задаётся либо частотой, либо периодом 
// (длительностью, если речь идёт об одиночном сигнале, например, по переполнению). 
// Соответственно, имеются четыре функции:
// 
// uint8_t prescalerBitsByPeriod(int8_t nTimer, uint32_t period);
// uint16_t timerTicksByPeriod(int8_t nTimer, uint32_t period, int8_t error = 0);
// 
// uint8_t prescalerBitsByFrequency(int8_t nTimer, uint32_t frequency);
// uint16_t timerTicksByFrequency(int8_t nTimer, uint32_t frequency, int8_t error = 0);
// 
// Первый параметр у всех функций – номер таймера. Параметры period и frequency – соответственно  
// требуемые период в тактах микроконтроллера (см. ниже о суффиксах) и частота (в герцах).   
// Параметр error задаёт допустимое отклонение от запрошенных характеристик в процентах. 
// Если не удаётся получить решение в пределах допустимого отклонения, то timerTicksByХХХ вернут 0.
// 
// Также имеется функция, возвращающая значение делителя частоты заданного таймера по битам конфигурации, 
// полученным от функций prescalerBitsByХХХ.
// 
// int16_t prescalerValue(uint8_t nTimer, uint8_t bits);
// 
// Для удобства работы с временными интервалами добавлены суффиксы _clk, _us, _ms и _sec. Таким образом, 
// второй параметр функций prescalerBitsByPeriod и timerTicksByPeriod (время в тактах микроконтроллера) 
// можно задавать при помощи суффиксов, например:
//
//    100 или 100_clk – сто тактов микроконтроллера;
//    100_us – сто микросекунд;
//    100_ms – сто миллисекунд;
//    2_sec – две секунды.
//    
// Допускаются также арифметические операции, например, запись
//
//    2_ms + 50_us
//
// вполне допустима и означает 2050 микросекунд.
//
//  ИСПОЛЬЗОВАНИЕ
//
// Для использования необходимо включить файл «ConstTimers.h» и определить константы с
// модификатором constexpr для нужных конфигурационных битов и количества тиков, которым
// присвоить значения, возвращаемые функциям prescalerBitsByХХХ и timerTicksByХХХ соответственно.
//
// Если использовать именно так, то код библиотеки целиком исполняется во время компиляции
// и не оказывает никакого влияния ни на размер занимаемой памяти, ни на код программы.
// В коде программы будут вставлены готовые (вычисленные на этапе компиляции) константы.
//
// Это позволяет организовать проверку полученного на этапе компиляции значения (функции
// timerTicksByХХХ возвращают 0 в случае невозможности соблюсти необходимую точность)
// и прервать компиляцию с соответствующим сообщением об ошибке при помощи static_assert.
//
//  Пример рекомендуемого использования:
//
//    /////////////////////////////////////////////////
//    //
//    //  Получаем меандр с частотой 50Гц на 9-ом пине
//    //  для этого заводим его на СТС и инвертированием
//    //  на частоте 100Гц (как раз 100/2 = 50)
//    //
//    #include <ConstTimers.h>
//
//    #define TIMER 1
//    #define FREQUENCY 100
//
//    static constexpr uint8_t prescalerBits = prescalerBitsByFrequency(TIMER, FREQUENCY);
//    static constexpr uint16_t timerTicks = timerTicksByFrequency(TIMER, FREQUENCY);
//
//    // проверка установилась ли частота (например, при частоте 101 будет ошибка компиляции)
//    static_assert(timerTicks, "The required frequency with a desired accuracy is unattainable for timer/counter");
//
//    void setup() {
//      pinMode(9, OUTPUT);
//      TCCR1A = bit(COM1A0); // Инвертирование пина 9 по сравнению
//      TCCR1B = bit(WGM12) | prescalerBits;  // Установить СТС режим и делитель частоты
//      OCR1A = timerTicks; // установить TOP равным timerTicks
//    }
//
//    void loop() {}
//
//Результат работы будет точно такой же, как если написать константы, вместо вычислений:
//
//    void setup() {
//      pinMode(9, OUTPUT);
//      TCCR1A = bit(COM1A0);
//      TCCR1B = bit(WGM12) | 2;
//      OCR1A = 20000;
//    }
//    void loop() {}
//
// Ни на один байт код не изменится.
//
//  КОНФИГУРАЦИЯ:
//
//  1. расчёт производится для текущей тактовой частоты микроконтроллера. Если нужно
//    считать для какой-то другой частоты, измените константу FCPU.
//
//  2. STimerParameters - массив конфигурации таймеров. Количество элементов массива
//    соответствует количеству таймеров. Нулевой элемент описывает нулевой таймер,
//    первый элемент – первый таймер и т.д. Если требуется расширить недобиблиотеку для других
//    микроконтроллеров, нужно изменить именно этот массив и больше изменять ничего не надо.
//
//  В массиве для каждого таймера указано:
//    1) разрядность таймера в виде максимально возможного значения количества тиков
//      (для 8-разрядных таймеров – 0xFF, для 16-разрядных – 0xFFFF.
//    2) указатель на массив делителей частоты. Делители начинаются с 1 (делитель 0 писать не нужно)
//    3) количество делителей частоты у данного таймера.
//
// ЛИЦЕНЗИЯ
//
// Данный код поставляется по лицензии ПНХ.
//
// 1. Вы можете свободно использовать или не использовать его в коммерческих,
//    некоммерческих, и любых иных, не запрещённых законом, целях.
//
// 2. Автор не несёт решительно никакой ответственности за любые положительные
//    или отрицательные результаты использования или неиспользования данного кода.
//
// 3. Если Вам таки хочется сделать автору предъяву, то Вы знаете, куда
//    Вам следует обратиться. А если не знаете, то см. название лицензии.
//
// 4. Если данный код вдруг Вам пригодился (как учебник или ещё как что) и Вам
//    почему-либо (ну, приболели, может) захотелось отблагодарить автора рублём,
//    то это всегда пожалуйста – WebMoney, кошелёк № R626206676373
//
// 5. Возникновение или невозникновение у Вас желаний, обозначенных в п.4
//     настоящей лицензии никак не связано с п.1, который действует безусловно
//     и независимо от п.4.
//
// 6. Если данный код нужен Вам с какой-либо другой лицензией, например, с
//     сопровождением или Вы нуждаетесь во внесении изменений, свяжитесь с автором
//     на предмет заключения договора гражданско-правового характера.
//
///////////////////////////////////////////////////////////////////////////////

#define ATtiny85Detected  (defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__))
#define ATmega328Detected (defined(__AVR_ATmega48A__) || defined(__AVR_ATmega48PA__) || defined(__AVR_ATmega88A__) \
  || defined(__AVR_ATmega88PA__) || defined(__AVR_ATmega168A__) || defined(__AVR_ATmega168PA__) \
  || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__))
#define ATmega2561Detected  (defined(__AVR_ATmega640__) || defined(__AVR_ATmega640V__) || defined(__AVR_ATmega1280__) \
  || defined(__AVR_ATmega1280V__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega1281V__) \
  || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2560V__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega2561V__))
#define ATmega32U4Detected (defined(__AVR_ATmega32U4__))
#define ATmega32ADetected (defined(__AVR_ATmega32A__))
#define ATmega328PBDetected (defined(__AVR_ATmega328PB__))
#define Wavgatlgtx8PDetected (defined(__LGT8FX8P32__)) || (defined(__LGT8FX8P__))

#define FCPU  F_CPU

namespace constTimersNS {

struct STimerParameters {
  const uint32_t maxValue;
  const int16_t * prescalers;
  const uint8_t totalPrescalers;
};

static constexpr uint32_t bits8 = 0x000000FFul;
static constexpr uint32_t bits10 = 0x000003FFul;
static constexpr uint32_t bits16 = 0x0000FFFFul;

#if Wavgatlgtx8PDetected

static constexpr  int16_t prescalers013[] = { 1, 8, 64, 256, 1024 };
static constexpr  int16_t prescalers2[] = { 1, 8, 32, 64, 128, 256, 1024 };

static constexpr STimerParameters timerParameters[] = {
  { bits8, prescalers013, sizeof(prescalers013) / sizeof(prescalers013[0]) },
  { bits16, prescalers013, sizeof(prescalers013) / sizeof(prescalers013[0]) },
  { bits8, prescalers2, sizeof(prescalers2) / sizeof(prescalers2[0]) },
  { bits16, prescalers013, sizeof(prescalers013) / sizeof(prescalers013[0]) }
};

#elif ATmega328PBDetected

static constexpr  int16_t prescalers0134[] = { 1, 8, 64, 256, 1024 };
static constexpr  int16_t prescalers2[] = { 1, 8, 32, 64, 128, 256, 1024 };

static constexpr STimerParameters timerParameters[] = {
  { bits8, prescalers0134, sizeof(prescalers0134) / sizeof(prescalers0134[0]) },
  { bits16, prescalers0134, sizeof(prescalers0134) / sizeof(prescalers0134[0]) },
  { bits8, prescalers2, sizeof(prescalers2) / sizeof(prescalers2[0]) },
  { bits16, prescalers0134, sizeof(prescalers0134) / sizeof(prescalers0134[0]) },
  { bits16, prescalers0134, sizeof(prescalers0134) / sizeof(prescalers0134[0]) }
};

#elif ATmega328Detected || ATmega32ADetected

static constexpr  int16_t prescalers01[] = { 1, 8, 64, 256, 1024 };
static constexpr  int16_t prescalers2[] = { 1, 8, 32, 64, 128, 256, 1024 };
static constexpr  int16_t prescalers3[] = { 1, 8, 64, 256, 1024 };

static constexpr STimerParameters timerParameters[] = {
  { bits8, prescalers01, sizeof(prescalers01) / sizeof(prescalers01[0]) },
  { bits16, prescalers01, sizeof(prescalers01) / sizeof(prescalers01[0]) },
  { bits8, prescalers2, sizeof(prescalers2) / sizeof(prescalers2[0]) },
  { bits16, prescalers3, sizeof(prescalers3) / sizeof(prescalers3[0]) } // для WAVGAT
};

#elif ATmega32U4Detected

static constexpr  int16_t prescalers013[] = { 1, 8, 64, 256, 1024 };
static constexpr  int16_t prescalers2[] = { 1, 8, 32, 64, 128, 256, 1024 };
static constexpr  int16_t prescalers4[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384 };

static constexpr STimerParameters timerParameters[] = {
  { bits8, prescalers013, sizeof(prescalers013) / sizeof(prescalers013[0]) },
  { bits16, prescalers013, sizeof(prescalers013) / sizeof(prescalers013[0]) },
  { bits8, prescalers2, sizeof(prescalers2) / sizeof(prescalers2[0]) },
  { bits16, prescalers013, sizeof(prescalers013) / sizeof(prescalers013[0]) },
  { bits10, prescalers4, sizeof(prescalers4) / sizeof(prescalers4[0]) }
};

#elif ATmega2561Detected

static constexpr  int16_t prescalers01345[] = { 1, 8, 64, 256, 1024 };
static constexpr  int16_t prescalers2[] = { 1, 8, 32, 64, 128, 256, 1024 };

static constexpr STimerParameters timerParameters[] = {
  { bits8, prescalers01345, sizeof(prescalers01345) / sizeof(prescalers01345[0]) },
  { bits16, prescalers01345, sizeof(prescalers01345) / sizeof(prescalers01345[0]) },
  { bits8, prescalers2, sizeof(prescalers2) / sizeof(prescalers2[0]) },
  { bits16, prescalers01345, sizeof(prescalers01345) / sizeof(prescalers01345[0]) },
  { bits16, prescalers01345, sizeof(prescalers01345) / sizeof(prescalers01345[0]) },
  { bits16, prescalers01345, sizeof(prescalers01345) / sizeof(prescalers01345[0]) }
};

#elif ATtiny85Detected

static constexpr  int16_t prescalers0[] = { 1, 8, 64, 256, 1024 };
static constexpr  int16_t prescalers1[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384 };

static constexpr STimerParameters timerParameters[] = {
  { bits8, prescalers0, sizeof(prescalers0) / sizeof(prescalers0[0]) },
  { bits8, prescalers1, sizeof(prescalers1) / sizeof(prescalers1[0]) }
};

#else

#error The library does not seem to support your MCU

#endif

constexpr int8_t totalTimers = sizeof(timerParameters) / sizeof(timerParameters[0]);

static constexpr uint32_t getPeriod(const uint32_t frequency) {
  return (FCPU + frequency / 2) / frequency;
}

static constexpr uint16_t prValue(const int8_t prescalerId, const int8_t nTimer) {
  return timerParameters[nTimer].prescalers[prescalerId];
}

static constexpr uint32_t getDesiredTicks(const uint32_t period, const int8_t prescalerId, const int8_t nTimer) {
  return (period + prValue(prescalerId, nTimer) / 2) / prValue(prescalerId, nTimer);
}

static constexpr uint32_t correctTicks(uint32_t dTicks, const uint32_t maxValue) {
  //if (dTicks > maxValue) return maxValue; else return dTicks; // начиная с C++14
  return dTicks > maxValue ? maxValue : dTicks;
}

static constexpr uint32_t getTicks(const uint32_t period, const int8_t prescalerId, const int8_t nTimer) {
  return prescalerId >= timerParameters[nTimer].totalPrescalers ? 0x1FFFFFFF :
  correctTicks(getDesiredTicks(period, prescalerId, nTimer), timerParameters[nTimer].maxValue);
}

static constexpr uint32_t getBits(const int8_t prescalerId, const int8_t nTimer) {
  return prescalerId >= timerParameters[nTimer].totalPrescalers ? timerParameters[nTimer].totalPrescalers : prescalerId + 1;
}


static constexpr int32_t absErrorTicks(const uint32_t period, const uint32_t ticks) {
  return period > ticks ? period - ticks : ticks - period;
}

static constexpr int32_t absError(const uint32_t period, const int8_t prescalerId, const int8_t nTimer) {
  return prescalerId >= timerParameters[nTimer].totalPrescalers ? 0x1FFFFFFF :
  absErrorTicks(period, getTicks(period, prescalerId, nTimer) * prValue(prescalerId, nTimer));
}

static constexpr uint8_t getPrescalerId(const uint32_t error, const uint32_t newError, const uint8_t prId, const uint8_t candidate, const uint32_t period, const int8_t nTimer) {
  return
  (prId >= timerParameters[nTimer].totalPrescalers) ? candidate
  : getPrescalerId(newError, absError(period, prId + 1, nTimer), prId + 1, (error <= newError) ? candidate : prId, period, nTimer);
}

static constexpr double calcErrorPercentage(const double fcpu, const double perc) {
  return (fcpu < perc ? 1.0 - fcpu / perc : fcpu / perc - 1.0) * 100.0;
}

static constexpr uint16_t returnTicksOrZero(const uint32_t left, const uint32_t right, const int8_t allowableError, const uint32_t ticks) {
  return left == right || calcErrorPercentage(left, right) <= allowableError ? ticks : 0;
}

static constexpr uint16_t getTimerTicksIntFTicks(const uint32_t ticks, const int8_t nTimer, const uint32_t freq, uint8_t prescalerId, const int8_t allowableError) {
  return returnTicksOrZero(FCPU, freq * ticks * timerParameters[nTimer].prescalers[prescalerId], allowableError, ticks);
}

static constexpr uint16_t getTimerTicksIntF(const int8_t nTimer, const uint32_t freq, uint8_t prescalerId, const int8_t allowableError) {
  return getTimerTicksIntFTicks(getTicks(getPeriod(freq), prescalerId, nTimer), nTimer, freq, prescalerId, allowableError);
}

static constexpr uint16_t getTimerTicksIntTTicks(const uint32_t ticks, const int8_t nTimer, const uint32_t period, uint8_t prescalerId, const int8_t allowableError) {
  return returnTicksOrZero(period, ticks * timerParameters[nTimer].prescalers[prescalerId], allowableError, ticks);
}

static constexpr uint16_t getTimerTicksIntT(const int8_t nTimer, const uint32_t period, uint8_t prescalerId, const int8_t allowableError) {
  return getTimerTicksIntTTicks(getTicks(period, prescalerId, nTimer), nTimer, period, prescalerId, allowableError);
}


//////////////////////////////////////////////////////////////////
//
//  Суффиксы литералов для задания времени
//    100 или 100_clk - время в тактах контроллера (100 тактов)
//    100_us - время в микросекундах (100 микросекунд)
//    100_ms - время в милисекундах (100 милисекунд)
//    5_sec - время в секундах (5 секунд)
//
static constexpr int8_t __sLen(const char * str, const int8_t candidate = 0) { return (!*str) ? candidate : __sLen(str + 1, candidate + 1); }
static constexpr bool __isFin(const char * str, const int8_t lInd) { return lInd < 0 || !isdigit(str[lInd]); }
static constexpr uint32_t __toDig(const char * str, const uint32_t lg, const int8_t lInd) { return (str[lInd] - '0') * lg; }
static constexpr uint32_t ___s2ul(const char * str, const uint32_t, const int8_t);
static constexpr uint32_t __nextL(const char * str, const uint32_t lg, const int8_t lInd) { return __toDig(str, lg, lInd) + ___s2ul(str, lg * 10, lInd - 1); }
static constexpr uint32_t ___s2ul(const char * str, const uint32_t lg, const int8_t lInd) { return __isFin(str, lInd) ? 0 : __nextL(str, lg, lInd); }
static constexpr uint32_t __s2ul(const char * str) { return ___s2ul(str, 1, __sLen(str) - 1); }

} //  namespace constTimersNS

static constexpr uint32_t operator "" _clk(const char * s) { return constTimersNS::__s2ul(s); }
static constexpr uint32_t operator "" _us(const char * s) { return operator "" _clk(s) * (FCPU / 1000000ul); }
static constexpr uint32_t operator "" _ms(const char * s) { return operator "" _us(s) * 1000ul; }
static constexpr uint32_t operator "" _sec(const char * s) { return operator "" _ms(s) * 1000ul; }
//
//////////////////////////////////////////////////////////////////


static constexpr uint8_t prescalerBitsByPeriod(const int8_t nTimer, const uint32_t period) {
  return constTimersNS::getBits(constTimersNS::getPrescalerId(0x1FFFFFul, constTimersNS::absError(period, 0, nTimer), 0, 0, period, nTimer), nTimer);
}

static constexpr uint16_t timerTicksByPeriod(const int8_t nTimer, const uint32_t period, const int8_t allowableError = 0) {
  return constTimersNS::getTimerTicksIntT(nTimer, period, constTimersNS::getPrescalerId(0x1FFFFFul, constTimersNS::absError(period, 0, nTimer), 0, 0, period, nTimer), allowableError);
}

static constexpr uint8_t prescalerBitsByFrequency(const int8_t nTimer, const uint32_t freq) {
  return prescalerBitsByPeriod(nTimer, constTimersNS::getPeriod(freq));
}

static constexpr uint16_t timerTicksByFrequency(const int8_t nTimer, const uint32_t freq, const int8_t allowableError = 0) {
  return constTimersNS::getTimerTicksIntF(nTimer, freq, 
      constTimersNS::getPrescalerId(0x1FFFFFul, constTimersNS::absError(constTimersNS::getPeriod(freq), 0, nTimer), 0, 0, 
      constTimersNS::getPeriod(freq), nTimer), allowableError);
}

static constexpr int16_t prescalerValue(const uint8_t nTimer, const uint8_t bits) {
  return constTimersNS::timerParameters[nTimer].prescalers[bits-1];
}

#endif  //  CONSTTIMERS_H

 

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015
nevkon
Offline
Зарегистрирован: 20.01.2015

А Atmel квадратиками закрасили чтобы не было претензий при получении левого чипа?

MaksVV
Offline
Зарегистрирован: 06.08.2015

задам тупой вопрос. А раз уж распиновка не очень с простым 328 совпадает, может просто другой камень повыше в линейке применять? Например 1284p. У него и с памятью совсем хорошо. Ну понятно по цене чуть дороже, но не сильно.

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

MaksVV, другой камень взять для чего? Этот мк для тех, кто привык к меге328 и к большому кол-ву библиотек, написанных под мегу328. Я вот хоть уже давно увлечён stm32, но именно к меге 328 сохранил тёплые дружеские чувства ;)

MaksVV
Offline
Зарегистрирован: 06.08.2015

понятно. согласен, всеобщая поддержка это важно.

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

Приветствую ! Ни у кого случаем нет лишнего камня ... двух ... на руках в России ? Купил бы с отправкой простым письмом.

P.S. За сутки никто не откликнулся ... :-(

Logik
Offline
Зарегистрирован: 05.08.2014

Рассчитывали что все, у кого нет отпишутся? )) Камень этот пока скорей экзотика.

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

Кстати на амперке появились нанки по вменяемой (для Москвы) цене https://amperka.ru/product/iskra-nano-pro-headless

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

Вот и задачка для платы нарисовалась, осталось подключить модуль и проверить )))

Yomasoul
Offline
Зарегистрирован: 21.04.2020

Кому нибудь попадались такие нано с 328pb
Их стоит брать?
#Aliexpress 159,89 руб. 10%СКИДКА | Nano Mini USB с Загрузчиком совместимый контроллер Nano 3,0 Для arduino CH340 USB драйвер Nano v3.0 Atmega328 Atmega328pb
https://a.aliexpress.ru/_BPjqJj

Yomasoul
Offline
Зарегистрирован: 21.04.2020
sadman41
Offline
Зарегистрирован: 19.10.2016

На фото обычный контроллер 328P

Yomasoul
Offline
Зарегистрирован: 21.04.2020

Если 328pb лучше 328p почему он не пошёл в массы и не обрёл популярность? В чем проблема использования для рядового пользователя?

sadman41
Offline
Зарегистрирован: 19.10.2016

Пойдет ещё, надеюсь. Существующий техпроцесс по производству ардуин со старыми МК никто не торопится ломать.

alex_r61
Offline
Зарегистрирован: 20.06.2012

Yomasoul пишет:
В чем проблема использования для рядового пользователя?

 Для рядового куча проблем: менталитет, отсутствие в массовых поделках, библиотеки надо править. Для меня вот эти интереснее https://aliexpress.ru/item/32828713412.html

 Ну а пока на макетке.

Charovnik
Charovnik аватар
Offline
Зарегистрирован: 05.02.2016

добрый день.

приобрел 328pb без загрущика.

подключил к ардуино нано по isp и кварцу в 16 мгц.

в менеджере плат скачал 328pb. при попытке залить бутлодырь  получается ошибка.

Arduino: 1.8.12 (Windows 10), Плата:"ATmega328PB Crystal Clock, 16 MHz"
 
Ошибка при записи загрузчика.
avrdude.exe: Expected signature for ATmega328PB is 1E 95 16
             Double check chip, or use -F to override this check.
 
пошарился по форумам ничего не получилось.
помогите с прошивкой пожалуста
b707
Offline
Зарегистрирован: 26.05.2017

Charovnik пишет:

 
Ошибка при записи загрузчика.
avrdude.exe: Expected signature for ATmega328PB is 1E 95 16
             Double check chip, or use -F to override this check.

выложите сообщение об ошибке полностью. В частности. если пишет "ожидаемая сигнатура такая-то..." - должен писать , какая реально прочитана с чипа

Charovnik
Charovnik аватар
Offline
Зарегистрирован: 05.02.2016
Arduino: 1.8.12 (Windows 10), Плата:"ATmega328PB Internal Clock, 8 MHz"
 
C:\Users\jp\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude.exe -CC:\Users\jp\AppData\Local\Arduino15\packages\m328pb\hardware\avr\1.1.4/tools/avrdude.conf -v -patmega328pb -cstk500v1 -PCOM11 -b19200 -e -Ulock:w:0xFF:m -Uefuse:w:0xFD:m -Uhfuse:w:0xD6:m -Ulfuse:w:0xE2:m 
 
avrdude.exe: Version 6.3-20190619
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch
 
             System wide configuration file is "C:\Users\jp\AppData\Local\Arduino15\packages\m328pb\hardware\avr\1.1.4/tools/avrdude.conf"
 
             Using Port                    : COM11
             Using Programmer              : stk500v1
             Overriding Baud Rate          : 19200
             AVR Part                      : ATmega328PB
             Chip Erase delay              : 9000 us
             PAGEL                         : PD7
             BS2                           : PC2
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 200
             StabDelay                     : 100
             CmdexeDelay                   : 25
             SyncLoops                     : 32
             ByteDelay                     : 0
             PollIndex                     : 3
             PollValue                     : 0x53
             Memory Detail                 :
 
                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
               flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
               lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
               signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
 
             Programmer Type : STK500
             Description     : Atmel STK500 Version 1.x firmware
             Hardware Version: 2
             Firmware Version: 1.18
             Topcard         : Unknown
             Vtarget         : 0.0 V
             Varef           : 0.0 V
             Oscillator      : Off
             SCK period      : 0.1 us
 
avrdude.exe: AVR device initialized and ready to accept instructions
 
Ошибка при записи загрузчика.
Reading | ################################################## | 100% 0.02s
 
avrdude.exe: Device signature = 0x0000ff
avrdude.exe: Expected signature for ATmega328PB is 1E 95 16
             Double check chip, or use -F to override this check.
 
avrdude.exe done.  Thank you.
b707
Offline
Зарегистрирован: 26.05.2017

Charovnik пишет:

avrdude.exe: Device signature = 0x0000ff

это означает, что МК не отвечает программатору.

Тут либо МК не стартует, либо в соединениях что-то напутали

Charovnik
Charovnik аватар
Offline
Зарегистрирован: 05.02.2016

взял другой чип попытался залить загрущик выбрав 16 мгц он вроде начал шиться но выкатил ошибку

 

Arduino: 1.8.12 (Windows 10), Плата:"ATmega328PB Crystal Clock, 16 MHz"


C:\Users\jp\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude.exe -CC:\Users\jp\AppData\Local\Arduino15\packages\m328pb\hardware\avr\1.1.4/tools/avrdude.conf -v -patmega328pb -cstk500v1 -PCOM14 -b19200 -e -Ulock:w:0xFF:m -Uefuse:w:0xFD:m -Uhfuse:w:0xD6:m -Ulfuse:w:0xFF:m 

avrdude.exe: Version 6.3-20190619
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "C:\Users\jp\AppData\Local\Arduino15\packages\m328pb\hardware\avr\1.1.4/tools/avrdude.conf"

             Using Port                    : COM14
             Using Programmer              : stk500v1
             Overriding Baud Rate          : 19200
             AVR Part                      : ATmega328PB
             Chip Erase delay              : 9000 us
             PAGEL                         : PD7
             BS2                           : PC2
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 200
             StabDelay                     : 100
             CmdexeDelay                   : 25
             SyncLoops                     : 32
             ByteDelay                     : 0
             PollIndex                     : 3
             PollValue                     : 0x53
             Memory Detail                 :

                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
               flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
               lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
               signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

             Programmer Type : STK500
             Description     : Atmel STK500 Version 1.x firmware
             Hardware Version: 2
             Firmware Version: 1.18
             Topcard         : Unknown
             Vtarget         : 0.0 V
             Varef           : 0.0 V
             Oscillator      : Off
             SCK period      : 0.1 us

avrdude.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude.exe: Device signature = 0x1e9516 (probably m328pb)
avrdude.exe: erasing chip
avrdude.exe: reading input file "0xFF"
avrdude.exe: writing lock (1 bytes):

Writing | ################################################## | 100% 0.01s

avrdude.exe: 1 bytes of lock written
avrdude.exe: verifying lock memory against 0xFF:
avrdude.exe: load data lock data from input file 0xFF:
avrdude.exe: input file 0xFF contains 1 bytes
avrdude.exe: reading on-chip lock data:

Reading | ################################################## | 100% 0.01s

avrdude.exe: verifying ...
avrdude.exe: 1 bytes of lock verified
avrdude.exe: reading input file "0xFD"
avrdude.exe: writing efuse (1 bytes):

Writing |  ***failed;  
################################################## | 100% 0.05s

avrdude.exe: 1 bytes of efuse written
avrdude.exe: verifying efuse memory against 0xFD:
avrdude.exe: load data efuse data from input file 0xFD:
avrdude.exe: input file 0xFD contains 1 bytes
avrdude.exe: reading on-chip efuse data:

Reading | ################################################## | 100% 0.01s

avrdude.exe: verifying ...
avrdude.exe: WARNING: invalid value for unused bits in fuse "efuse", should be set to 1 according to datasheet
This behaviour is deprecated and will result in an error in future version
You probably want to use 0xf5 instead of 0xfd (double check with your datasheet first).
avrdude.exe: 1 bytes of efuse verified
avrdude.exe: reading input file "0xD6"
avrdude.exe: writing hfuse (1 bytes):

Writing | ################################################## | 100% 0.02s

avrdude.exe: 1 bytes of hfuse written
avrdude.exe: verifying hfuse memory against 0xD6:
avrdude.exe: load data hfuse data from input file 0xD6:
avrdude.exe: input file 0xD6 contains 1 bytes
avrdude.exe: reading on-chip hfuse data:

Reading | ################################################## | 100% 0.01s

avrdude.exe: verifying ...
avrdude.exe: 1 bytes of hfuse verified
avrdude.exe: reading input file "0xFF"
avrdude.exe: writing lfuse (1 bytes):

C:\Users\jp\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude.exe -CC:\Users\jp\AppData\Local\Arduino15\packages\m328pb\hardware\avr\1.1.4/tools/avrdude.conf -v -patmega328pb -cstk500v1 -PCOM14 -b19200 -Uflash:w:C:\Users\jp\AppData\Local\Arduino15\packages\m328pb\hardware\avr\1.1.4/bootloaders/optiboot_m328pb.hex:i -Ulock:w:0xCF:m 
Writing | ################################################## | 100% 0.02s

avrdude.exe: 1 bytes of lfuse written
avrdude.exe: verifying lfuse memory against 0xFF:
avrdude.exe: load data lfuse data from input file 0xFF:
avrdude.exe: input file 0xFF contains 1 bytes
avrdude.exe: reading on-chip lfuse data:

Reading | ################################################## | 100% 0.01s

avrdude.exe: verifying ...
avrdude.exe: 1 bytes of lfuse verified

avrdude.exe done.  Thank you.


avrdude.exe: Version 6.3-20190619
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "C:\Users\jp\AppData\Local\Arduino15\packages\m328pb\hardware\avr\1.1.4/tools/avrdude.conf"

             Using Port                    : COM14
             Using Programmer              : stk500v1
             Overriding Baud Rate          : 19200
             AVR Part                      : ATmega328PB
             Chip Erase delay              : 9000 us
             PAGEL                         : PD7
             BS2                           : PC2
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 200
             StabDelay                     : 100
             CmdexeDelay                   : 25
             SyncLoops                     : 32
             ByteDelay                     : 0
             PollIndex                     : 3
             PollValue                     : 0x53
             Memory Detail                 :

                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
               flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
               lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
               signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

             Programmer Type : STK500
             Description     : Atmel STK500 Version 1.x firmware
             Hardware Version: 2
             Firmware Version: 1.18
             Topcard         : Unknown
             Vtarget         : 0.0 V
             Varef           : 0.0 V
             Oscillator      : Off
             SCK period      : 0.1 us

avrdude.exe: AVR device initialized and ready to accept instructions

Ошибка при записи загрузчика.
Reading | ################################################## | 100% 0.02s

avrdude.exe: Device signature = 0x0000ff
avrdude.exe: Expected signature for ATmega328PB is 1E 95 16
             Double check chip, or use -F to override this check.

avrdude.exe done.  Thank you.
 
 
 
 
затем выбрал шится на внутренем кварце в 8 мгц и вроде как залилось, затем попытался еще раз залить то же самое не двигая и не разьединя ничего сразу выпадает ошибка 

Arduino: 1.8.12 (Windows 10), Плата:"ATmega328PB Internal Clock, 8 MHz"

C:\Users\jp\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude.exe -CC:\Users\jp\AppData\Local\Arduino15\packages\m328pb\hardware\avr\1.1.4/tools/avrdude.conf -v -patmega328pb -cstk500v1 -PCOM14 -b19200 -e -Ulock:w:0xFF:m -Uefuse:w:0xFD:m -Uhfuse:w:0xD6:m -Ulfuse:w:0xE2:m 

avrdude.exe: Version 6.3-20190619
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "C:\Users\jp\AppData\Local\Arduino15\packages\m328pb\hardware\avr\1.1.4/tools/avrdude.conf"

             Using Port                    : COM14
             Using Programmer              : stk500v1
             Overriding Baud Rate          : 19200
             AVR Part                      : ATmega328PB
             Chip Erase delay              : 9000 us
             PAGEL                         : PD7
             BS2                           : PC2
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 200
             StabDelay                     : 100
             CmdexeDelay                   : 25
             SyncLoops                     : 32
             ByteDelay                     : 0
             PollIndex                     : 3
             PollValue                     : 0x53
             Memory Detail                 :

                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
               flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
               lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
               signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

             Programmer Type : STK500
             Description     : Atmel STK500 Version 1.x firmware
             Hardware Version: 2
             Firmware Version: 1.18
             Topcard         : Unknown
             Vtarget         : 0.0 V
             Varef           : 0.0 V
             Oscillator      : Off
             SCK period      : 0.1 us

avrdude.exe: AVR device initialized and ready to accept instructions

Ошибка при записи загрузчика.
Reading | ################################################## | 100% 0.02s

avrdude.exe: Device signature = 0x00ff00
avrdude.exe: Expected signature for ATmega328PB is 1E 95 16
             Double check chip, or use -F to override this check.

avrdude.exe done.  Thank you.

Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
"Показать подробный вывод во время компиляции"

 

 
 
b707
Offline
Зарегистрирован: 26.05.2017

Charovnik, по логам похоже на то, что вы прошиваете камень под внешний кварц, а с кварцем он у вас не стартует. как подключали кварц, покажите схему

А если не прошивать загрузчик, не менять фьюзы - программатором скетчи в МК заливаются?

Charovnik
Charovnik аватар
Offline
Зарегистрирован: 05.02.2016

Колодка с первого пина по кругу на фото верх ногами , правда не уверен за кварц посто новый припаял

slider
Offline
Зарегистрирован: 17.06.2014

- обожмите сильнее эти провода ( встречал что китайцы такие плохо обжимают)

- пробуйте другие контроллеры

- попробуйте программатор USBtinyISP  ( был случай что только он помог #comment-536135 )

- еще народ сталкивался c проблемами при программировании atmega328PB https://www.avrfreaks.net/forum/programming-atmega328pb-ispenterprogmode-fail?page=all

- самый крайний случай параллельное программирование  Fuse doctor  ,( на счет как там с -PB незнамо).

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

А зачем вы стираете бит CFD ???

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

Charovnik, Мне кажется, что  проблемы с прошивкой голых МК  в 99% случаев возникают из-за плохих контактов(монтажа).  Я например никогда не шью так, как вы -подвесив МК на соплях. Либо сначала припаиваю МК в ту плату, где он будет работать, а потом через разъём ISP прошиваю. Либо припаиваю МК непосредственно на переходник программатора. И всё всегда шьётся без проблем.

 

Charovnik
Charovnik аватар
Offline
Зарегистрирован: 05.02.2016

я череза arduino ide заливал там все само происходит, посоветуйте может какую программу

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

avrdude прямо из командной строки.

Charovnik
Charovnik аватар
Offline
Зарегистрирован: 05.02.2016

Вобщем взял ардуину нану с простым 328р залил в нее блинк, снял кварц с наны блинк не работал, снял чип поставил чип и кварц на колодку поставил диод на 13 ногу и резистор 1ком на ресет и 5вольт подал напряжение блинк работает. Подключил поровода isp. Тот же самый блинк скетч заливается загрузка же загрущика не идет. Ошибки типа ff0000 00ff00 0000ff. При этом когда отравляю команду по диоду видно что чип в колодке пытался прерватся

Weisnar
Weisnar аватар
Offline
Зарегистрирован: 19.07.2018

b707 пишет:

А если не прошивать загрузчик, не менять фьюзы - программатором скетчи в МК заливаются?

Если не прошивать загрузчик, то скетчи программатором загружаются. Но с завода чип настроен на непонятный внешний кварц, толи 16MHz толи 1Mhz. Не столь важно, всё равно не подходит. По этому надо перепрошить. И вот у меня полностью аналогично, как описывает Charovnik. 

После первой записи загрузчика - дальше ничего не работало. Правда, я это два года назад делал и разными загрузчиками испортил три атмеги и на этом эксперименты отложил до лучших времён. Сейчас активно использую MiniCore библиотеку. Ею еще не пробовал прошить новые Atmega328PB, а в старые не грузится. Хотя тут пишут, что это может программатор Arduino as ISP не подходит. А USBtinyISP загрузить сможет... попробовать, что-ли... 

Для сравнения, Atmega328P прекрасно прошивается. Отличие от в логах от Atmega328PB вот именно в этой строчке: 

avrdude: Device signature = 0x1e950f (probably m328p)
Почему-то для Atmega328PB оно напрочь разучивается правильно считывать эту сигнатуру. Пишет, что не тот контроллер и останавливается. А надо, чтобы пробовало загрузить загрузчик. Люди пишут, что когда делают это в принудительном порядке, то загружается и всё дальше работает. 
Jeka_M
Jeka_M аватар
Онлайн
Зарегистрирован: 06.07.2014

Цитата:

Но с завода чип настроен на непонятный внешний кварц, толи 16MHz толи 1Mhz.

С завода чип ВСЕГДА настроен на внутренний RC-осциллятор 8МГц с делителем на 8 (т.е. тактовая 1МГц). Если у Вас чип настроен на внешний кварц, значит он уже не с завода. Вам продали б/у чип, в котором менялись фьюзы.

Цитата:

avrdude: Device signature = 0x1e950f (probably m328p)
Почему-то для Atmega328PB оно напрочь разучивается правильно считывать эту сигнатуру.

Если бы были проблемы со считыванием сигнатуры, там были нули: Device signature = 0x000000 или другая билиберда. В данном случае он чётко считывает сигнатуру Atmega328P. Сигнатура для Atmega328PB = 0x1e9516.

Вы уверены, что чип не перемаркировка б/у Atmega328P? Все признаки указывают на это.

Weisnar
Weisnar аватар
Offline
Зарегистрирован: 19.07.2018

"С завода чип ВСЕГДА настроен на внутренний RC-осциллятор 8МГц с делителем на 8 (т.е. тактовая 1МГц). "

Да, где-то про это и написал, что там была другая частота, а не 8MHz, которая нужна тогда была мне. 

"Если бы были проблемы со считыванием сигнатуры, там были нули: Device signature = 0x000000". 

Да, вот так и есть на микроконтроллерах, которые когда-то "испортил". В зависимости от выбранной частоты кварца там еще ff куда нибудь вписывается. Типа: avrdude.exe: Device signature = 0x00ff00

Загвоздка была, что первый раз то оно прошивалось. 

 

Ради эксперимента, взял только что новый Atmega328PB. Прошил его MiniCore. Прошилось (но первый раз так и с другими загрузчиками было). Загрузил загрузчик второй раз - снова загрузилось! Залил через программатор сектч - работает. Алилуя. Вот она, нормально работающая библиотека для этого микропроцессора. Дело в том, что нашел её только год назад и теперь активно использую. А портил микроконтроллеры PB года два назад. Тогда по ним инфы было маловато.  

И в завершение, вот как выглядит успешный лог (не знаю, как его свернуть): 

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\Aleks\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.0.5/avrdude.conf"

         Using Port                    : COM3
         Using Programmer              : stk500v1
         Overriding Baud Rate          : 19200
         AVR Part                      : ATmega328PB
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00

         Programmer Type : STK500
         Description     : Atmel STK500 Version 1.x firmware
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e9516 (probably m328pb)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "C:\Users\Aleks\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.0.5/bootloaders/optiboot_flash/bootloaders/atmega328pb/8000000L/optiboot_flash_atmega328pb_UART0_38400_8000000L_B5.hex"
avrdude: writing flash (32768 bytes):

Writing | ################################################## | 100% -0.00s

avrdude: 32768 bytes of flash written
avrdude: verifying flash memory against C:\Users\Aleks\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.0.5/bootloaders/optiboot_flash/bootloaders/atmega328pb/8000000L/optiboot_flash_atmega328pb_UART0_38400_8000000L_B5.hex:
avrdude: load data flash data from input file C:\Users\Aleks\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.0.5/bootloaders/optiboot_flash/bootloaders/atmega328pb/8000000L/optiboot_flash_atmega328pb_UART0_38400_8000000L_B5.hex:
avrdude: input file C:\Users\Aleks\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.0.5/bootloaders/optiboot_flash/bootloaders/atmega328pb/8000000L/optiboot_flash_atmega328pb_UART0_38400_8000000L_B5.hex contains 32768 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% -0.00s

avrdude: verifying ...
avrdude: 32768 bytes of flash verified
avrdude: reading input file "0x0f"
avrdude: writing lock (1 bytes):

Writing | ################################################## | 100% 0.02s

avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x0f:
avrdude: load data lock data from input file 0x0f:
avrdude: input file 0x0f contains 1 bytes
avrdude: reading on-chip lock data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of lock verified

avrdude done.  Thank you.

Как восстановить неправильно прошитые Atmega328PB - это уже совсем другая история. Люди пишут, что как минимум через Arduino as ISP это не получится.

sadman41
Offline
Зарегистрирован: 19.10.2016

Я на первой странице тоже менял левый бутлоадер, но только полулой.

b707
Offline
Зарегистрирован: 26.05.2017

Weisnar - это все интересно, но совершенно не отменяет того, что тот чип где у вас читается

avrdude: Device signature = 0x1e950f

- скорее всего перемаркировка.

 

Вообще , мне кажется что вы как-то очень смутно представляете весь процесс, постоянно путаетесь в рассуждениях, что и как прошивали, что у вас в итоге работает, а что блочится...

По мне так тут все предельно ясно. Когда вы выставляете правильные фьюзы к правильно определенному чипу, верно соединяете провода, правильно выбираете параметры в настройках программатора - все прошивается. А если где-то ошибка - то нет. И не надо никакой магии...

а если у вас был чип с сигнатурой 0x1e950f от обычной 328р , а вы его насильно с параметром -f зашили как 328pb - то понятно, что такое можно сделать только один раз, а потом он блочится

Jeka_M
Jeka_M аватар
Онлайн
Зарегистрирован: 06.07.2014

Weisnar пишет:

"С завода чип ВСЕГДА настроен на внутренний RC-осциллятор 8МГц с делителем на 8 (т.е. тактовая 1МГц). "

Да, где-то про это и написал, что там была другая частота, а не 8MHz, которая нужна тогда была мне. 

Так она и должна быть другая. 8 МГц с делителем на 8 дают тактовую 1МГц. Так и должно быть с завода.

Jeka_M
Jeka_M аватар
Онлайн
Зарегистрирован: 06.07.2014

b707 пишет:

скорее всего перемаркировка.

Согласен с b707.
Сигнатура 0x1e950f НЕ может возникнуть случайным образом в результате ошибки считывания, это исключено.
Это однозначно говорит о том, что прошиваемый чип является Atmega328P, а не Atmega328PB.

Weisnar
Weisnar аватар
Offline
Зарегистрирован: 19.07.2018

b707 пишет:

а если у вас был чип с сигнатурой 0x1e950f от обычной 328р , а вы его насильно с параметром -f зашили как 328pb - то понятно, что такое можно сделать только один раз, а потом он блочится

Всё практически так, только на оборот. Были 328PB и прошивались разными загрузчиками от 328P (предварительно изменёнными по инфе с разных форумов). Блочится навсегда? 

 

Про avrdude: Device signature = 0x1e950f (probably m328p) я там сначала указал, что это "Для сравнения, Atmega328P прекрасно прошивается". У меня разные атмеги: 328P, 328P-AU, 328PB.

Atmega328PB - более двух лет назад на алиекспресс куплен десяток за 12$ (доставка бесплатная).  Классические Atmega328P на то время стоили дороже.

Тогда, летом 18-го года, я не нашел, как прошить загрузчик для этих PB. Их и не было, надо было модифицировать загрузчик от обычного 328P. Попробовал несколько вариантов. Убил пару микроконтроллеров и эксперименты отложил.

Ситуация там была в точности, как описал Чаровник. Первый раз что-то закачивалось, но потом всё. На все попытки что-то в него залить сигнатура больше не считывалась:  avrdude.exe: Device signature = 0x00ff00 .

Год назад набрёл на MiniCore, которую активно использую, так как она добавляет два дополнительных пина  (This core gives you two extra IO pins if you're using the internal oscillator!). И там по умолчанию была поддержка 328PB. Случайно увидел, что в этой ветке поднимали уже вопрос о том, как записать загрузчик. Этим летом вот снова. Поделился личными наблюдениями:

1. Программатором скетчи заливаются. Если не пытаться записать  свой загрузчик.

2. Если пытаться записать  загрузчик криво, например, модифицированный от 328P, то чё-то сбивается и больше сигнатура не считывается.

3. Загрузчик от MiniCore записывается  (в новые 328PB) и всё работает.

4. В предварительно "испорченные" 328PB корявым загрузчиком записать тот же MiniCore уже не выходит. Программатор ругается на отсутствие сигнатуры.

b707
Offline
Зарегистрирован: 26.05.2017

Weisnar - вопрос о том, нафига вообще нужен загрузчик, если вы работаете с голым чипом, да еще и на внутреннем осцилляторе? Заливайте скетчи программатором и не мучайтесь

Weisnar
Weisnar аватар
Offline
Зарегистрирован: 19.07.2018

Нужен ли загрузчик в атмегах вопрос, наверно, больше философский.
Лично мне он подходит по двум причинам:
- добавляет два цифровых пина, которые в заводской прошивке не активны;
- добавляет возможность обновлять скетчи по UART, а на пины 10,11,12,13 обычно припаиваю какой-то радиомодуль.
Тоесть, мне всегда думалось, что загрузчик - штука полезная.
Тем боле, насколько понял, MiniCore использует загрузчик Optiboot, а он в свою очередь совсем не большой размером.
Хотя очень давно экспериментировал, там толи MISO, толи MOSI радиомодуля достаточно через резистор подключить и всё. Он не будет мешать перепрошивке.

Так что... Загрузчики лучше не использовать? Я же написал. Проверил уже на нескольких 328PB. MiniCore нормально заливается и всё работает лучше прежнего.
Кто не знает, Optiboot еще и функцию watchdog восстанавливает. Но она конфликтует с библиотекой LowPower, по этому тут уж кому что нужнее.

nik182
Offline
Зарегистрирован: 04.05.2015

Ну какой же бред...