Чип AT91SAM7X (AT91SAM7X128, AT91SAM7X256, AT91SAM7X512) спроектирован для работы от одного источника напряжения, и имеет 6 типов ножек, предназначенных для питания:
• VDDIN. Запитывает регулятор напряжения и ADC. Диапазон напряжения 3.0..3.6V, 3.3V номинал. Для уменьшения энергопотребления, если не используется регулятор напряжения и ADC, ножки VDDIN, ADVREF, AD4, AD5, AD6 и AD7 должны быть соединены с землей (GND), а ножка VDDOUT должна висеть в воздухе. • VDDOUT. Выходное напряжение 1.8V встроенного в чип регулятора напряжения. • VDDIO. Запитывает ножки I/O. Диапазон напряжения 3.0..3.6V, 3.3V номинал. • VDDFLASH. Запитывает приемопередатчик USB и часть узлов flash (требуется для корректной работы flash). Диапазон напряжения 3.0..3.6V, 3.3V номинал. • VDDCORE. Запитывает логику чипа. Диапазон напряжения 1.65..1.95V, 1.8V номинал. Может быть подсоединена напрямую к ножке VDDOUT с применением блокировочного конденсатора. VDDCORE абсолютно необходима для работы чипа, включая встроенную память flash. • VDDPLL. Запитывает тактовый генератор, работающий от кварца, и PLL. Может быть подсоединена напрямую к ножке VDDOUT.
Не предусмотрено отдельных ножек земли для различных входов/выходов питания. Только ножки GND, принадлежащие одной шине, предназначены для кратчайшего соединения с шиной земли системы, где используется чип.
Встроенный стабилизатор в нормальном режиме потребляет ток 100 мкА, в режиме с низким потреблением 25 мкА.
Стандартная схема включения, предусматривающая питание от одного источника (требуется стабилизатор на 3.3 вольт, например LM1117MPX-3.3 или ADP3335-ARM-3.3): Есть и другие варианты подачи питания, см. документацию на сайте atmel.com (см. также здесь).
Режимы пониженного энергопотребления AT91SAM7X256
В статическом режиме по линии VDDCORE потребляется менее 60 мкА, при этом работает только генератор RC, стабилизатор напряжения и узел сброса при включении питания. Если активировать еще и детектор кратковременных провалов, то добавляется 28 мкА. При максимальном быстродействии ток потребления от VDDCORE составляет 90 мА, а от VDDFLASH 10 мА. У меня на тактовой частоте 48 МГц при работе из flash, со включенными (на эти узлы поданы такты) USB, SSC, ADC, TWI, PIO чип потреблял около 30 мА от источника 3.3 V.
Уменьшить энергопотребление можно следующими способами (насколько мне известно): 1. Снизить тактовую частоту (минимальный предел - 500 Гц при работе от внутреннего генератора 32 кГц через делитель на 64). Это делается путем программирования регистра PMC_MCKR. 2. Отключить всю периферию (снять с периферийных устройств тактирование). Это делается записью в регистр PMC_PCDR нужных бит. 3. Отказаться от использования flash (запустить программу в ОЗУ). Это делается присвоением функции атрибута __ramfunc и передаче ей управления. 4. Перевести регулятор напряжения в режим Low-power (или режим Standby). Это делается записью 1 в бит VREG_MR.PSTDBY. 5. Выключить частоту процессора PCK, что переводит его в режим ожидания (idle mode, или STANDBY). Отключается PCK путем записи 1 в бит PMC_SCDR.PCK. Вывести из этого режима может любое прерывание (nIRQ или nFIQ) либо сброс. Поэтому если хотим, чтобы состояние STANDBY сохранялось, нужно запретить все прерывания и оставить только нужные. Например, оставить только прерывание от PIO, к которому подключена клавиатура (чтобы процессор просыпался от нажатий пользователя). Отключаются прерывания путем записи нужных бит в регистр AIC_IDCR. Внимание! Прерывания от PIT запрещаются другим методом - путем сброса бита PITEN в AT91C_PITC_PIMR.
Пример программирования
static u32 uIntState, uClockState;
//-----------------------------------------------------------------------------
/// Переключение MCK (master clock) на частоту 500 Гц.
//-----------------------------------------------------------------------------
void Configure500Hz(void)
{
// Установка медленной тактовой частоты.
AT91C_BASE_PMC -> PMC_MCKR = AT91C_PMC_CSS_SLOW_CLK;
while ((AT91C_BASE_PMC -> PMC_SR & AT91C_PMC_MCKRDY) != AT91C_PMC_MCKRDY);
//AT91C_BASE_PMC -> PMC_MCKR = AT91C_PMC_CSS_SLOW_CLK | AT91C_PMC_PRES_CLK_64;
AT91C_BASE_PMC -> PMC_MCKR = AT91C_PMC_CSS_SLOW_CLK | AT91C_PMC_PRES_CLK;
while ((AT91C_BASE_PMC -> PMC_SR & AT91C_PMC_MCKRDY) != AT91C_PMC_MCKRDY);
// Отмена циклов ожидания (установка 0 wait state).
AT91C_BASE_MC -> MC_FMR = AT91C_MC_FWS_0FWS;
}
//-----------------------------------------------------------------------------
/// Переключение MCK (master clock) на частоту 48 МГц (PLL).
//-----------------------------------------------------------------------------
void Configure48Mhz(void)
{
/* Установка циклов ожидания flash в EFC **********************************/
/* 48MHz = 1 wait state */
#if defined(at91sam7x512)
AT91C_BASE_EFC0 -> EFC_FMR = AT91C_MC_FWS_1FWS;
AT91C_BASE_EFC1 -> EFC_FMR = AT91C_MC_FWS_1FWS;
#elif defined(at91sam7x128) || defined(at91sam7x256)
AT91C_BASE_MC -> MC_FMR = AT91C_MC_FWS_1FWS;
#else
#error No chip definition ?
#endif
/* Инициализация главного генератора ****************************/
AT91C_BASE_PMC -> PMC_MOR = BOARD_OSCOUNT | AT91C_CKGR_MOSCEN;
while (!(AT91C_BASE_PMC -> PMC_SR & AT91C_PMC_MOSCS));
/* Инициализация PLL на 96 МГц (96.109) тактовой частоты USB на 48 МГц */
AT91C_BASE_PMC -> PMC_PLLR = BOARD_USBDIV | BOARD_CKGR_PLL | BOARD_PLLCOUNT
| BOARD_MUL | BOARD_DIV;
while (!(AT91C_BASE_PMC -> PMC_SR & AT91C_PMC_LOCK));
/* Ожидание, пока главная частота будет проинициализирована */
while (!(AT91C_BASE_PMC -> PMC_SR & AT91C_PMC_MCKRDY));
/* Переключение на быструю тактовую частоту **********************/
/* Переключение на медленную тактовую частоту + прескалер */
AT91C_BASE_PMC -> PMC_MCKR = BOARD_PRESCALER;
while (!(AT91C_BASE_PMC -> PMC_SR & AT91C_PMC_MCKRDY));
/* Переключение на быструю тактовую частоту + прескалер */
AT91C_BASE_PMC -> PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;
while (!(AT91C_BASE_PMC -> PMC_SR & AT91C_PMC_MCKRDY));
}
//-----------------------------------------------------------------------------
/// Переход в режим пониженного энергопотребления.
//-----------------------------------------------------------------------------
void GotoPowerSave (void)
{
//отключаем все прерывания, кроме прерывания от клавиатуры
// (она подключена к PIOA)
uIntState = AT91C_BASE_AIC -> AIC_IMR;
AT91C_BASE_AIC -> AIC_IDCR = ~(1 << AT91C_ID_PIOA);
//запрещаем прерывание от PIT
*AT91C_PITC_PIMR &= ~AT91C_PITC_PITEN;
//отключаем тактирование всего, кроме клавиатуры (PIOA)
uClockState = AT91C_BASE_PMC -> PMC_PCSR;
AT91C_BASE_PMC -> PMC_PCDR = ~(1 << AT91C_ID_PIOA);
//переходим на низкую тактовую частоту
Configure500Hz();
//переводим регулятор напряжения в режим STANDBY
*AT91C_VREG_MR = AT91C_VREG_PSTDBY;
//переводим проц в режим IDLE (выключаем частоту процессора PCK)
AT91C_BASE_PMC -> PMC_SCDR = AT91C_PMC_PCK;
}
//-----------------------------------------------------------------------------
/// Восстановление нормального режима энергопотребления.
//-----------------------------------------------------------------------------
void GotoPowerNorm (void)
{
//переводим регулятор напряжения в режим NORMAL
*AT91C_VREG_MR = 0;
//переходим на высокую тактовую частоту
Configure48Mhz();
//восстанавливаем тактирование всего
AT91C_BASE_PMC -> PMC_PCER = uClockState;
//разрешаем прерывание от PIT
*AT91C_PITC_PIMR |= AT91C_PITC_PITEN;
//восстанавливаем работу всех прерываний
AT91C_BASE_AIC -> AIC_IECR = uIntState;
PowerSaveON = false;
}
При переходе в режим IDLE может глючить отладчик SEGGER J-Link (наверное, потому что не тактируется процессор):
[Ссылки]
1. IAR EW ARM: где задаются циклы ожидания (wait state) при работе с flash. 2. Power Management Controller микроконтроллера AT91SAM7X. |