Третий раз делаю подписку на эту тему, но кто-то удаляет пост, зачем ?. Соответственно уведомления не приходят.
Если пост пустой - я удаляю, не разбираясь, для подписки он или руки не туда дрогнули. На этом форуме это стандартная практика.
Дед, до этого момента, если тема меня заинтересовала я ставил - точку(.) и всё уведомления на почту, это по моему и была стандартная практика на этом форуме.
визуальную индикацию работы таймеров, светодиод для этого на плате уже есть - LED на пине 13, в идеале 1 короткая вспышка - 0 таймер, две - 1-й и так далее, по кругу на всех доступных таймерах
До сих пор ничерта не понимаю. Перед каждым вызовом добавить for(uint8_t i=0; 3 > i; i++) { digitalWrite(13, HIGH); delay(200); digitalWrite(13, LOW);} что ли?
Да как угодно. чтобы работу всех таймеров можно было визуально проверить только одним светодиодом )))
Вот тут я сделал по рабоче-крестьянски, но для того, чтобы проверить все таймера надо изменять номер таймера и заливать прошивку, а это - пять раз, сможешь сделать ХЭД ЭНД ШОЛДЕРС будет великолепно
Дед, до этого момента, если тема меня заинтересовала я ставил - точку(.) и всё уведомления на почту, это по моему и была стандартная практика на этом форуме.
Олег, просто точки, я тоже удаляю, т.к. неясно, человек запостил и потом стер или подписался.
А ещё лучше написать что-то полезное по теме :)
Есть много чего, что можно исследовать обладателям этого МК, например:
-как "заардуинить" сенсорные кнопки на этом мк.
-тестирование стабильности при разгоне.
-сравнить разные аддоны
А ещё лучше написать что-то полезное по теме :)
Есть много чего, что можно исследовать обладателям этого МК, например:
-как "заардуинить" сенсорные кнопки на этом мк.
-тестирование стабильности при разгоне.
-сравнить разные аддоны
как раз последним и занимаюсь, сравниваю, аддон от pololu выпадает, много косяков
продолжаю исследовать аддоны, в аддоне от MiniCore (в нём доступны и другие процессоры) есть возможность установки BOD и опции компилятора LTO, при разрешении последнего к примеру на скетче квона для LCD2004 позволяет экономить память программ до полкилобайта!
задам тупой вопрос. А раз уж распиновка не очень с простым 328 совпадает, может просто другой камень повыше в линейке применять? Например 1284p. У него и с памятью совсем хорошо. Ну понятно по цене чуть дороже, но не сильно.
MaksVV, другой камень взять для чего? Этот мк для тех, кто привык к меге328 и к большому кол-ву библиотек, написанных под мегу328. Я вот хоть уже давно увлечён stm32, но именно к меге 328 сохранил тёплые дружеские чувства ;)
Кому нибудь попадались такие нано с 328pb
Их стоит брать?
#Aliexpress 159,89 руб. 10%СКИДКА | Nano Mini USB с Загрузчиком совместимый контроллер Nano 3,0 Для arduino CH340 USB драйвер Nano v3.0 Atmega328 Atmega328pb https://a.aliexpress.ru/_BPjqJj
Double check chip, or use -F to overridethischeck.
185
186
avrdude.exe done. Thank you.
затем выбрал шится на внутренем кварце в 8 мгц и вроде как залилось, затем попытался еще раз залить то же самое не двигая и не разьединя ничего сразу выпадает ошибка
Charovnik, Мне кажется, что проблемы с прошивкой голых МК в 99% случаев возникают из-за плохих контактов(монтажа). Я например никогда не шью так, как вы -подвесив МК на соплях. Либо сначала припаиваю МК в ту плату, где он будет работать, а потом через разъём ISP прошиваю. Либо припаиваю МК непосредственно на переходник программатора. И всё всегда шьётся без проблем.
Вобщем взял ардуину нану с простым 328р залил в нее блинк, снял кварц с наны блинк не работал, снял чип поставил чип и кварц на колодку поставил диод на 13 ногу и резистор 1ком на ресет и 5вольт подал напряжение блинк работает. Подключил поровода isp. Тот же самый блинк скетч заливается загрузка же загрущика не идет. Ошибки типа ff0000 00ff00 0000ff. При этом когда отравляю команду по диоду видно что чип в колодке пытался прерватся
А если не прошивать загрузчик, не менять фьюзы - программатором скетчи в МК заливаются?
Если не прошивать загрузчик, то скетчи программатором загружаются. Но с завода чип настроен на непонятный внешний кварц, толи 16MHz толи 1Mhz. Не столь важно, всё равно не подходит. По этому надо перепрошить. И вот у меня полностью аналогично, как описывает Charovnik.
После первой записи загрузчика - дальше ничего не работало. Правда, я это два года назад делал и разными загрузчиками испортил три атмеги и на этом эксперименты отложил до лучших времён. Сейчас активно использую MiniCore библиотеку. Ею еще не пробовал прошить новые Atmega328PB, а в старые не грузится. Хотя тут пишут, что это может программатор Arduino as ISP не подходит. А USBtinyISP загрузить сможет... попробовать, что-ли...
Для сравнения, Atmega328P прекрасно прошивается. Отличие от в логах от Atmega328PB вот именно в этой строчке:
Почему-то для Atmega328PB оно напрочь разучивается правильно считывать эту сигнатуру. Пишет, что не тот контроллер и останавливается. А надо, чтобы пробовало загрузить загрузчик. Люди пишут, что когда делают это в принудительном порядке, то загружается и всё дальше работает.
Но с завода чип настроен на непонятный внешний кварц, толи 16MHz толи 1Mhz.
С завода чип ВСЕГДА настроен на внутренний RC-осциллятор 8МГц с делителем на 8 (т.е. тактовая 1МГц). Если у Вас чип настроен на внешний кварц, значит он уже не с завода. Вам продали б/у чип, в котором менялись фьюзы.
Цитата:
avrdude: Device signature = 0x1e950f (probably m328p)
Почему-то для Atmega328PB оно напрочь разучивается правильно считывать эту сигнатуру.
Если бы были проблемы со считыванием сигнатуры, там были нули: Device signature = 0x000000 или другая билиберда. В данном случае он чётко считывает сигнатуру Atmega328P. Сигнатура для Atmega328PB = 0x1e9516.
Вы уверены, что чип не перемаркировка б/у Atmega328P? Все признаки указывают на это.
"С завода чип ВСЕГДА настроен на внутренний RC-осциллятор 8МГц с делителем на 8 (т.е. тактовая 1МГц). "
Да, где-то про это и написал, что там была другая частота, а не 8MHz, которая нужна тогда была мне.
"Если бы были проблемы со считыванием сигнатуры, там были нули: Device signature = 0x000000".
Да, вот так и есть на микроконтроллерах, которые когда-то "испортил". В зависимости от выбранной частоты кварца там еще ff куда нибудь вписывается. Типа: avrdude.exe: Device signature = 0x00ff00
Загвоздка была, что первый раз то оно прошивалось.
Ради эксперимента, взял только что новый Atmega328PB. Прошил его MiniCore. Прошилось (но первый раз так и с другими загрузчиками было). Загрузил загрузчик второй раз - снова загрузилось! Залил через программатор сектч - работает. Алилуя. Вот она, нормально работающая библиотека для этого микропроцессора. Дело в том, что нашел её только год назад и теперь активно использую. А портил микроконтроллеры PB года два назад. Тогда по ним инфы было маловато.
И в завершение, вот как выглядит успешный лог (не знаю, как его свернуть):
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:
64
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:
Weisnar - это все интересно, но совершенно не отменяет того, что тот чип где у вас читается
avrdude: Device signature = 0x1e950f
- скорее всего перемаркировка.
Вообще , мне кажется что вы как-то очень смутно представляете весь процесс, постоянно путаетесь в рассуждениях, что и как прошивали, что у вас в итоге работает, а что блочится...
По мне так тут все предельно ясно. Когда вы выставляете правильные фьюзы к правильно определенному чипу, верно соединяете провода, правильно выбираете параметры в настройках программатора - все прошивается. А если где-то ошибка - то нет. И не надо никакой магии...
а если у вас был чип с сигнатурой 0x1e950f от обычной 328р , а вы его насильно с параметром -f зашили как 328pb - то понятно, что такое можно сделать только один раз, а потом он блочится
Согласен с b707.
Сигнатура 0x1e950f НЕ может возникнуть случайным образом в результате ошибки считывания, это исключено.
Это однозначно говорит о том, что прошиваемый чип является Atmega328P, а не Atmega328PB.
а если у вас был чип с сигнатурой 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 уже не выходит. Программатор ругается на отсутствие сигнатуры.
Weisnar - вопрос о том, нафига вообще нужен загрузчик, если вы работаете с голым чипом, да еще и на внутреннем осцилляторе? Заливайте скетчи программатором и не мучайтесь
Нужен ли загрузчик в атмегах вопрос, наверно, больше философский.
Лично мне он подходит по двум причинам:
- добавляет два цифровых пина, которые в заводской прошивке не активны;
- добавляет возможность обновлять скетчи по UART, а на пины 10,11,12,13 обычно припаиваю какой-то радиомодуль.
Тоесть, мне всегда думалось, что загрузчик - штука полезная.
Тем боле, насколько понял, MiniCore использует загрузчик Optiboot, а он в свою очередь совсем не большой размером.
Хотя очень давно экспериментировал, там толи MISO, толи MOSI радиомодуля достаточно через резистор подключить и всё. Он не будет мешать перепрошивке.
Так что... Загрузчики лучше не использовать? Я же написал. Проверил уже на нескольких 328PB. MiniCore нормально заливается и всё работает лучше прежнего.
Кто не знает, Optiboot еще и функцию watchdog восстанавливает. Но она конфликтует с библиотекой LowPower, по этому тут уж кому что нужнее.
Третий раз делаю подписку на эту тему, но кто-то удаляет пост, зачем ?. Соответственно уведомления не приходят.
Если пост пустой - я удаляю, не разбираясь, для подписки он или руки не туда дрогнули. На этом форуме это стандартная практика.
Дед, до этого момента, если тема меня заинтересовала я ставил - точку(.) и всё уведомления на почту, это по моему и была стандартная практика на этом форуме.
Индикацию чего?
визуальную индикацию работы таймеров, светодиод для этого на плате уже есть - LED на пине 13, в идеале 1 короткая вспышка - 0 таймер, две - 1-й и так далее, по кругу на всех доступных таймерах
До сих пор ничерта не понимаю. Перед каждым вызовом добавить for(uint8_t i=0; 3 > i; i++) { digitalWrite(13, HIGH); delay(200); digitalWrite(13, LOW);} что ли?
Да как угодно. чтобы работу всех таймеров можно было визуально проверить только одним светодиодом )))
Вот тут я сделал по рабоче-крестьянски, но для того, чтобы проверить все таймера надо изменять номер таймера и заливать прошивку, а это - пять раз, сможешь сделать ХЭД ЭНД ШОЛДЕРС будет великолепно
Да как угодно. чтобы работу всех таймеров можно было визуально проверить только одним светодиодом )))
Ну подключайте один светодиод к разным ногам. Или думаете, что я каким-то волшебным способом заставлю T1 меандр выдавать на D13, а не на D9?
Да как угодно. чтобы работу всех таймеров можно было визуально проверить только одним светодиодом )))
Ну подключайте один светодиод к разным ногам. Или думаете, что я каким-то волшебным способом заставлю T1 меандр выдавать на D13, а не на D9?
впрямую нет, но программист, он жеж как бог, не вижу почему это нельзя сделать
Дед, до этого момента, если тема меня заинтересовала я ставил - точку(.) и всё уведомления на почту, это по моему и была стандартная практика на этом форуме.
Олег, просто точки, я тоже удаляю, т.к. неясно, человек запостил и потом стер или подписался.
Стандартная практика, на большинстве форумов, внятно, по-русски, написать "подпишусь", а не плодить посты с точками. Или я из тьмы выпал?
А ещё лучше написать что-то полезное по теме :)
Есть много чего, что можно исследовать обладателям этого МК, например:
-как "заардуинить" сенсорные кнопки на этом мк.
-тестирование стабильности при разгоне.
-сравнить разные аддоны
А ещё лучше написать что-то полезное по теме :)
Есть много чего, что можно исследовать обладателям этого МК, например:
-как "заардуинить" сенсорные кнопки на этом мк.
-тестирование стабильности при разгоне.
-сравнить разные аддоны
как раз последним и занимаюсь, сравниваю, аддон от pololu выпадает, много косяков
продолжаю исследовать аддоны, в аддоне от MiniCore (в нём доступны и другие процессоры) есть возможность установки BOD и опции компилятора LTO, при разрешении последнего к примеру на скетче квона для LCD2004 позволяет экономить память программ до полкилобайта!
Проверочный скетч, задействованы все таймеры:
001
// Скетч проверки таймеров для платы на чипе ATmega328PB
002
#include "ConstTimers.h"
003
004
#define TIMER0 0 //здесь указать номер таймера, индикация - мигание LED на пине 13
005
#define FREQUENCY0 1600
006
#define TIMER1 1 //здесь указать номер таймера, индикация - мигание LED на пине 13
007
#define FREQUENCY1 3200
008
#define TIMER2 2 //здесь указать номер таймера, индикация - мигание LED на пине 13
009
#define FREQUENCY2 6400
010
#define TIMER3 3 //здесь указать номер таймера, индикация - мигание LED на пине 13
011
#define FREQUENCY3 12800
012
#define TIMER4 4 //здесь указать номер таймера, индикация - мигание LED на пине 13
013
#define FREQUENCY4 25600
014
015
uint8_t t, p;
016
const
byte
delta = 1;
//отклонение частоты от расчетной в %
017
unsigned
int
counter, counter1 = 0;
018
019
void
setup
() {
020
constexpr uint8_t prescalerBits0 = prescalerBitsByFrequency(TIMER0, FREQUENCY0);
021
constexpr uint16_t timerTicks0 = timerTicksByFrequency(TIMER0, FREQUENCY0, delta);
022
static_assert(timerTicks0,
"The required frequency is unattainable"
);
023
024
constexpr uint8_t prescalerBits1 = prescalerBitsByFrequency(TIMER1, FREQUENCY1);
025
constexpr uint16_t timerTicks1 = timerTicksByFrequency(TIMER1, FREQUENCY1, delta);
026
static_assert(timerTicks1,
"The required frequency is unattainable"
);
027
028
constexpr uint8_t prescalerBits2 = prescalerBitsByFrequency(TIMER2, FREQUENCY2);
029
constexpr uint16_t timerTicks2 = timerTicksByFrequency(TIMER2, FREQUENCY2, delta);
030
static_assert(timerTicks2,
"The required frequency is unattainable"
);
031
032
constexpr uint8_t prescalerBits3 = prescalerBitsByFrequency(TIMER3, FREQUENCY3);
033
constexpr uint16_t timerTicks3 = timerTicksByFrequency(TIMER3, FREQUENCY3, delta);
034
static_assert(timerTicks3,
"The required frequency is unattainable"
);
035
036
constexpr uint8_t prescalerBits4 = prescalerBitsByFrequency(TIMER4, FREQUENCY4);
037
constexpr uint16_t timerTicks4 = timerTicksByFrequency(TIMER4, FREQUENCY4, delta);
038
static_assert(timerTicks0,
"The required frequency is unattainable"
);
039
040
pinMode(13, OUTPUT);
041
//t=TIMER;
042
043
//if(t==0){
044
// p=6;
045
pinMode(6, OUTPUT);
046
TCCR0A = 0x42;
// Инвертирование пина 6 по сравнению и режим CTC то OCR0A
047
TCCR0B = 0x00 | prescalerBits0;
// Установить СТС режим и делитель частоты
048
OCR0A = timerTicks0;
// установить TOP равным timerTicks
049
// }
050
051
// if(t==1){
052
// p=9;
053
pinMode(9, OUTPUT);
054
TCCR1A = bit(COM1A0);
// Инвертирование пина 9 по сравнению
055
TCCR1B = bit(WGM12) | prescalerBits1;
// Установить СТС режим и делитель частоты
056
OCR1A = timerTicks1;
// установить TOP равным timerTicks
057
// }
058
059
// if(t==2){
060
// p=11;
061
pinMode(11, OUTPUT);
062
TCCR2A = 0x42;
// Инвертирование пина 11 по сравнению и режим CTC то OCR2A
063
TCCR2B = 0x00 | prescalerBits2;
// Установить СТС режим и делитель частоты
064
OCR2A = timerTicks2;
// установить TOP равным timerTicks
065
// }
066
067
// if(t==3){
068
// p = 0;
069
pinMode(0, OUTPUT);
070
TCCR3A=1<<COM3A0 | 1<<COM3B0;
071
TCCR3B=1<<WGM32 | prescalerBits3;
// Режим СТС WGM3[3:0]=4 или 12
072
OCR3A = timerTicks3;
// установить TOP равным timerTicks
073
// }
074
075
// if(t==4){
076
// p = 1;
077
pinMode(1, OUTPUT);
078
TCCR4A=1<<COM4A0 | 1<<COM4B0;
079
TCCR4B=1<<WGM42 | prescalerBits4;
// Режим СТС WGM4[3:0]=4 или 12
080
OCR4A = timerTicks4;
// установить TOP равным timerTicks
081
// }
082
}
083
084
void
loop
() {
085
while
(counter1 <10){
086
while
(digitalRead(6)==LOW);
087
counter++;
088
while
(digitalRead(6)==HIGH);
089
if
(counter==FREQUENCY0/4){
// BLINK 250 мсек
090
digitalWrite(13,!digitalRead(13));
091
counter = 0; counter1++;}
092
}
093
counter1=0;
094
095
while
(counter1 <10){
096
while
(digitalRead(9)==LOW);
097
counter++;
098
while
(digitalRead(9)==HIGH);
099
if
(counter==FREQUENCY1/8){
// BLINK 250 мсек
100
digitalWrite(13,!digitalRead(13));
101
counter = 0; counter1++;}
102
}
103
counter1=0;
104
105
while
(counter1 <10){
106
while
(digitalRead(11)==LOW);
107
counter++;
108
while
(digitalRead(11)==HIGH);
109
if
(counter==FREQUENCY2/4){
// BLINK 250 мсек
110
digitalWrite(13,!digitalRead(13));
111
counter = 0; counter1++;}
112
}
113
counter1=0;
114
115
while
(counter1 <10){
116
while
(digitalRead(0)==LOW);
117
counter++;
118
while
(digitalRead(0)==HIGH);
119
if
(counter==FREQUENCY3/8){
// BLINK 250 мсек
120
digitalWrite(13,!digitalRead(13));
121
counter = 0; counter1++;}
122
}
123
counter1=0;
124
125
while
(counter1 <10){
126
while
(digitalRead(1)==LOW);
127
counter++;
128
while
(digitalRead(1)==HIGH);
129
if
(counter==FREQUENCY4/4){
// BLINK 250 мсек
130
digitalWrite(13,!digitalRead(13));
131
counter = 0; counter1++;}
132
}
133
counter1=0;
134
}
135
И библиотека к нему:
001
#ifndef CONSTTIMERS_H
002
#define CONSTTIMERS_H
003
004
///////////////////////////////////////////////////////////////////////////////
005
//
006
// Модификация недобиблиотеки от ЕвгенийП.
007
// Выполнена: Ворота, 11.07.2019.
008
// Проба: UA6EM 12.07.2019 (Atmega328PB, WAVGAT, LGT8FX8P)
009
//
010
// Основные изменения:
011
// 1. К работе с частотами добавлена работа с периодами/интервалами;
012
// 2. Добавлено задание максимальной допустимой погрешности количества тактов;
013
// 3. Появилась возможность выдавать ошибку компиляции в случае выхода за допустимую погрешность;
014
// 4. Добавлены суффиксы для работы с временными интервалами (на основе другого кода от ЕвгенийП);
015
// 5. Добавлена поддержка Мега, Леонардо и ATmega32A
016
// 6. Все «внутренние» функции спрятаны в своё пространство имён.
017
//
018
// ---------------
019
//
020
// Определяются биты конфигурации делителя частоты таймера и количество тактов с данным делителем для
021
// получения нужного интервала срабатывания таймера. Интервал задаётся либо частотой, либо периодом
022
// (длительностью, если речь идёт об одиночном сигнале, например, по переполнению).
023
// Соответственно, имеются четыре функции:
024
//
025
// uint8_t prescalerBitsByPeriod(int8_t nTimer, uint32_t period);
026
// uint16_t timerTicksByPeriod(int8_t nTimer, uint32_t period, int8_t error = 0);
027
//
028
// uint8_t prescalerBitsByFrequency(int8_t nTimer, uint32_t frequency);
029
// uint16_t timerTicksByFrequency(int8_t nTimer, uint32_t frequency, int8_t error = 0);
030
//
031
// Первый параметр у всех функций – номер таймера. Параметры period и frequency – соответственно
032
// требуемые период в тактах микроконтроллера (см. ниже о суффиксах) и частота (в герцах).
033
// Параметр error задаёт допустимое отклонение от запрошенных характеристик в процентах.
034
// Если не удаётся получить решение в пределах допустимого отклонения, то timerTicksByХХХ вернут 0.
035
//
036
// Также имеется функция, возвращающая значение делителя частоты заданного таймера по битам конфигурации,
037
// полученным от функций prescalerBitsByХХХ.
038
//
039
// int16_t prescalerValue(uint8_t nTimer, uint8_t bits);
040
//
041
// Для удобства работы с временными интервалами добавлены суффиксы _clk, _us, _ms и _sec. Таким образом,
042
// второй параметр функций prescalerBitsByPeriod и timerTicksByPeriod (время в тактах микроконтроллера)
043
// можно задавать при помощи суффиксов, например:
044
//
045
// 100 или 100_clk – сто тактов микроконтроллера;
046
// 100_us – сто микросекунд;
047
// 100_ms – сто миллисекунд;
048
// 2_sec – две секунды.
049
//
050
// Допускаются также арифметические операции, например, запись
051
//
052
// 2_ms + 50_us
053
//
054
// вполне допустима и означает 2050 микросекунд.
055
//
056
// ИСПОЛЬЗОВАНИЕ
057
//
058
// Для использования необходимо включить файл «ConstTimers.h» и определить константы с
059
// модификатором constexpr для нужных конфигурационных битов и количества тиков, которым
060
// присвоить значения, возвращаемые функциям prescalerBitsByХХХ и timerTicksByХХХ соответственно.
061
//
062
// Если использовать именно так, то код библиотеки целиком исполняется во время компиляции
063
// и не оказывает никакого влияния ни на размер занимаемой памяти, ни на код программы.
064
// В коде программы будут вставлены готовые (вычисленные на этапе компиляции) константы.
065
//
066
// Это позволяет организовать проверку полученного на этапе компиляции значения (функции
067
// timerTicksByХХХ возвращают 0 в случае невозможности соблюсти необходимую точность)
068
// и прервать компиляцию с соответствующим сообщением об ошибке при помощи static_assert.
069
//
070
// Пример рекомендуемого использования:
071
//
072
// /////////////////////////////////////////////////
073
// //
074
// // Получаем меандр с частотой 50Гц на 9-ом пине
075
// // для этого заводим его на СТС и инвертированием
076
// // на частоте 100Гц (как раз 100/2 = 50)
077
// //
078
// #include <ConstTimers.h>
079
//
080
// #define TIMER 1
081
// #define FREQUENCY 100
082
//
083
// static constexpr uint8_t prescalerBits = prescalerBitsByFrequency(TIMER, FREQUENCY);
084
// static constexpr uint16_t timerTicks = timerTicksByFrequency(TIMER, FREQUENCY);
085
//
086
// // проверка установилась ли частота (например, при частоте 101 будет ошибка компиляции)
087
// static_assert(timerTicks, "The required frequency with a desired accuracy is unattainable for timer/counter");
088
//
089
// void setup() {
090
// pinMode(9, OUTPUT);
091
// TCCR1A = bit(COM1A0); // Инвертирование пина 9 по сравнению
092
// TCCR1B = bit(WGM12) | prescalerBits; // Установить СТС режим и делитель частоты
093
// OCR1A = timerTicks; // установить TOP равным timerTicks
094
// }
095
//
096
// void loop() {}
097
//
098
//Результат работы будет точно такой же, как если написать константы, вместо вычислений:
099
//
100
// void setup() {
101
// pinMode(9, OUTPUT);
102
// TCCR1A = bit(COM1A0);
103
// TCCR1B = bit(WGM12) | 2;
104
// OCR1A = 20000;
105
// }
106
// void loop() {}
107
//
108
// Ни на один байт код не изменится.
109
//
110
// КОНФИГУРАЦИЯ:
111
//
112
// 1. расчёт производится для текущей тактовой частоты микроконтроллера. Если нужно
113
// считать для какой-то другой частоты, измените константу FCPU.
114
//
115
// 2. STimerParameters - массив конфигурации таймеров. Количество элементов массива
116
// соответствует количеству таймеров. Нулевой элемент описывает нулевой таймер,
117
// первый элемент – первый таймер и т.д. Если требуется расширить недобиблиотеку для других
118
// микроконтроллеров, нужно изменить именно этот массив и больше изменять ничего не надо.
119
//
120
// В массиве для каждого таймера указано:
121
// 1) разрядность таймера в виде максимально возможного значения количества тиков
122
// (для 8-разрядных таймеров – 0xFF, для 16-разрядных – 0xFFFF.
123
// 2) указатель на массив делителей частоты. Делители начинаются с 1 (делитель 0 писать не нужно)
124
// 3) количество делителей частоты у данного таймера.
125
//
126
// ЛИЦЕНЗИЯ
127
//
128
// Данный код поставляется по лицензии ПНХ.
129
//
130
// 1. Вы можете свободно использовать или не использовать его в коммерческих,
131
// некоммерческих, и любых иных, не запрещённых законом, целях.
132
//
133
// 2. Автор не несёт решительно никакой ответственности за любые положительные
134
// или отрицательные результаты использования или неиспользования данного кода.
135
//
136
// 3. Если Вам таки хочется сделать автору предъяву, то Вы знаете, куда
137
// Вам следует обратиться. А если не знаете, то см. название лицензии.
138
//
139
// 4. Если данный код вдруг Вам пригодился (как учебник или ещё как что) и Вам
140
// почему-либо (ну, приболели, может) захотелось отблагодарить автора рублём,
141
// то это всегда пожалуйста – WebMoney, кошелёк № R626206676373
142
//
143
// 5. Возникновение или невозникновение у Вас желаний, обозначенных в п.4
144
// настоящей лицензии никак не связано с п.1, который действует безусловно
145
// и независимо от п.4.
146
//
147
// 6. Если данный код нужен Вам с какой-либо другой лицензией, например, с
148
// сопровождением или Вы нуждаетесь во внесении изменений, свяжитесь с автором
149
// на предмет заключения договора гражданско-правового характера.
150
//
151
///////////////////////////////////////////////////////////////////////////////
152
153
#define ATtiny85Detected (defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__))
154
#define ATmega328Detected (defined(__AVR_ATmega48A__) || defined(__AVR_ATmega48PA__) || defined(__AVR_ATmega88A__) \
155
|| defined(__AVR_ATmega88PA__) || defined(__AVR_ATmega168A__) || defined(__AVR_ATmega168PA__) \
156
|| defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__))
157
#define ATmega2561Detected (defined(__AVR_ATmega640__) || defined(__AVR_ATmega640V__) || defined(__AVR_ATmega1280__) \
158
|| defined(__AVR_ATmega1280V__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega1281V__) \
159
|| defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2560V__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega2561V__))
160
#define ATmega32U4Detected (defined(__AVR_ATmega32U4__))
161
#define ATmega32ADetected (defined(__AVR_ATmega32A__))
162
#define ATmega328PBDetected (defined(__AVR_ATmega328PB__))
163
#define Wavgatlgtx8PDetected (defined(__LGT8FX8P32__)) || (defined(__LGT8FX8P__))
164
165
#define FCPU F_CPU
166
167
namespace
constTimersNS {
168
169
struct
STimerParameters {
170
const
uint32_t maxValue;
171
const
int16_t * prescalers;
172
const
uint8_t totalPrescalers;
173
};
174
175
static
constexpr uint32_t bits8 = 0x000000FFul;
176
static
constexpr uint32_t bits10 = 0x000003FFul;
177
static
constexpr uint32_t bits16 = 0x0000FFFFul;
178
179
#if Wavgatlgtx8PDetected
180
181
static
constexpr int16_t prescalers013[] = { 1, 8, 64, 256, 1024 };
182
static
constexpr int16_t prescalers2[] = { 1, 8, 32, 64, 128, 256, 1024 };
183
184
static
constexpr STimerParameters timerParameters[] = {
185
{ bits8, prescalers013,
sizeof
(prescalers013) /
sizeof
(prescalers013[0]) },
186
{ bits16, prescalers013,
sizeof
(prescalers013) /
sizeof
(prescalers013[0]) },
187
{ bits8, prescalers2,
sizeof
(prescalers2) /
sizeof
(prescalers2[0]) },
188
{ bits16, prescalers013,
sizeof
(prescalers013) /
sizeof
(prescalers013[0]) }
189
};
190
191
#elif ATmega328PBDetected
192
193
static
constexpr int16_t prescalers0134[] = { 1, 8, 64, 256, 1024 };
194
static
constexpr int16_t prescalers2[] = { 1, 8, 32, 64, 128, 256, 1024 };
195
196
static
constexpr STimerParameters timerParameters[] = {
197
{ bits8, prescalers0134,
sizeof
(prescalers0134) /
sizeof
(prescalers0134[0]) },
198
{ bits16, prescalers0134,
sizeof
(prescalers0134) /
sizeof
(prescalers0134[0]) },
199
{ bits8, prescalers2,
sizeof
(prescalers2) /
sizeof
(prescalers2[0]) },
200
{ bits16, prescalers0134,
sizeof
(prescalers0134) /
sizeof
(prescalers0134[0]) },
201
{ bits16, prescalers0134,
sizeof
(prescalers0134) /
sizeof
(prescalers0134[0]) }
202
};
203
204
#elif ATmega328Detected || ATmega32ADetected
205
206
static
constexpr int16_t prescalers01[] = { 1, 8, 64, 256, 1024 };
207
static
constexpr int16_t prescalers2[] = { 1, 8, 32, 64, 128, 256, 1024 };
208
static
constexpr int16_t prescalers3[] = { 1, 8, 64, 256, 1024 };
209
210
static
constexpr STimerParameters timerParameters[] = {
211
{ bits8, prescalers01,
sizeof
(prescalers01) /
sizeof
(prescalers01[0]) },
212
{ bits16, prescalers01,
sizeof
(prescalers01) /
sizeof
(prescalers01[0]) },
213
{ bits8, prescalers2,
sizeof
(prescalers2) /
sizeof
(prescalers2[0]) },
214
{ bits16, prescalers3,
sizeof
(prescalers3) /
sizeof
(prescalers3[0]) }
// для WAVGAT
215
};
216
217
#elif ATmega32U4Detected
218
219
static
constexpr int16_t prescalers013[] = { 1, 8, 64, 256, 1024 };
220
static
constexpr int16_t prescalers2[] = { 1, 8, 32, 64, 128, 256, 1024 };
221
static
constexpr int16_t prescalers4[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384 };
222
223
static
constexpr STimerParameters timerParameters[] = {
224
{ bits8, prescalers013,
sizeof
(prescalers013) /
sizeof
(prescalers013[0]) },
225
{ bits16, prescalers013,
sizeof
(prescalers013) /
sizeof
(prescalers013[0]) },
226
{ bits8, prescalers2,
sizeof
(prescalers2) /
sizeof
(prescalers2[0]) },
227
{ bits16, prescalers013,
sizeof
(prescalers013) /
sizeof
(prescalers013[0]) },
228
{ bits10, prescalers4,
sizeof
(prescalers4) /
sizeof
(prescalers4[0]) }
229
};
230
231
#elif ATmega2561Detected
232
233
static
constexpr int16_t prescalers01345[] = { 1, 8, 64, 256, 1024 };
234
static
constexpr int16_t prescalers2[] = { 1, 8, 32, 64, 128, 256, 1024 };
235
236
static
constexpr STimerParameters timerParameters[] = {
237
{ bits8, prescalers01345,
sizeof
(prescalers01345) /
sizeof
(prescalers01345[0]) },
238
{ bits16, prescalers01345,
sizeof
(prescalers01345) /
sizeof
(prescalers01345[0]) },
239
{ bits8, prescalers2,
sizeof
(prescalers2) /
sizeof
(prescalers2[0]) },
240
{ bits16, prescalers01345,
sizeof
(prescalers01345) /
sizeof
(prescalers01345[0]) },
241
{ bits16, prescalers01345,
sizeof
(prescalers01345) /
sizeof
(prescalers01345[0]) },
242
{ bits16, prescalers01345,
sizeof
(prescalers01345) /
sizeof
(prescalers01345[0]) }
243
};
244
245
#elif ATtiny85Detected
246
247
static
constexpr int16_t prescalers0[] = { 1, 8, 64, 256, 1024 };
248
static
constexpr int16_t prescalers1[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384 };
249
250
static
constexpr STimerParameters timerParameters[] = {
251
{ bits8, prescalers0,
sizeof
(prescalers0) /
sizeof
(prescalers0[0]) },
252
{ bits8, prescalers1,
sizeof
(prescalers1) /
sizeof
(prescalers1[0]) }
253
};
254
255
#else
256
257
#error The library does not seem to support your MCU
258
259
#endif
260
261
constexpr int8_t totalTimers =
sizeof
(timerParameters) /
sizeof
(timerParameters[0]);
262
263
static
constexpr uint32_t getPeriod(
const
uint32_t frequency) {
264
return
(FCPU + frequency / 2) / frequency;
265
}
266
267
static
constexpr uint16_t prValue(
const
int8_t prescalerId,
const
int8_t nTimer) {
268
return
timerParameters[nTimer].prescalers[prescalerId];
269
}
270
271
static
constexpr uint32_t getDesiredTicks(
const
uint32_t period,
const
int8_t prescalerId,
const
int8_t nTimer) {
272
return
(period + prValue(prescalerId, nTimer) / 2) / prValue(prescalerId, nTimer);
273
}
274
275
static
constexpr uint32_t correctTicks(uint32_t dTicks,
const
uint32_t maxValue) {
276
//if (dTicks > maxValue) return maxValue; else return dTicks; // начиная с C++14
277
return
dTicks > maxValue ? maxValue : dTicks;
278
}
279
280
static
constexpr uint32_t getTicks(
const
uint32_t period,
const
int8_t prescalerId,
const
int8_t nTimer) {
281
return
prescalerId >= timerParameters[nTimer].totalPrescalers ? 0x1FFFFFFF :
282
correctTicks(getDesiredTicks(period, prescalerId, nTimer), timerParameters[nTimer].maxValue);
283
}
284
285
static
constexpr uint32_t getBits(
const
int8_t prescalerId,
const
int8_t nTimer) {
286
return
prescalerId >= timerParameters[nTimer].totalPrescalers ? timerParameters[nTimer].totalPrescalers : prescalerId + 1;
287
}
288
289
290
static
constexpr int32_t absErrorTicks(
const
uint32_t period,
const
uint32_t ticks) {
291
return
period > ticks ? period - ticks : ticks - period;
292
}
293
294
static
constexpr int32_t absError(
const
uint32_t period,
const
int8_t prescalerId,
const
int8_t nTimer) {
295
return
prescalerId >= timerParameters[nTimer].totalPrescalers ? 0x1FFFFFFF :
296
absErrorTicks(period, getTicks(period, prescalerId, nTimer) * prValue(prescalerId, nTimer));
297
}
298
299
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) {
300
return
301
(prId >= timerParameters[nTimer].totalPrescalers) ? candidate
302
: getPrescalerId(newError, absError(period, prId + 1, nTimer), prId + 1, (error <= newError) ? candidate : prId, period, nTimer);
303
}
304
305
static
constexpr
double
calcErrorPercentage(
const
double
fcpu,
const
double
perc) {
306
return
(fcpu < perc ? 1.0 - fcpu / perc : fcpu / perc - 1.0) * 100.0;
307
}
308
309
static
constexpr uint16_t returnTicksOrZero(
const
uint32_t left,
const
uint32_t right,
const
int8_t allowableError,
const
uint32_t ticks) {
310
return
left == right || calcErrorPercentage(left, right) <= allowableError ? ticks : 0;
311
}
312
313
static
constexpr uint16_t getTimerTicksIntFTicks(
const
uint32_t ticks,
const
int8_t nTimer,
const
uint32_t freq, uint8_t prescalerId,
const
int8_t allowableError) {
314
return
returnTicksOrZero(FCPU, freq * ticks * timerParameters[nTimer].prescalers[prescalerId], allowableError, ticks);
315
}
316
317
static
constexpr uint16_t getTimerTicksIntF(
const
int8_t nTimer,
const
uint32_t freq, uint8_t prescalerId,
const
int8_t allowableError) {
318
return
getTimerTicksIntFTicks(getTicks(getPeriod(freq), prescalerId, nTimer), nTimer, freq, prescalerId, allowableError);
319
}
320
321
static
constexpr uint16_t getTimerTicksIntTTicks(
const
uint32_t ticks,
const
int8_t nTimer,
const
uint32_t period, uint8_t prescalerId,
const
int8_t allowableError) {
322
return
returnTicksOrZero(period, ticks * timerParameters[nTimer].prescalers[prescalerId], allowableError, ticks);
323
}
324
325
static
constexpr uint16_t getTimerTicksIntT(
const
int8_t nTimer,
const
uint32_t period, uint8_t prescalerId,
const
int8_t allowableError) {
326
return
getTimerTicksIntTTicks(getTicks(period, prescalerId, nTimer), nTimer, period, prescalerId, allowableError);
327
}
328
329
330
//////////////////////////////////////////////////////////////////
331
//
332
// Суффиксы литералов для задания времени
333
// 100 или 100_clk - время в тактах контроллера (100 тактов)
334
// 100_us - время в микросекундах (100 микросекунд)
335
// 100_ms - время в милисекундах (100 милисекунд)
336
// 5_sec - время в секундах (5 секунд)
337
//
338
static
constexpr int8_t __sLen(
const
char
* str,
const
int8_t candidate = 0) {
return
(!*str) ? candidate : __sLen(str + 1, candidate + 1); }
339
static
constexpr
bool
__isFin(
const
char
* str,
const
int8_t lInd) {
return
lInd < 0 || !isdigit(str[lInd]); }
340
static
constexpr uint32_t __toDig(
const
char
* str,
const
uint32_t lg,
const
int8_t lInd) {
return
(str[lInd] -
'0'
) * lg; }
341
static
constexpr uint32_t ___s2ul(
const
char
* str,
const
uint32_t,
const
int8_t);
342
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); }
343
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); }
344
static
constexpr uint32_t __s2ul(
const
char
* str) {
return
___s2ul(str, 1, __sLen(str) - 1); }
345
346
}
// namespace constTimersNS
347
348
static
constexpr uint32_t
operator
""
_clk(
const
char
* s) {
return
constTimersNS::__s2ul(s); }
349
static
constexpr uint32_t
operator
""
_us(
const
char
* s) {
return
operator
""
_clk(s) * (FCPU / 1000000ul); }
350
static
constexpr uint32_t
operator
""
_ms(
const
char
* s) {
return
operator
""
_us(s) * 1000ul; }
351
static
constexpr uint32_t
operator
""
_sec(
const
char
* s) {
return
operator
""
_ms(s) * 1000ul; }
352
//
353
//////////////////////////////////////////////////////////////////
354
355
356
static
constexpr uint8_t prescalerBitsByPeriod(
const
int8_t nTimer,
const
uint32_t period) {
357
return
constTimersNS::getBits(constTimersNS::getPrescalerId(0x1FFFFFul, constTimersNS::absError(period, 0, nTimer), 0, 0, period, nTimer), nTimer);
358
}
359
360
static
constexpr uint16_t timerTicksByPeriod(
const
int8_t nTimer,
const
uint32_t period,
const
int8_t allowableError = 0) {
361
return
constTimersNS::getTimerTicksIntT(nTimer, period, constTimersNS::getPrescalerId(0x1FFFFFul, constTimersNS::absError(period, 0, nTimer), 0, 0, period, nTimer), allowableError);
362
}
363
364
static
constexpr uint8_t prescalerBitsByFrequency(
const
int8_t nTimer,
const
uint32_t freq) {
365
return
prescalerBitsByPeriod(nTimer, constTimersNS::getPeriod(freq));
366
}
367
368
static
constexpr uint16_t timerTicksByFrequency(
const
int8_t nTimer,
const
uint32_t freq,
const
int8_t allowableError = 0) {
369
return
constTimersNS::getTimerTicksIntF(nTimer, freq,
370
constTimersNS::getPrescalerId(0x1FFFFFul, constTimersNS::absError(constTimersNS::getPeriod(freq), 0, nTimer), 0, 0,
371
constTimersNS::getPeriod(freq), nTimer), allowableError);
372
}
373
374
static
constexpr int16_t prescalerValue(
const
uint8_t nTimer,
const
uint8_t bits) {
375
return
constTimersNS::timerParameters[nTimer].prescalers[bits-1];
376
}
377
378
#endif // CONSTTIMERS_H
10 шт./лот ATMEGA328PB-AU MEGA328PB-U ATMEGA328PB MEGA328PB MEGA328PB-AU
824,88 руб. / партия
Заказов (12)
Shenzhen Chuangzhuo Store Связаться с продавцом
А Atmel квадратиками закрасили чтобы не было претензий при получении левого чипа?
задам тупой вопрос. А раз уж распиновка не очень с простым 328 совпадает, может просто другой камень повыше в линейке применять? Например 1284p. У него и с памятью совсем хорошо. Ну понятно по цене чуть дороже, но не сильно.
MaksVV, другой камень взять для чего? Этот мк для тех, кто привык к меге328 и к большому кол-ву библиотек, написанных под мегу328. Я вот хоть уже давно увлечён stm32, но именно к меге 328 сохранил тёплые дружеские чувства ;)
понятно. согласен, всеобщая поддержка это важно.
Приветствую ! Ни у кого случаем нет лишнего камня ... двух ... на руках в России ? Купил бы с отправкой простым письмом.
P.S. За сутки никто не откликнулся ... :-(
Рассчитывали что все, у кого нет отпишутся? )) Камень этот пока скорей экзотика.
Кстати на амперке появились нанки по вменяемой (для Москвы) цене https://amperka.ru/product/iskra-nano-pro-headless
Вот и задачка для платы нарисовалась, осталось подключить модуль и проверить )))
Кому нибудь попадались такие нано с 328pb
Их стоит брать?
#Aliexpress 159,89 руб. 10%СКИДКА | Nano Mini USB с Загрузчиком совместимый контроллер Nano 3,0 Для arduino CH340 USB драйвер Nano v3.0 Atmega328 Atmega328pb
https://a.aliexpress.ru/_BPjqJj
Фото в "живую"
https://ibb.co/pdDh6z6
https://ibb.co/zPg4pQm
https://ibb.co/ZHpmq3C
https://ibb.co/LpHCL4V
https://ibb.co/Jv0YYvG
https://ibb.co/YB990Cx
https://ibb.co/NK4y8KL
https://ibb.co/1vwM7SS
На фото обычный контроллер 328P
Если 328pb лучше 328p почему он не пошёл в массы и не обрёл популярность? В чем проблема использования для рядового пользователя?
Пойдет ещё, надеюсь. Существующий техпроцесс по производству ардуин со старыми МК никто не торопится ломать.
Для рядового куча проблем: менталитет, отсутствие в массовых поделках, библиотеки надо править. Для меня вот эти интереснее https://aliexpress.ru/item/32828713412.html
Ну а пока на макетке.
добрый день.
приобрел 328pb без загрущика.
подключил к ардуино нано по isp и кварцу в 16 мгц.
в менеджере плат скачал 328pb. при попытке залить бутлодырь получается ошибка.
выложите сообщение об ошибке полностью. В частности. если пишет "ожидаемая сигнатура такая-то..." - должен писать , какая реально прочитана с чипа
это означает, что МК не отвечает программатору.
Тут либо МК не стартует, либо в соединениях что-то напутали
взял другой чип попытался залить загрущик выбрав 16 мгц он вроде начал шиться но выкатил ошибку
001
Arduino: 1.8.12 (Windows 10), Плата:
"ATmega328PB Crystal Clock, 16 MHz"
002
003
004
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
005
006
avrdude.exe: Version 6.3-20190619
007
Copyright (c) 2000-2005 Brian Dean, <a href=
"http://www.bdmicro.com/"
rel=
"nofollow"
>http://www.bdmicro.com/</a>
008
Copyright (c) 2007-2014 Joerg Wunsch
009
010
System wide configuration file
is
"C:\Users\jp\AppData\Local\Arduino15\packages\m328pb\hardware\avr\1.1.4/tools/avrdude.conf"
011
012
Using Port : COM14
013
Using Programmer : stk500v1
014
Overriding Baud Rate : 19200
015
AVR Part : ATmega328PB
016
Chip Erase delay : 9000 us
017
PAGEL : PD7
018
BS2 : PC2
019
RESET disposition : dedicated
020
RETRY pulse : SCK
021
serial program mode : yes
022
parallel program mode : yes
023
Timeout : 200
024
StabDelay : 100
025
CmdexeDelay : 25
026
SyncLoops : 32
027
ByteDelay : 0
028
PollIndex : 3
029
PollValue : 0x53
030
Memory Detail :
031
032
Block Poll Page Polled
033
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
034
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
035
eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff
036
flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff
037
lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
038
hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
039
efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
040
lock
0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
041
calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
042
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
043
044
Programmer Type : STK500
045
Description : Atmel STK500 Version 1.x firmware
046
Hardware Version: 2
047
Firmware Version: 1.18
048
Topcard : Unknown
049
Vtarget : 0.0 V
050
Varef : 0.0 V
051
Oscillator : Off
052
SCK period : 0.1 us
053
054
avrdude.exe: AVR device initialized and ready to accept instructions
055
056
Reading | ################################################## | 100% 0.02s
057
058
avrdude.exe: Device signature = 0x1e9516 (probably m328pb)
059
avrdude.exe: erasing chip
060
avrdude.exe: reading input file
"0xFF"
061
avrdude.exe: writing
lock
(1 bytes):
062
063
Writing | ################################################## | 100% 0.01s
064
065
avrdude.exe: 1 bytes of
lock
written
066
avrdude.exe: verifying
lock
memory against 0xFF:
067
avrdude.exe: load data
lock
data from input file 0xFF:
068
avrdude.exe: input file 0xFF contains 1 bytes
069
avrdude.exe: reading on-chip
lock
data:
070
071
Reading | ################################################## | 100% 0.01s
072
073
avrdude.exe: verifying ...
074
avrdude.exe: 1 bytes of
lock
verified
075
avrdude.exe: reading input file
"0xFD"
076
avrdude.exe: writing efuse (1 bytes):
077
078
Writing | ***failed;
079
################################################## | 100% 0.05s
080
081
avrdude.exe: 1 bytes of efuse written
082
avrdude.exe: verifying efuse memory against 0xFD:
083
avrdude.exe: load data efuse data from input file 0xFD:
084
avrdude.exe: input file 0xFD contains 1 bytes
085
avrdude.exe: reading on-chip efuse data:
086
087
Reading | ################################################## | 100% 0.01s
088
089
avrdude.exe: verifying ...
090
avrdude.exe: WARNING: invalid value
for
unused bits
in
fuse
"efuse"
, should be
set
to 1 according to datasheet
091
This behaviour
is
deprecated and will result
in
an error
in
future version
092
You probably want to use 0xf5 instead of 0xfd (
double
check with your datasheet first).
093
avrdude.exe: 1 bytes of efuse verified
094
avrdude.exe: reading input file
"0xD6"
095
avrdude.exe: writing hfuse (1 bytes):
096
097
Writing | ################################################## | 100% 0.02s
098
099
avrdude.exe: 1 bytes of hfuse written
100
avrdude.exe: verifying hfuse memory against 0xD6:
101
avrdude.exe: load data hfuse data from input file 0xD6:
102
avrdude.exe: input file 0xD6 contains 1 bytes
103
avrdude.exe: reading on-chip hfuse data:
104
105
Reading | ################################################## | 100% 0.01s
106
107
avrdude.exe: verifying ...
108
avrdude.exe: 1 bytes of hfuse verified
109
avrdude.exe: reading input file
"0xFF"
110
avrdude.exe: writing lfuse (1 bytes):
111
112
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
113
Writing | ################################################## | 100% 0.02s
114
115
avrdude.exe: 1 bytes of lfuse written
116
avrdude.exe: verifying lfuse memory against 0xFF:
117
avrdude.exe: load data lfuse data from input file 0xFF:
118
avrdude.exe: input file 0xFF contains 1 bytes
119
avrdude.exe: reading on-chip lfuse data:
120
121
Reading | ################################################## | 100% 0.01s
122
123
avrdude.exe: verifying ...
124
avrdude.exe: 1 bytes of lfuse verified
125
126
avrdude.exe done. Thank you.
127
128
129
avrdude.exe: Version 6.3-20190619
130
Copyright (c) 2000-2005 Brian Dean, <a href=
"http://www.bdmicro.com/"
rel=
"nofollow"
>http://www.bdmicro.com/</a>
131
Copyright (c) 2007-2014 Joerg Wunsch
132
133
System wide configuration file
is
"C:\Users\jp\AppData\Local\Arduino15\packages\m328pb\hardware\avr\1.1.4/tools/avrdude.conf"
134
135
Using Port : COM14
136
Using Programmer : stk500v1
137
Overriding Baud Rate : 19200
138
AVR Part : ATmega328PB
139
Chip Erase delay : 9000 us
140
PAGEL : PD7
141
BS2 : PC2
142
RESET disposition : dedicated
143
RETRY pulse : SCK
144
serial program mode : yes
145
parallel program mode : yes
146
Timeout : 200
147
StabDelay : 100
148
CmdexeDelay : 25
149
SyncLoops : 32
150
ByteDelay : 0
151
PollIndex : 3
152
PollValue : 0x53
153
Memory Detail :
154
155
Block Poll Page Polled
156
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
157
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
158
eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff
159
flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff
160
lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
161
hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
162
efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
163
lock
0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
164
calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
165
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
166
167
Programmer Type : STK500
168
Description : Atmel STK500 Version 1.x firmware
169
Hardware Version: 2
170
Firmware Version: 1.18
171
Topcard : Unknown
172
Vtarget : 0.0 V
173
Varef : 0.0 V
174
Oscillator : Off
175
SCK period : 0.1 us
176
177
avrdude.exe: AVR device initialized and ready to accept instructions
178
179
Ошибка при записи загрузчика.
180
Reading | ################################################## | 100% 0.02s
181
182
avrdude.exe: Device signature = 0x0000ff
183
avrdude.exe: Expected signature
for
ATmega328PB
is
1E 95 16
184
Double check chip, or use -F to
override
this
check.
185
186
avrdude.exe done. Thank you.
01
Arduino: 1.8.12 (Windows 10), Плата:
"ATmega328PB Internal Clock, 8 MHz"
02
03
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
04
05
avrdude.exe: Version 6.3-20190619
06
Copyright (c) 2000-2005 Brian Dean, <a href=
"http://www.bdmicro.com/"
rel=
"nofollow"
>http://www.bdmicro.com/</a>
07
Copyright (c) 2007-2014 Joerg Wunsch
08
09
System wide configuration file
is
"C:\Users\jp\AppData\Local\Arduino15\packages\m328pb\hardware\avr\1.1.4/tools/avrdude.conf"
10
11
Using Port : COM14
12
Using Programmer : stk500v1
13
Overriding Baud Rate : 19200
14
AVR Part : ATmega328PB
15
Chip Erase delay : 9000 us
16
PAGEL : PD7
17
BS2 : PC2
18
RESET disposition : dedicated
19
RETRY pulse : SCK
20
serial program mode : yes
21
parallel program mode : yes
22
Timeout : 200
23
StabDelay : 100
24
CmdexeDelay : 25
25
SyncLoops : 32
26
ByteDelay : 0
27
PollIndex : 3
28
PollValue : 0x53
29
Memory Detail :
30
31
Block Poll Page Polled
32
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
33
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
34
eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff
35
flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff
36
lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
37
hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
38
efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
39
lock
0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
40
calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
41
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
42
43
Programmer Type : STK500
44
Description : Atmel STK500 Version 1.x firmware
45
Hardware Version: 2
46
Firmware Version: 1.18
47
Topcard : Unknown
48
Vtarget : 0.0 V
49
Varef : 0.0 V
50
Oscillator : Off
51
SCK period : 0.1 us
52
53
avrdude.exe: AVR device initialized and ready to accept instructions
54
55
Ошибка при записи загрузчика.
56
Reading | ################################################## | 100% 0.02s
57
58
avrdude.exe: Device signature = 0x00ff00
59
avrdude.exe: Expected signature
for
ATmega328PB
is
1E 95 16
60
Double check chip, or use -F to
override
this
check.
61
62
avrdude.exe done. Thank you.
63
64
Этот отчёт будет иметь больше информации с
65
включенной опцией Файл -> Настройки ->
66
"Показать подробный вывод во время компиляции"
Charovnik, по логам похоже на то, что вы прошиваете камень под внешний кварц, а с кварцем он у вас не стартует. как подключали кварц, покажите схему
А если не прошивать загрузчик, не менять фьюзы - программатором скетчи в МК заливаются?
Колодка с первого пина по кругу на фото верх ногами
, правда не уверен за кварц посто новый припаял
- обожмите сильнее эти провода ( встречал что китайцы такие плохо обжимают)
- пробуйте другие контроллеры
- попробуйте программатор USBtinyISP ( был случай что только он помог #comment-536135 )

- еще народ сталкивался c проблемами при программировании atmega328PB https://www.avrfreaks.net/forum/programming-atmega328pb-ispenterprogmode-fail?page=all
- самый крайний случай параллельное программирование Fuse doctor ,( на счет как там с -PB незнамо).
А зачем вы стираете бит CFD ???
Charovnik, Мне кажется, что проблемы с прошивкой голых МК в 99% случаев возникают из-за плохих контактов(монтажа). Я например никогда не шью так, как вы -подвесив МК на соплях. Либо сначала припаиваю МК в ту плату, где он будет работать, а потом через разъём ISP прошиваю. Либо припаиваю МК непосредственно на переходник программатора. И всё всегда шьётся без проблем.
я череза arduino ide заливал там все само происходит, посоветуйте может какую программу
avrdude прямо из командной строки.
Вобщем взял ардуину нану с простым 328р залил в нее блинк, снял кварц с наны блинк не работал, снял чип поставил чип и кварц на колодку поставил диод на 13 ногу и резистор 1ком на ресет и 5вольт подал напряжение блинк работает. Подключил поровода isp. Тот же самый блинк скетч заливается загрузка же загрущика не идет. Ошибки типа ff0000 00ff00 0000ff. При этом когда отравляю команду по диоду видно что чип в колодке пытался прерватся
А если не прошивать загрузчик, не менять фьюзы - программатором скетчи в МК заливаются?
Если не прошивать загрузчик, то скетчи программатором загружаются. Но с завода чип настроен на непонятный внешний кварц, толи 16MHz толи 1Mhz. Не столь важно, всё равно не подходит. По этому надо перепрошить. И вот у меня полностью аналогично, как описывает Charovnik.
После первой записи загрузчика - дальше ничего не работало. Правда, я это два года назад делал и разными загрузчиками испортил три атмеги и на этом эксперименты отложил до лучших времён. Сейчас активно использую MiniCore библиотеку. Ею еще не пробовал прошить новые Atmega328PB, а в старые не грузится. Хотя тут пишут, что это может программатор Arduino as ISP не подходит. А USBtinyISP загрузить сможет... попробовать, что-ли...
Для сравнения, Atmega328P прекрасно прошивается. Отличие от в логах от Atmega328PB вот именно в этой строчке:
Но с завода чип настроен на непонятный внешний кварц, толи 16MHz толи 1Mhz.
С завода чип ВСЕГДА настроен на внутренний RC-осциллятор 8МГц с делителем на 8 (т.е. тактовая 1МГц). Если у Вас чип настроен на внешний кварц, значит он уже не с завода. Вам продали б/у чип, в котором менялись фьюзы.
avrdude: Device signature = 0x1e950f (probably m328p)
Почему-то для Atmega328PB оно напрочь разучивается правильно считывать эту сигнатуру.
Если бы были проблемы со считыванием сигнатуры, там были нули: Device signature = 0x000000 или другая билиберда. В данном случае он чётко считывает сигнатуру Atmega328P. Сигнатура для Atmega328PB = 0x1e9516.
Вы уверены, что чип не перемаркировка б/у Atmega328P? Все признаки указывают на это.
"С завода чип ВСЕГДА настроен на внутренний RC-осциллятор 8МГц с делителем на 8 (т.е. тактовая 1МГц). "
Да, где-то про это и написал, что там была другая частота, а не 8MHz, которая нужна тогда была мне.
"Если бы были проблемы со считыванием сигнатуры, там были нули: Device signature = 0x000000".
Да, вот так и есть на микроконтроллерах, которые когда-то "испортил". В зависимости от выбранной частоты кварца там еще ff куда нибудь вписывается. Типа: avrdude.exe: Device signature = 0x00ff00
Загвоздка была, что первый раз то оно прошивалось.
Ради эксперимента, взял только что новый Atmega328PB. Прошил его MiniCore. Прошилось (но первый раз так и с другими загрузчиками было). Загрузил загрузчик второй раз - снова загрузилось! Залил через программатор сектч - работает. Алилуя. Вот она, нормально работающая библиотека для этого микропроцессора. Дело в том, что нашел её только год назад и теперь активно использую. А портил микроконтроллеры PB года два назад. Тогда по ним инфы было маловато.
И в завершение, вот как выглядит успешный лог (не знаю, как его свернуть):
01
avrdude: Version 6.3-20190619
02
Copyright (c) 2000-2005 Brian Dean, <a href=
"http://www.bdmicro.com/"
title=
"http://www.bdmicro.com/"
rel=
"nofollow"
>http://www.bdmicro.com/</a>
03
Copyright (c) 2007-2014 Joerg Wunsch
04
05
System wide configuration file
is
"C:\Users\Aleks\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.0.5/avrdude.conf"
06
07
Using Port : COM3
08
Using Programmer : stk500v1
09
Overriding Baud Rate : 19200
10
AVR Part : ATmega328PB
11
Chip Erase delay : 9000 us
12
PAGEL : PD7
13
BS2 : PC2
14
RESET disposition : dedicated
15
RETRY pulse : SCK
16
serial program mode : yes
17
parallel program mode : yes
18
Timeout : 200
19
StabDelay : 100
20
CmdexeDelay : 25
21
SyncLoops : 32
22
ByteDelay : 0
23
PollIndex : 3
24
PollValue : 0x53
25
Memory Detail :
26
27
Block Poll Page Polled
28
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
29
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
30
eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff
31
flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff
32
lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
33
hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
34
lock
0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
35
calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
36
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
37
efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
38
39
Programmer Type : STK500
40
Description : Atmel STK500 Version 1.x firmware
41
Hardware Version: 2
42
Firmware Version: 1.18
43
Topcard : Unknown
44
Vtarget : 0.0 V
45
Varef : 0.0 V
46
Oscillator : Off
47
SCK period : 0.1 us
48
49
avrdude: AVR device initialized and ready to accept instructions
50
51
Reading | ################################################## | 100% 0.02s
52
53
avrdude: Device signature = 0x1e9516 (probably m328pb)
54
avrdude: NOTE:
"flash"
memory has been specified, an erase cycle will be performed
55
To disable
this
feature, specify the -D option.
56
avrdude: erasing chip
57
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"
58
avrdude: writing flash (32768 bytes):
59
60
Writing | ################################################## | 100% -0.00s
61
62
avrdude: 32768 bytes of flash written
63
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:
64
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:
65
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
66
avrdude: reading on-chip flash data:
67
68
Reading | ################################################## | 100% -0.00s
69
70
avrdude: verifying ...
71
avrdude: 32768 bytes of flash verified
72
avrdude: reading input file
"0x0f"
73
avrdude: writing
lock
(1 bytes):
74
75
Writing | ################################################## | 100% 0.02s
76
77
avrdude: 1 bytes of
lock
written
78
avrdude: verifying
lock
memory against 0x0f:
79
avrdude: load data
lock
data from input file 0x0f:
80
avrdude: input file 0x0f contains 1 bytes
81
avrdude: reading on-chip
lock
data:
82
83
Reading | ################################################## | 100% 0.01s
84
85
avrdude: verifying ...
86
avrdude: 1 bytes of
lock
verified
87
88
avrdude done. Thank you.
Как восстановить неправильно прошитые Atmega328PB - это уже совсем другая история. Люди пишут, что как минимум через Arduino as ISP это не получится.
Я на первой странице тоже менял левый бутлоадер, но только полулой.
Weisnar - это все интересно, но совершенно не отменяет того, что тот чип где у вас читается
avrdude: Device signature = 0x1e950f
- скорее всего перемаркировка.
Вообще , мне кажется что вы как-то очень смутно представляете весь процесс, постоянно путаетесь в рассуждениях, что и как прошивали, что у вас в итоге работает, а что блочится...
По мне так тут все предельно ясно. Когда вы выставляете правильные фьюзы к правильно определенному чипу, верно соединяете провода, правильно выбираете параметры в настройках программатора - все прошивается. А если где-то ошибка - то нет. И не надо никакой магии...
а если у вас был чип с сигнатурой 0x1e950f от обычной 328р , а вы его насильно с параметром -f зашили как 328pb - то понятно, что такое можно сделать только один раз, а потом он блочится
"С завода чип ВСЕГДА настроен на внутренний RC-осциллятор 8МГц с делителем на 8 (т.е. тактовая 1МГц). "
Да, где-то про это и написал, что там была другая частота, а не 8MHz, которая нужна тогда была мне.
Так она и должна быть другая. 8 МГц с делителем на 8 дают тактовую 1МГц. Так и должно быть с завода.
скорее всего перемаркировка.
Согласен с b707.
Сигнатура 0x1e950f НЕ может возникнуть случайным образом в результате ошибки считывания, это исключено.
Это однозначно говорит о том, что прошиваемый чип является Atmega328P, а не Atmega328PB.
а если у вас был чип с сигнатурой 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 уже не выходит. Программатор ругается на отсутствие сигнатуры.
Weisnar - вопрос о том, нафига вообще нужен загрузчик, если вы работаете с голым чипом, да еще и на внутреннем осцилляторе? Заливайте скетчи программатором и не мучайтесь
Нужен ли загрузчик в атмегах вопрос, наверно, больше философский.
Лично мне он подходит по двум причинам:
- добавляет два цифровых пина, которые в заводской прошивке не активны;
- добавляет возможность обновлять скетчи по UART, а на пины 10,11,12,13 обычно припаиваю какой-то радиомодуль.
Тоесть, мне всегда думалось, что загрузчик - штука полезная.
Тем боле, насколько понял, MiniCore использует загрузчик Optiboot, а он в свою очередь совсем не большой размером.
Хотя очень давно экспериментировал, там толи MISO, толи MOSI радиомодуля достаточно через резистор подключить и всё. Он не будет мешать перепрошивке.
Так что... Загрузчики лучше не использовать? Я же написал. Проверил уже на нескольких 328PB. MiniCore нормально заливается и всё работает лучше прежнего.
Кто не знает, Optiboot еще и функцию watchdog восстанавливает. Но она конфликтует с библиотекой LowPower, по этому тут уж кому что нужнее.
Ну какой же бред...