Слава оборонцям України. Давно нічого тут не писав, бо зараз в основному працюю з більш сучасними МК. Але от довелося мати діло з MS51FB9AE від Nuvoton. Це трошки покращений (але у чомусь, наприклаклад розмірі Flash - погіршений) послідовник N76E003AT20 від того самого Nuvoton https://www.nuvoton.com/products/microc … 8051-mcus/, який у свою чергу pin-to-pin сумійсний із втратившими популярнійсть STM8S003F3P6/STM8S103F3P6. Я дуже люблю pin-to-pin сумійсні МК, оскільки можна заміняти їх між собою на одній платі, якщо у одному щось не влаштовує з периферії, або він раптом стає важкодоступним. А ще я дуже люблю завантажувачі, які розміщені у Flash-пам'яті МК, і дозволяють оновлювати ПЗ без программатора. Зазвичай, найзручнішим і напростішим варіантом є USB-UART перетворювач (https://arduino.ua/cat167-usb-uart-ttl, не сприймайте як рекламу, просто для розуміня того, як вони виглядають, для людей, які не шарять у цій темі). Для цього МК на сайті виробника доступний Board Support Pakage - MS51_Series_BSP_Keil_V1.00.005.zip (https://www.nuvoton.com/products/microc … &tab=2). У цьому архіві є як сам проект завантажувача, так і вже скомпільовані файли для прошивки. У цьому МК є 2 UART (UART0 і UART1). UART1 виведений на ті самі ніжки МК, що і інтерфейс програмування. Хтось вважає, що це незручно, бо під час налагодлждення ПЗ через програматор-відладчик ми не маємо нормального доступу до інтерфейсу UART. Але мені наприклад зручно один раз прошити МК програматором, а потім весь час його прошивати і мати отладочний вивід по UART на тій самій гребінці пінів. Це і економія місця на текстоліті, і простота розводки/макетування плати. Але виявилось, що готовий файл для прошивки через UART1, при кожній подачі живлення чекає аж 20 секунд замість 2-3 секунд, як на UART0. Зазвичай це неприпустимо довго для вбудованих систем, кожного разу очікувати аж стільки, перед кожним початком роботи. Ну і плюс розмір завантажувача трохи вилазив за 2 Кб, і доводилоося резервувати під нього аж 3 Кб, даремно втрачаючи майже цілий кілобайт. Колега з роботи зібрав мені файл зі зменшеним часом очікування виходу у робочий режим. А далі я пропросив його скинути мені Keil, і почав шукати, де можна зекономити пару байт, щоб влізти у бажані 2048 байт, і нарешті отримати під свої потреби цілих 14 Кб замість 13 (16 Кб базового розміру Flash мінус розмір завантажувача).
Тайванці (острівні китайці) не розчарували. Довго шукати не довелося, друга по рахунку функція налаштовує внутрішній тактовий генератор на частоту 24 МГц, а потім у кінці, при виході із завантажувача, повертаються дефолтні 16 МГц.
Виглядає це як
void main (void)
{
set_CHPCON_IAPEN;
MODIFY_HIRC_24();
... багато коду ...
_APROM:
MODIFY_HIRC_16();
... ще трошки коду, і вихід із завантажувача.
Три перегляді цих фунцій було помічего, що вони відрізняються тільки двома значеннями, які присвоюються регістру IAPAL.
void MODIFY_HIRC_24(void)
{
unsigned char data hircmap0,hircmap1;
/* Check if power on reset, modify HIRC */
// set_CHPCON_IAPEN;
IAPAL = 0x38;
IAPAH = 0x00;
IAPCN = READ_UID;
set_IAPTRG_IAPGO;
hircmap0 = IAPFD;
IAPAL = 0x39;
IAPAH = 0x00;
set_IAPTRG_IAPGO;
hircmap1 = IAPFD;
TA = 0XAA;
TA = 0X55;
RCTRIM0 = hircmap0;
TA = 0XAA;
TA = 0X55;
RCTRIM1 = hircmap1;
// clr_CHPCON_IAPEN;
}
void MODIFY_HIRC_16(void)
{
unsigned char data hircmap0,hircmap1;
// set_CHPCON_IAPEN;
IAPAL = 0x30;
IAPAH = 0x00;
IAPCN = READ_UID;
set_IAPTRG_IAPGO;
hircmap0 = IAPFD;
IAPAL = 0x31;
IAPAH = 0x00;
set_IAPTRG_IAPGO;
hircmap1 = IAPFD;
TA = 0XAA;
TA = 0X55;
RCTRIM0 = hircmap0;
TA = 0XAA;
TA = 0X55;
RCTRIM1 = hircmap1;
// clr_CHPCON_IAPEN;
}
Було вирішено замінити їх на 1 універсальну функцію
typedef enum{
HIRC_16_MHz = 0x30,
HIRC_24_MHz = 0x38
} HIRC_t;
void MODIFY_HIRC(HIRC_t HIRC_type)
{
unsigned char data hircmap0,hircmap1;
/* Check if power on reset, modify HIRC */
// set_CHPCON_IAPEN;
IAPAL = HIRC_type;
IAPAH = 0x00;
IAPCN = READ_UID;
set_IAPTRG_IAPGO;
hircmap0 = IAPFD;
IAPAL = HIRC_type+1;
IAPAH = 0x00;
set_IAPTRG_IAPGO;
hircmap1 = IAPFD;
TA = 0XAA;
TA = 0X55;
RCTRIM0 = hircmap0;
TA = 0XAA;
TA = 0X55;
RCTRIM1 = hircmap1;
// clr_CHPCON_IAPEN;
}
і тепер вона просто визивається 2 рази, із відповідними параметрами:
void main (void)
{
set_CHPCON_IAPEN;
MODIFY_HIRC(HIRC_24_MHz);
... багато коду ...
_APROM:
MODIFY_HIRC(HIRC_16_MHz);
... ще трошки коду, і вихід із завантажувача.
Це дозволило зекономити 72 байти, і з запасом влізти у відведені 2 Кб. Далі я не шукав де ще оптимізувати, бо все одно у 1 Кб завантажувач не влізе (якщо не урізати функціонал).
Ще один косяк тайванців (острівних китайців) виліз у процесі використання софту для прошивки NuMicro_ISP_Programming_Tool_V4.16. Виявилось, що ця версія нормально прошиває МК при використанні GUI, але не працює при використанні командної стрічки. Дослідним шляхом, з допомогою колеги по роботі, у якого вивився набір старих версій цієї програми, було вивлено, що на версії 4.10 ще все працює, а на версіях починаючи з 4.12 працює вже тільки GUI. Тому, хто стикнувся, майте на увазі.
Робіть, і у вас все вийде. Всім некацапам добра.