Всё про ATmega328PB

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

Решил сделать отдельную темку по МК ATmega328PB, дабы всё было в одном месте.

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

Этот чип почти тоже самое что обычные atmega328, но есть несколько интересных отличий.
Atmega328PB     Atmega328
2 Serial              1 Serial
2 SPI                 1 SPI
2 I²C/TWI          1 I²C/TWI
27 Digital IO      23 Digital IO
3 16Bit Timer     1 16Bit Timer
9 PWM Channel  6 PWM Channel
 

Новые фичи:
-Механизм обнаружения сбоев синхронизации (если отвалится кварц, то МК не остановится)  / Clock Failure Detection
-контроллер сенсорного интерфейса / QTouch Peripheral Touch Controller, PTC
-модулятор выходов таймеров (умеет складывать сигналы от двух таймеров)   / Output Compare Modulator
-Уникальный серийный номер
-аппаратный выход аналогового компаратора
 

Отличия в распиновке: -главное отличие в том, что на 3 и 6 ноге мк где в обычной меге земля и питание теперь два новых пина порта E.  Ещё два пина этого же порта подсажено к аналоговым входам ADC6 ADC7.

Плохие новости:
-МК не производят в дип-корпусе.
-Убрали поддержку Full Swing Oscillator, по факту это выливается в то, что
кварцы с частотой выше 16Мгц с этим МК не работают (вернее завестись может быть сможет, но вместо тактовой частоты будет  стоять свистопляска)
Хорошая новость: мега328PB разгоняется, у меня стабильно работала на 32Мгц при тактировании от внешнего кварцевого генератора.
Совместимость с ArduinoIDE: если шить как обычный мега328 avrdude будет ругаться на сигнатуру. Что-б корректно работать есть варианты аддонов. Я использую этот. Другие пока не пробывал.

Boards: пока на Али не продают дешевых плат, но наш коллега sadman41 нашёл магазин, где на обычных нанах припаян чип 328PB.

Ещё можно самостоятельно сделать вот такой переходник, в который можно класть МК и закреплять без пайки, мой вариант на картинке:

Описание как сделать такой переходник  в теме на изиэлектроникс.

Я себе сделал самопальную Уно-подобную платку для 328PB со всеми разведёнными выводами.

За исходный вариант взял плату буратино с сайта simple-devices.ru  Мой вариант существенно изменён.  Скачать мой вариант в спринте.

Из того, что представляет интерес на данный момент -как заюзать QTouch из ArduinoIDE. Я заглядывал в библиотеку атмеля, там понакручено -чёрт ногу сломит. В даташите ни слова про то, как работать и программировать эту штуку напрямую. Пока могу осторожно предположить , что  весь процесс  там  сводится к digitalWrite и analogRead :)

Если у вас есть что-то интересное по этому МК, то добавляйте информацию.

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

Любителям усыплять микроконтроллеры должно понравиться это: ATmega328PB has one additional USART with start-of-frame detection, which can wake up the MCU from all sleep modes - when a start bit is detected.

AT15007: Differences between ATmega328/P and ATmega328PB

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

подпишусь

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

не подпишусь, хватает пока LGT8F328P.

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

DIMAX! Когда ожидать скетч частотомера без delay(), исключительно на таймерах?
Я тут OCXO присмотрел с 0,1ppm )))

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

ua6em, что то типа такого? У меня лежит в закладочках. Хочется иметь, но не знаю зачем)

Что бы в частотометре реализовать такую точность нужны алгоритмы обратного счёта с интерполяцией, типа как в частотометре Леонид Иваныча , иначе точность разбазариться впустую из-за потерь на примитивных принципах счёта.

PS: Частотометр с чисто аппаратным "delay" реализован в версии генератора для stm32. После того, как я узнал способности таймеров в stm32 , таймеры на AVR выглядят очень уж примитивно, ничего на них не хочется делать :)

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

dimax пишет:

ua6em, что то типа такого? У меня лежит в закладочках. Хочется иметь, но не знаю зачем)

Что бы в частотометре реализовать такую точность нужны алгоритмы обратного счёта с интерполяцией, типа как в частотометре Леонид Иваныча , иначе точность разбазариться впустую из-за потерь на примитивных принципах счёта.

PS: Частотометр с чисто аппаратным "delay" реализован в версии генератора для stm32. После того, как я узнал способности таймеров в stm32 , таймеры на AVR выглядят очень уж примитивно, ничего на них не хочется делать :)

из недорогих - да, но я присмотрел себе немного подороже, за 8 с небольшим тыр )))
 

Green
Offline
Зарегистрирован: 01.10.2015

dimax пишет:

что то типа такого?

До 50 мгц делается на древнейшем PICе, типа 628. Вообще без ничего.)

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

Green, ну да. PIC рулит. Только "без ничего" -это будет прямой счёт с  потерями точности в начале и конце измеряемого участка. Для обратного уже нужен обвес. На коте кстати был хороший проект с обратным счётом.  Повторил бы сам, но мне частотометр не нужен :)

Green
Offline
Зарегистрирован: 01.10.2015

Да, конечно. Но даже в таком виде, КМК, увеличив ворота можно добиться желаемого результата малой кровью, не?

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

Green, ну да.

Интересно бы было что нибудь по теме топика пообсуждать :)

 

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

dimax пишет:

Интересно бы было что нибудь по теме топика пообсуждать :)

я платки только заказал )))

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

Green пишет:

dimax пишет:

что то типа такого?

До 50 мгц делается на древнейшем PICе, типа 628. Вообще без ничего.)

PicProg+ у меня есть, осталось найти компьютер под WIN98 )))

spa-sam
Offline
Зарегистрирован: 14.12.2012

Вот хороший аддон https://github.com/MCUdude/MiniCore

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

spa-sam пишет:

Вот хороший аддон https://github.com/MCUdude/MiniCore

Проверочный скетч под аддон компилируется
 

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

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

void setup() {
  constexpr uint8_t prescalerBits = prescalerBitsByFrequency(TIMER, FREQUENCY);
  constexpr uint16_t timerTicks = timerTicksByFrequency(TIMER, FREQUENCY, delta);
  static_assert(timerTicks, "The required frequency is unattainable");
  
  pinMode(13, OUTPUT);
  t=TIMER;

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

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

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

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

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

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

  
  /*
   * Enter desired frequency in Hz 
   * (use decimal point for fractions. I.e. 0.12 means 0,12Hz):
   * Results for frequency: 1600.00Hz
   * (1,3) Prescaler: 1; MaxValue: 4999; Frequency: 1600.00Hz; Diff: 0.00Hz
   * (1,3) Prescaler: 8; MaxValue: 624; Frequency: 1600.00Hz; Diff: 0.00Hz
   * (2) Prescaler: 128; MaxValue: 38; Frequency: 1602.56Hz; Diff: 2.56Hz
   * (0,1,2,3) Prescaler: 64; MaxValue: 77; Frequency: 1602.56Hz; Diff: 2.56Hz
   * (2) Prescaler: 32; MaxValue: 155; Frequency: 1602.56Hz; Diff: 2.56Hz
   * (0,1,2,3) Prescaler: 256; MaxValue: 19; Frequency: 1562.50Hz; Diff: 37.50Hz
   * (0,1,2,3) Prescaler: 1024; MaxValue: 4; Frequency: 1562.50Hz; Diff: 37.50Hz
   * Enter desired frequency in Hz
   * (use decimal point for fractions. I.e. 0.12 means 0,12Hz):
*/
 

Библиотека
 

#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

 

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

sadman41 пишет:

Любителям усыплять микроконтроллеры должно понравиться это: ATmega328PB has one additional USART with start-of-frame detection, which can wake up the MCU from all sleep modes - when a start bit is detected.

AT15007: Differences between ATmega328/P and ATmega328PB

интересно девки пляшут, на 3-ем и 4-ом таймере можно использовать модулятор -
OCM1C2 - Output Compare Modulator

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

А никому не пришло в голову поискать эту переферию в старом добром 328P? Может она там давно, а сейчас токо декларировали. Чем черт не шутит. Такое уже бывало.

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

Я из 328P достаю ID. На моих экземплярах не повторяются номера и от внешних воздействий не зависят. 

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

sadman41, я пока не изучал тему серийного номера. А как читаешь?  Там же что-бы прочесть эту область нужно сделать адресный ремап специальными командами на ассемблере. И потом с адреса 0x00 вместо флеша начнёт читаться закрытая область МК,в которой сигнатура и серийник. Иначе прочтётся флеш. И проверить то сложно. Как вариант можно выгрузив выводящий серийник "HEX"  из одного МК в другой. Что б гарантированно точная копия. Если покажут разные цифры -скорее всего сработало)

PS вспомнил, что в GCC есть макрос специальный, может им можно: boot_signature_byte_get(addr)

PS2: по поводу поискать периферию -можно скомпилить тот проверочный скетч для PB и влить его в обычную мегу. Если на 0,1,2 ногах будет сигнал -случилось чудо. Но его не случиться, думаю давно бы народ раскусил, если б в меге328 было что-то неизвестное.

 

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

dimax пишет:

PS вспомнил, что в GCC есть макрос специальный, может им можно: boot_signature_byte_get(addr)

Так и делаю: http://arduino.ru/forum/programmirovanie/sysinfo-arduino?page=1#comment-330125

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

Прочёл две обычные 328 и две 328PB

ATMEGA328(1) MCU ID = 55 35 38 30 39 31 FF 01 09 0E
ATMEGA328(2) MCU ID = 59 32 33 35 37 32 FF 0B 03 14
ATMEGA328PB(1) MCU ID = 50 51 34 39 42 38 69 0E 13 1C
ATMEGA328PB(2) MCU ID = 50 51 34 39 42 38 69 0E 13 12

Понятно, *PB из одной партии, а те из разных. Выводы делать рано. Для чистоты эксперемента нужно хотя бы пару обычных мег328 из одной партии :)

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

У меня целый десяток есть из одной партии

MCU ID = 59 36 30 32 31 37 FF 12 07 08
 

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

Итак, есть две новости: одна хорошая, другая загадочная.

Хорошая - плата от Thinary Electronic (зелёная, в формате Nano, упомянута в посте #2) сделана неплохо, по качеству близка к роботдину. Только вот на AMS1117-5.0 сэкономили - совсем он мелкий. Вопреки опасениям dimax'а PE0 не сидит на GND, а PE1 на VCC. Прозвонка показала, что "GND" соединён с выводом МК #5, с #3 - нет. Соответсвенно "+5V" соединён с #4, с #6 - нет. 

Загадочная - avrdude говорит, что МК имеет сигнатуру 0x1e950f. И шьёт плату как обычный 328P со старым бутлодером.

Плагин от Pololu плату не увидел, пока я ему не подправил скорость со 115200 на 57600. После этого avrdude увидел плату, но шить отказался - сигнатура, мол, не подходит, растудыть её в качель. Но, сначала, я даже подумал, когда словил STK500 Error, что загрузчика в МК нет, 

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: Expected signature for ATmega328PB is 1E 95 16
         Double check chip, or use -F to override this check.

Однако, операция взятия Signature и MCU ID (из этого поста) показывает, что:

SysInfo for Arduino version 1.07

F_CPU = 16000000
Frequency = 16 MHz

MCU ID = 50 51 31 37 42 51 69 10 3C 22 
CPU_IDE = ATmega328P

Flash Memory = 32767 bytes
Free RAM memory = 1091 bytes

Signature = 1E 95 16
Fuses (Low/High/Ext/Lock) = FF DA FD CF
Processor = ATmega328PB
Flash memory size = 32 kB

Номер же схож с теми, что публиковал dimax.

nikolaki
nikolaki аватар
Offline
Зарегистрирован: 14.02.2013

А никто не пробывал загрузчик из MiniCore. Вроде пишут * All variants (A, P, PA and PB).Сам не пробовал из-за отсутствия 328PB.

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

Так, и что делать и кто виноват?

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

sadman41 пишет:

avrdude говорит, что МК имеет сигнатуру 0x1e950f. И шьёт плату как обычный 328P со старым

Любопытно, да.  Могу предположить, что бутлоадер этой платы специально модифицированный, и не передаёт дудке реальную сигнатуру.  Бутлоадер в MK LGT8F328 проделывает такой же фокус. 

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

dimax пишет:

Любопытно, да.  Могу предположить, что бутлоадер этой платы специально модифицированный, и не передаёт дудке реальную сигнатуру.  Бутлоадер в MK LGT8F328 проделывает такой же фокус. 

Стоит пытаться заменить бутлоадер USBASP-ом (под рукой нет его) на Minicore / Pololu / etc? 

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

вчера вечером сел помучать эту платку, ситуация один в один, сигнатуру вечером могу скинуть.

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

Эксперимент проведён. USBASP-ом насильно вкрыжен бутлоадер из комплекта Pololu (Optiboot, см. инструкцию). В процессе обновления avrdude обругался:

avrdude: set SCK frequency to 1500000 Hz
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: AVR device initialized and ready to accept instructions

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

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: set SCK frequency to 1500000 Hz
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: reading input file "C:\Users\sadman\AppData\Local\Arduino15\packages\pololu-a-star\hardware\avr\4.0.2/bootloaders/optiboot/optiboot_atmega328pb_16mhz.hex"
avrdude: writing flash (32768 bytes):

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

avrdude: 32768 bytes of flash written
avrdude: verifying flash memory against C:\Users\sadman\AppData\Local\Arduino15\packages\pololu-a-star\hardware\avr\4.0.2/bootloaders/optiboot/optiboot_atmega328pb_16mhz.hex:
avrdude: load data flash data from input file C:\Users\sadman\AppData\Local\Arduino15\packages\pololu-a-star\hardware\avr\4.0.2/bootloaders/optiboot/optiboot_atmega328pb_16mhz.hex:
avrdude: input file C:\Users\sadman\AppData\Local\Arduino15\packages\pololu-a-star\hardware\avr\4.0.2/bootloaders/optiboot/optiboot_atmega328pb_16mhz.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 "0xCF"
avrdude: writing lock (1 bytes):

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

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

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

avrdude: verifying ...
avrdude: WARNING: invalid value for unused bits in fuse "lock", 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 0x0f instead of 0xcf (double check with your datasheet first).
avrdude: 1 bytes of lock verified

avrdude done.  Thank you.

Но, в итоге, пока всё неплохо, блинк залился:

avrdude: AVR device initialized and ready to accept instructions

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

avrdude: Device signature = 0x1e9516 (probably m328pb)
avrdude: reading input file "C:\Users\sadman\AppData\Local\Temp\arduino_build_293077/Blink.ino.hex"
avrdude: writing flash (1158 bytes):

Writing | ################################################## | 100% 0.19s

avrdude: 1158 bytes of flash written

avrdude done.  Thank you.

Затем сделал самое простое, что пришло в голову:


void setup() {
  // D11 is PB3 => TXD1
  Serial1.begin(9600);
}

void loop() {
  Serial1.println("12345\n");
  delay(100);
}

Присел осциллографом на D11 и увидел повторяющийся пакет. Так что можно сказать - плата работает и там действительно ATMega328PB.

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

sadman41 пишет:

Стоит пытаться заменить бутлоадер USBASP-ом (под рукой нет его) на Minicore / Pololu / etc? 

Думаю да. Вдвое большая скорость заливки,  и вчетверо меньший объём отъедаемой флэшпамяти определённо стоят этого :) PS: правда с конкретно моим аддоном в boards.txt тоже скорость 57600. Но я вписал 115200, и работает на этой скорости. Возможно там вариант бутлоадера  с Auto-Baudrate.

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

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

Скетч содержит две части: 
1) Независимую хардварную генерацию меандра тремя таймерами (T1, T3, T4) - на D9, D0, D1;
2) Независимую хардварную генерацию меандра двумя таймерами (T3, T4) и модулированную (OCM1C2 feature) - на D0, D1 и D2;

Частоты рассчитаны на визуальное восприятие, так что можно подвесить три светодиода.

#define TIMER_ONE              (0x01)
#define TIMER_THREE            (0x03)
#define TIMER_FOUR             (0x04)
#define OCM1C2_ENABLED         true

const uint8_t timerOneOutPin   = 9;
const uint8_t timerThreeOutPin = 0;
const uint8_t timerFourOutPin  = 1;
const uint8_t ocmOutPin        = 2;

void calcValues(const uint32_t _frequency, uint16_t& _OCRxA, uint8_t& _TCCRxB) {
  uint16_t divider  = 0x01;
  uint32_t newOCRxA = (F_CPU / 0x02 / _frequency / divider);

  uint8_t shifts[] = {0x03, 0x03, 0x02, 0x02};
  for (uint8_t i = 0x00; 0x04 > i; i++) {
    if (newOCRxA > 65536) {
      divider <<= shifts[i];
      newOCRxA = F_CPU / 0x02 / _frequency / divider;
    } else {
      _TCCRxB = (i + 0x01); _OCRxA = newOCRxA - 0x01;
      return;
    }
  }
}

uint8_t setFrequency(const uint8_t _timerNo, const uint32_t _frequency, const uint8_t _ocmEnable = false) {
  if (_frequency > (F_CPU / 0x02)) {
    return false;
  }

  if (_frequency == 0x00) {
    // (1 << COM1A1) => set COM1A1, COM3A1, or COM4A1, because all of that macros points to the same bit of the TCCRxA registers
    uint8_t TCCRxA = (1 << COM1A1);
    // (1 << FOC1A) => set FOC1A, FOC3A, or FOC4A, because all of that macros points to the same bit of the TCCRxC registers
    uint8_t TCCRxC = (1 << FOC1A);
    switch (_timerNo) {
      case TIMER_ONE:   TCCR1A = TCCRxA; TCCR1C = TCCRxC; break;
      case TIMER_THREE: TCCR3A = TCCRxA; TCCR3C = TCCRxC; break;
      case TIMER_FOUR:  TCCR4A = TCCRxA; TCCR4C = TCCRxC; break;
    }
  } else {
    uint16_t OCRxA = 0x00;
    uint8_t TCCRxA, TCCRxB = 0x00;
    calcValues(_frequency, OCRxA, TCCRxB);
    // (1 << COM1A0) => set COM1A0, COM3A0, or COM4A0, because all of that macros points to the same bit of the TCCRxA registers
    TCCRxA = (1 << COM1A0);
    // (1 << WGM12) => set WGM12, WGM32, or WGM42, because all of that macros points to the same bit of the TCCRxB registers
    TCCRxB |= (1 << WGM12);
    switch (_timerNo) {
      case TIMER_ONE:   TCCR1A = TCCRxA; TCCR1B = TCCRxB; OCR1A = OCRxA; break;
      case TIMER_THREE: TCCR3A = TCCRxA | (!!_ocmEnable << COM3B0); TCCR3B = TCCRxB; OCR3A = OCRxA; break;
      case TIMER_FOUR:  TCCR4A = TCCRxA | (!!_ocmEnable << COM4B0); TCCR4B = TCCRxB; OCR4A = OCRxA; break;
    }
  }
  return true;
}

void setup() {
  TCCR1A = 0x00; TCCR1B = 0x00;
  TCCR3A = 0x00; TCCR3B = 0x00;
  TCCR4A = 0x00; TCCR4B = 0x00;

  pinMode(timerOneOutPin, OUTPUT);
  pinMode(timerThreeOutPin, OUTPUT);
  pinMode(timerFourOutPin, OUTPUT);
  pinMode(ocmOutPin, OUTPUT);

  // Independent frequency generation on D9, D0, D1
  setFrequency(TIMER_ONE,   5);     // Timer #1 - 5 Hz
  setFrequency(TIMER_THREE, 1);     // Timer #3 - 1 Hz
  setFrequency(TIMER_FOUR,  10);    // Timer #4 - 10 Hz
  delay(10000);
  // Stop crazy blinking
  setFrequency(TIMER_ONE,   0);     // Timer #1 - 0 Hz
  setFrequency(TIMER_THREE, 0);     // Timer #3 - 0 Hz
  setFrequency(TIMER_FOUR,  0);     // Timer #4 - 0 Hz

  delay(2000);

  // Independent frequency generation on D0, D1 and modulated frequency generation on D2
  setFrequency(TIMER_THREE, 1,  OCM1C2_ENABLED);  // Timer #3 - 1 Hz
  setFrequency(TIMER_FOUR,  10, OCM1C2_ENABLED);  // Timer #4 - 10 Hz
  delay(10000);
  // Take rest
  setFrequency(TIMER_THREE, 0);     // Timer #3 - 0 Hz
  setFrequency(TIMER_FOUR,  0);     // Timer #4 - 0 Hz
}

void loop() {}

OCM что-то не заводится, пишут что с ним есть какая-то проблема.

UPD: Проблема оказалась в недопонимании datasheet.

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

sadman41, почему OCM не заводится? В #19 есть ссылка на мой проверочный скетч, там в том числе и OCM, там же скриншот работы OCM

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

dimax пишет:

sadman41, почему OCM не заводится? В #19 есть ссылка на мой проверочный скетч, там в том числе и OCM, там же скриншот работы OCM

Да, действительно - так работает. Что-то я недокрутил...

UPD: немного разобрался, добавил функционал в примерчик. 

dimax интересовался - зачем OCM. Так модулированным генератором удобно мигалки типа полицейских делать ;)

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

Получил две платы, одна не шьётся, увы (((
VID 1A86 PID 7523, как на нано от рободина

 

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

#29

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

Ок!
Платки конечно какие-то недоплаты )))
Попробую ту, что совсем не видится перешить через ISP

Зы но пока не до этого, увлёкся openssl, под 1.1.1d firefox работает тока 68 кстати

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

Похоже одна платка пришла битая!
Собрал Sinaprog + avrdude, фьюзы читаю, фьюзы нормальные.
Кому нужен такой пакет, скину... Ардуино выходит дохлая, надо пробовать зацепить через сторониий USB-TTL переходник...

Пакет SinaProg понимающий этот чип.

Зачем это надо? Дело в том, что с использованием функции IDE загрузить через программатор, используя в качестве программатора arduino as isp загрузить скетч не получится. В SinaProg загрузка через этот же программатор проходит на ура. Убеждаемся, что камень исправный )))

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

ua6em пишет:

Дело в том, что с использованием функции IDE загрузить через программатор, используя в качестве программатора arduino as isp загрузить скетч не получится. 

А бутлоадер-то через IDE+ICSP шьётся?

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

sadman41 пишет:

ua6em пишет:

Дело в том, что с использованием функции IDE загрузить через программатор, используя в качестве программатора arduino as isp загрузить скетч не получится. 

А бутлоадер-то через IDE+ICSP шьётся?

шьёт как-то так, см. строка 63 и строка 75, с чего это там FF если считываю фьюзы и там 3F )))


 

C:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14/bin/avrdude -CC:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14/etc/avrdude.conf -C+C:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\pololu-a-star\hardware\avr\4.0.2/extra_avrdude.conf -v -patmega328pb -carduino -PCOM6 -b19200 -B 5 -e -Ulock:w:0xFF:m -Uefuse:w:0xF4:m -Uhfuse:w:0xDE:m -Ulfuse:w:0xFF:m 

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

         System wide configuration file is "C:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14/etc/avrdude.conf"
         Additional configuration file is "C:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\pololu-a-star\hardware\avr\4.0.2/extra_avrdude.conf"
avrdude: warning at C:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\pololu-a-star\hardware\avr\4.0.2/extra_avrdude.conf:1: part m328pb overwrites previous definition C:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14/etc/avrdude.conf:8802.

         Using Port                    : COM6
         Using Programmer              : arduino
         Overriding Baud Rate          : 19200
         Setting bit clk period        : 5.0
         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 : Arduino
         Description     : Arduino
         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.00s

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

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

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

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

avrdude: verifying ...
avrdude: WARNING: invalid value for unused bits in fuse "lock", 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 0x3f instead of 0xff (double check with your datasheet first).
avrdude: 1 bytes of lock verified
avrdude: reading input file "0xF4"
avrdude: writing efuse (1 bytes):

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

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

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

avrdude: verifying ...
avrdude: 1 bytes of efuse verified
avrdude: reading input file "0xDE"
avrdude: writing hfuse (1 bytes):

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

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

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

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

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

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

C:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14/bin/avrdude -CC:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14/etc/avrdude.conf -C+C:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\pololu-a-star\hardware\avr\4.0.2/extra_avrdude.conf -v -patmega328pb -carduino -PCOM6 -b19200 -B 0.5 -Uflash:w:C:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\pololu-a-star\hardware\avr\4.0.2/bootloaders/optiboot/optiboot_atmega328pb_16mhz.hex:i -Ulock:w:0xCF:m 
Reading | ################################################## | 100% 0.00s

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

avrdude done.  Thank you.


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

         System wide configuration file is "C:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14/etc/avrdude.conf"
         Additional configuration file is "C:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\pololu-a-star\hardware\avr\4.0.2/extra_avrdude.conf"
avrdude: warning at C:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\pololu-a-star\hardware\avr\4.0.2/extra_avrdude.conf:1: part m328pb overwrites previous definition C:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14/etc/avrdude.conf:8802.

         Using Port                    : COM6
         Using Programmer              : arduino
         Overriding Baud Rate          : 19200
         Setting bit clk period        : 0.5
         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 : Arduino
         Description     : Arduino
         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.00s

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:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\pololu-a-star\hardware\avr\4.0.2/bootloaders/optiboot/optiboot_atmega328pb_16mhz.hex"
avrdude: writing flash (32768 bytes):

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

avrdude: 32768 bytes of flash written
avrdude: verifying flash memory against C:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\pololu-a-star\hardware\avr\4.0.2/bootloaders/optiboot/optiboot_atmega328pb_16mhz.hex:
avrdude: load data flash data from input file C:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\pololu-a-star\hardware\avr\4.0.2/bootloaders/optiboot/optiboot_atmega328pb_16mhz.hex:
avrdude: input file C:\Documents and Settings\user\Local Settings\Application Data\Arduino15\packages\pololu-a-star\hardware\avr\4.0.2/bootloaders/optiboot/optiboot_atmega328pb_16mhz.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 "0xCF"
avrdude: writing lock (1 bytes):

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

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

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

avrdude: verifying ...
avrdude: WARNING: invalid value for unused bits in fuse "lock", 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 0x0f instead of 0xcf (double check with your datasheet first).
avrdude: 1 bytes of lock verified

avrdude done.  Thank you.

 

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

На странице 384 даташита  лок биты тоже 3F как бы

Докладываю! Битва за спасение девайса закончилась 1-0 в мою пользу.

Неисправность - обрыв резистора в 1 ком с CH340 на Чип (нижний), там их два (RX-TX)

И вдогонку! Попробовал другой аддон, можно использовать кварц до 20 мегагерц, по сути загрузчик видимо
тоже на основе оптибута, занимает столько же места как и на пололулу, только скорость при программировании на шине 57600.

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

ua6em, кварц выше 16МГц использовать невозможно, я писал про это.

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

ua6em пишет:

шьёт как-то так, см. строка 63 и строка 75, с чего это там FF если считываю фьюзы и там 3F )))

Ну, у меня тоже ругалось так же, но бутлоадер заменился и дальше всё, как по маслу.

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

sadman41 пишет:

ua6em пишет:

шьёт как-то так, см. строка 63 и строка 75, с чего это там FF если считываю фьюзы и там 3F )))

Ну, у меня тоже ругалось так же, но бутлоадер заменился и дальше всё, как по маслу.

а вот прошивку залить через ISP?

У меня через iSP с аддоном от pololu прошивка категорически не шьётся, с двумя другими аддонами - на ура
 

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

Не знаю, я такими извращениями не занимаюсь - мне хватает заливки и через UART.

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

sadman41 пишет:

Не знаю, я такими извращениями не занимаюсь - мне хватает заливки и через UART.

это разговор не об извращениях а о кривоватости аддона pololu, не находишь?

Кстати попытался в твой проверочный скетч добавить синхронное отображение на индикацию сетодиодом на 13 пину, чё то не взлетело, добавишь, чтобы диоды не лепить, к примеру 10 секунд с одного таймера и так по кругу

Нашёл еще один косяк, не компилируется проверочный скетч для 4-го таймера для аддона от pololu, для другого аддона всё компилирется, проверил 4-й таймер - всё работает, по остальным сейчас пройдусь, отпишусь

Проверил все таймера, всё работает. Почему не компилировался для 4-го таймера подсказать сможет только ЕвгенийП или Ворота, их детище, я только поддержку вавгада и этого чипа добавил )))

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

nikolaki пишет:

А никто не пробывал загрузчик из MiniCore. Вроде пишут * All variants (A, P, PA and PB).Сам не пробовал из-за отсутствия 328PB.

я попробовал, загрузчик кстати для этого чипа можно привязать на второй уарт, проверочный скетч для таймеров (пробовал 4-й на котором споткнулся pololu) работает!!!
Там много настроек становится доступно, надо разбираться, что это такое и зачем

Похоже это самый удачный аддон

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

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

 

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

oleg_kazakof пишет:

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

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

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

ua6em пишет:

sadman41 пишет:

Не знаю, я такими извращениями не занимаюсь - мне хватает заливки и через UART.

это разговор не об извращениях а о кривоватости аддона pololu, не находишь?

Кстати попытался в твой проверочный скетч добавить синхронное отображение на индикацию сетодиодом на 13 пину, чё то не взлетело, добавишь, чтобы диоды не лепить, к примеру 10 секунд с одного таймера и так по кругу

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

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

sadman41 пишет:

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

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