Есть система, построенная на базе PIC18F4520. В качестве тактового генератора был выбран кварц на частоте 4
Мгц, режим: HS-PLL. К кварцу приделаны 2 конденсатора по 15 пФ.
Чего бы ни выбирать с режимах работы внутренних и внешних генераторах, (Fail-safe clock, two speed
startup, startup timers, watchdog итд.), чего бы ни отключать, система периодически при старте
уходит в глубокий ступор.
Были выявлены следующие "закономерности"
* При выключенном FSCM (Fail-safe clock monitoring), TSS (Two-speed startup) - вне
зависимости от PTMR (Power-up Timer) и WDT, система просто иногда не стартует. Обычно после цикла "
программирование (ICD-2)-> выключение питания (снятие ICD) -> включение питания) первый раз стартует
всегда, а второй раз после включения-выключения - где-то только в 20% случаев.
* При включенном TSS система, в общем, ведёт себя схожим образом, только стартует чаще. А иногда стартует
на частоте примерно раз в 16 ниже (видимо, на встроенном генераторе, который по умолчанию настроен на 1
Мгц). И на основную частоту не переходит.
* При включённом FSCM и TSS система иногда стартует (обычно), иногда не стартует вообще, иногда стартует
на частоте 1 Мгц, иногда - где-то видимо в диапазоне 32 кГц (тоже там такой генератор есть).
* При сбросе по WDT система всегда стартует нормально. Если дёрнуть MCLR - аналогично.
* С добавлением в программе кода защиты от сбоев (приведён ниже), система стала 95% стабильной. Но иногда
всё равно не стартует, и хоть ты тресни.
Что самое неприятное, так это что глюк стал почти невоспроизводим. Вот сегодня я с ним долбался, раз 50
программировал, включал, выключал - и ни разу ни одного сбоя. А понёс девайс на приёмку, так он со
второго раза повесился. А потом опять начал нормально работать.
Я даже посоветовал включить в инструкцию по эксплуатации строчку, мол "если устройство не подаёт признаков
жизни, выдердните его из сети, подождите минуту и включите опять". (после такого перерыва устройство обычно
включалось) Но это как-то несолидно.
Привожу код защиты (на HT-PIC C18)
Код
// функция вызывается из main - в первой строке.
void DeviceInitialize (void)
{
u16 Temp;
// Выражения вроде BitN и xBitN определны как байт с одной единицей или одним нулём соответственно
OSCCON |= Bit4 | Bit5 | Bit6; // Выбираем частоту внутреннего генератора 8 Мгц
while (!OSTS) asm ("\tclrwdt"); // Ожидаем, пока внешний генератор не стабилизируется
OSCCON &= xBit0 & xBit1; // Выбираем режим работы: от основного (внешнего) генератора
// Подозреваю, что эта строка не будет иметь эффекта.
// Проверка, чтобы устройство работало на основной частоте. Иначе - сброс по Watchdog
// Длительность одного цикла декремента: 3 мкс (12 тактов).
// Период таймера устанавливаем около 16 млс (делитель 1:4)
// Получаемая задержка: 12 млс либо гораздо больше, если основной генератор не завёлся.
Temp = 4000;
while (Temp--);
asm ("\tclrwdt");
// Дальнейший код инициализации...
return;
}
void DeviceInitialize (void)
{
u16 Temp;
// Выражения вроде BitN и xBitN определны как байт с одной единицей или одним нулём соответственно
OSCCON |= Bit4 | Bit5 | Bit6; // Выбираем частоту внутреннего генератора 8 Мгц
while (!OSTS) asm ("\tclrwdt"); // Ожидаем, пока внешний генератор не стабилизируется
OSCCON &= xBit0 & xBit1; // Выбираем режим работы: от основного (внешнего) генератора
// Подозреваю, что эта строка не будет иметь эффекта.
// Проверка, чтобы устройство работало на основной частоте. Иначе - сброс по Watchdog
// Длительность одного цикла декремента: 3 мкс (12 тактов).
// Период таймера устанавливаем около 16 млс (делитель 1:4)
// Получаемая задержка: 12 млс либо гораздо больше, если основной генератор не завёлся.
Temp = 4000;
while (Temp--);
asm ("\tclrwdt");
// Дальнейший код инициализации...
return;
}
Ещё стоит заметить, что этот же проект на PIC18F458 работает безо всяких проблем, но это старая версия, в новой мы перешли на 4520.