Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Покритикуйте алгоритм включения и выключения устройства на AVR
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
zheka
Господа, есть некое устройство на АТМега, управляющее TFT-дисплеем с тачпанелью и небольшим набором периферии. Подключено к автомобильному аккумулятору постоянно. А значит нужно предусмотреть включение и выкючение устройства. При всем изяществе конструкции, наличии тачпанели слишком жалко будет смотреться механический переключатель для коммутации. Хочется выключать устройство нажав виртуальную кнопку на тачпанели, а включать простым прикосновением к экрану. А посему возникла такая идея:
Контроллер управляет дисплеем через специальную плату (если кому интересно TFT-компаньон) Эта плата умеет выходить в режим пониженного потребления и понимает в нем только две команды - выход из режима пониженного энергопотребления и опрос тачпанели.
Я планирую по нажатии на виртуальную кнопку на экране переводить его в PowerDown. Затем переводть в PowerDown (именно в этот режим) и сам AVR. Как включать? Предварительно - настроить WatchDog на 1 сек и на генерацию прерывания по переполнению. В прерывании опрашивать тачпанель и если было прикосновение - можно просыпаться. Однако получается следующее - при выключении всего устройства мы его на самом деле не выключаем, а переводим в спящий режим, и при включении оказываемся на том же месте. Хотелось бы перезагрузить и контроллер. А для этого хочу попробовать следующее - если при обработке прерывания от сорожевого таймера выяснится что к тачпанели прикасались - перенастраивать таймер на сброс контроллера и более короткий период (самый короткий 16 мс). После чего ждать следующего переполнения таймера.

Пока не пробовал, идею сочинял на работе, попробую только дома.

Вопросы:
1. Довольно странный алгоритм получился - при выключении устройство на самом деле просто останавливается, а истинная его перезагрузка происходит только при включении. Хотя на самом деле ввсе выглядит благористойно (забыл сказать - в режиме PowerDown TFT компаньон не только меньше жрет, но и подсветку отключает). Может есть какие-то более адекватные истрически сложившиеся алгоритмы?
2. Есть ли какой-то иной способ программного сброса AVR? Цеплять какой-нибудь выход на RESET не предлагайте, плата сделана и детали напаяны.
3. Не происходит ли чего нехорошего с портами ввода вывода в режиме PowerDown АВР? Нужно чтобы пины оставались в том же состоянии.
Спасибо.
forever_student
Цитата(zheka @ Mar 29 2011, 13:21) *
...
2. Есть ли какой-то иной способ программного сброса AVR? Цеплять какой-нибудь выход на RESET не предлагайте, плата сделана и детали напаяны.
3. Не происходит ли чего нехорошего с портами ввода вывода в режиме PowerDown АВР? Нужно чтобы пины оставались в том же состоянии.
...

2.
.ORG 0x00
RESET:
.
.
.
.
JMP RESET

3. Пины останутся в том же состоянии
zheka
Извните, ассемблера не знаю. Пишу на С.
Но даже глядя на то, что вы написали - это просто уловка для перемещения программы в начало, а не сброс.

forever_student
Цитата(zheka @ Mar 29 2011, 14:38) *
Извните, ассемблера не знаю. Пишу на С.
Но даже глядя на то, что вы написали - это просто уловка для перемещения программы в начало, а не сброс.


Если Вам нужно перезагрузить МК после выхода из Powerdown - "уловка" поможет.
Если перезагрузить зависший МК - альтернативы WDT не вижу.
zheka
Спасибо за совет, но я все же предпочту для перезагрузки WDT. К тому же, внимательно почитав еще раз даташит я убедился, что это единственное самостоятельное внутреннее средство сброса контроллера.
_Pasha
Дык все тривиально, не о чем переживать. Первый пост правильный
SysRq
Теоретически, можно перезагрузить МК тоже. На старте уснуть или работать решить по флагам MCUCSR (WDRF, PORF, BORF...).
Marian
Цитата(zheka @ Mar 29 2011, 11:21) *
Однако получается следующее - при выключении всего устройства мы его на самом деле не выключаем, а переводим в спящий режим, и при включении оказываемся на том же месте. Хотелось бы перезагрузить и контроллер.

Объясните необходимость сброса проца.
По идее перезагрузка не нужна, если проц. повиснит его сбросит вачдог.
Для надежности поставьте внешний супервизор по питанию.
Если все же видите необходимость повысить надежность, после выхода из сна(при касании тачскрина) запустите принудительную инициализацию важных данных.
Хотя самый простой метод "JMP 0"
coolbassnik
Есть идея заставить МК ресетить самого себя железно. Для этого любой вывод порта МК подключаем к ресет в Hi-Z состоянии, и когда нужно ресетить, то выводим на этот пин лог. 0. МК по идее должен перезагрузится, и состояние портов - сбросится.
_Pasha
Цитата(coolbassnik @ Mar 29 2011, 20:30) *
Есть идея заставить МК ресетить самого себя железно. Для этого любой вывод порта МК подключаем к ресет в Hi-Z состоянии, и когда нужно ресетить, то выводим на этот пин лог. 0. МК по идее должен перезагрузится, и состояние портов - сбросится.

А Вы почитайте доки, можно ли так Ымбеддить, а потом пишите. или хоть попробуйте разок.
IgorKossak
Цитата(coolbassnik @ Mar 29 2011, 20:30) *
Есть идея заставить МК ресетить самого себя железно. Для этого любой вывод порта МК подключаем к ресет в Hi-Z состоянии, и когда нужно ресетить, то выводим на этот пин лог. 0. МК по идее должен перезагрузится, и состояние портов - сбросится.

Это только по идее. Длительности сигнала сброса может не хватить для надёжного сброса внутренней периферии.
См. в описании Minimum pulse width on RESET Pin.
ILYAUL
Цитата(zheka @ Mar 29 2011, 14:38) *
Но даже глядя на то, что вы написали - это просто уловка для перемещения программы в начало, а не сброс.

Интересно , а что Вы понимаете под сбросом? Или Вы считаете что
Цитата
.... но я все же предпочту для перезагрузки WDT
перемещает программу куда то вдругое место ,а не на 0x0000
aaarrr
Цитата(ILYAUL @ Mar 29 2011, 22:27) *
Интересно , а что Вы понимаете под сбросом? Или Вы считаете что перемещает программу куда то вдругое место ,а не на 0x0000

Помимо программы и ее непосредственного исполнителя у МК как бы существует еще периферия.
zombi
Цитата(zheka @ Mar 29 2011, 13:21) *
Предварительно - настроить WatchDog на 1 сек и на генерацию прерывания по переполнению. В прерывании опрашивать тачпанель и если было прикосновение - можно просыпаться. Однако получается следующее - при выключении всего устройства мы его на самом деле не выключаем, а переводим в спящий режим, и при включении оказываемся на том же месте. Хотелось бы перезагрузить и контроллер. А для этого хочу попробовать следующее - если при обработке прерывания от сорожевого таймера выяснится что к тачпанели прикасались - перенастраивать таймер на сброс контроллера и более короткий период (самый короткий 16 мс). После чего ждать следующего переполнения таймера.

По моему это самый верный способ если необходим именно аппаратный сброс.
Но я не понимаю чем вызвана такая необходимость wacko.gif
ILYAUL
Цитата(aaarrr @ Mar 30 2011, 00:05) *
Помимо программы и ее непосредственного исполнителя у МК как бы существует еще периферия.

Да и ещё SRAM и регистры тоже бы не помешало "почистить" при запуске, но это всё делается только программным путём. Я говорю про инит процессора и он начинается с 0x0000.
Как будет написана инициализация MK так и будет выполнятся вне зависимости что ее вызвало, если только не учитываются флаги сброса
aaarrr
Цитата(ILYAUL @ Mar 30 2011, 00:34) *
Как будет написана инициализация MK так и будет выполнятся вне зависимости что ее вызвало, если только не учитываются флаги сброса

Скажите, а как вы инициализируете USART, например?

И сброс как делаете - "JMP 0"?
Atridies
Я не сильно знаю Атмегу, но на MSP430 я делал сброс WD-таймером. Банально в его регистр писал слово с неправильным ключом - он сбрасывался вообще без взвода таймера.
ILYAUL
Цитата(aaarrr @ Mar 30 2011, 00:44) *
Скажите, а как вы инициализируете USART, например?

И сброс как делаете - "JMP 0"?

Да так же как и все. Ниже пример
Код
;/    ***********************
;/    *                     *
;/    *     ATMega48P        *
;/    *   Jig for Hotel     *
;/    *                     *
;/    ***********************
;+ Version 1.0
.nolist
.include "m48def.inc"
.list
.listmac
.include "macros_Jig.asm"
.include "JigHotelTV.inc"    
;*************************************************
;*     ;;/ Определение командного сегмента;;*             *
;**************************************************
        .cseg
        .org 0
;*************************************************
;*     ;;/Initialization прерываний;;*            *
;*************************************************
        rjmp RESET; Reset Handler
;        rjmp EXT_INT0; IRQ0 Handler
;        rjmp EXT_INT1; IRQ1 Handler
;        rjmp PCINT0; PCINT0 Handler
;        rjmp PCINT1; PCINT1 Handler
;        rjmp PCINT2; PCINT2 Handler
;        rjmp WDT; Watchdog Timer Handler
;        rjmp TIM2_COMPA; Timer2 Compare A Handler
;        rjmp TIM2_COMPB; Timer2 Compare B Handler
;        rjmp TIM2_OVF; Timer2 Overflow Handler
;        rjmp TIM1_CAPT; Timer1 Capture Handler
;        rjmp TIM1_COMPA; Timer1 Compare A Handler
;        rjmp TIM1_COMPB; Timer1 Compare B Handler
;        rjmp TIM1_OVF; Timer1 Overflow Handler
;        rjmp TIM0_COMPA; Timer0 Compare A Handler
;        rjmp TIM0_COMPB; Timer0 Compare B Handler
;        rjmp TIM0_OVF; Timer0 Overflow Handler
;        rjmp SPI_STC; SPI Transfer Complete Handler
.org    URXCaddr
        rjmp USARTRXC        ; USART, RX Complete Handler
        rjmp USARTUDRE        ; USART, UDR Empty Handler
;        rjmp USART_TXC; USART, TX Complete Handler
;        rjmp ADC; ADC Conversion Complete
;        rjmp EE_RDY; EEPROM Ready Handler
;        rjmp ANA_COMP; Analog Comparator Handler
;        rjmp TWI; 2-wire Serial Interface
;        rjmp SPM_RDY; Store Program Memory Ready
;|                    KOOL                            
        .include    "Delays.asm"
        .include    "LCD.asm"
        .include    "USART.asm"
        .include    "JIGKeyBoard.asm"
;*************************************************
;*  ;;/Установка стека и Очитска регистров;;*   *
;*************************************************
RESET:
        cli                         ; запрет всех прерываний
        ldi        temp,$80           ; Запрещаем работу
        out        ACSR,temp; компаратора
        .include "1Init_MCU.asm"            ; Очистка памяти и всех регистров
            
;**************************************************
;*         ;;/Initialization PORTS;;*                  *
;**************************************************
        ldi        temp,0b_0000_1111
        out        DDRD,temp        ; ПортD старшие вход Младшие -выход    
        ldi        temp,0b_1111_1111
        out        PORTD,temp        ;- На старшие-(1), младшие RX0&RX1-подключены
        ldi        temp,0b_1110_1111
        out        DDRB,temp        ; ПортB старшие PB7-PB5,PB2-PB0 OUTputs, PB4 Input            
        ldi        temp,0b_1111_1111
        out        PORTB,temp        ;- Pull resistor down
;**************************************************
;*            ;;/Initialization LCD;;*              *
;**************************************************

        rcall    LCD_INIT        ;- Инициализация LCD

;**************************************************
;*        ;;/Initialization USARTs;;*              *
;**************************************************
            ;- INIT USART0
        ldi        temp,(SYSCLK/(16*USARTSPEED))-1
        sts        UBRR0L,temp
        ldi        temp,1<<RXCIE0|0<<UDRIE0|1<<RXEN0|0<<TXEN0
        sts        UCSR0B,temp
        ldi        temp,1<<USBS0|1<<UCSZ01|1<<UCSZ00
        sts        UCSR0C,temp
;+ Speed USART0 9600, 8-bit data, 1 STOP


Ну и какая будет разница в инит по POWER UP, WDT , внешний сброс или из MAIN rjmp RESET как тут предлагали при определённых условиях
aaarrr
Вот и попались. Логика USART'а сброшена не будет такой инициализацией. Нужно было сначала сбросить RXEN и TXEN в 0, чтобы получить то же состояние, что и после хардварного сброса. То же самое касается SPI и прочих интерфейсов.
А перед "JMP 0" нужно как минимум запретить прерывания.

А теперь представьте, что у вас в руках не мелкая AVR'ка, а достаточно приличный контроллер с десятком используемых периферийных блоков, контроллером прерываний и т.п. Тоже будете вручную выбираться из неопределенного состояния после перехода на 0? То что прощается сейчас по причине примитивности контроллера в будущем вылезет изрядными граблями. Лучше изначально использовать правильный подход.
forever_student
Цитата(aaarrr @ Mar 30 2011, 14:45) *
...Логика USART'а сброшена не будет такой инициализацией. Нужно было сначала сбросить RXEN и TXEN в 0, чтобы получить то же состояние, что и после хардварного сброса. То же самое касается SPI и прочих интерфейсов...

А что мешает в INIT сначала принудительно присвоить регистрам используемой периферии
значения после POWER-UP, а потом инициализировать обычным путем?
aaarrr
Цитата(forever_student @ Mar 30 2011, 15:04) *
А что мешает в INIT сначала принудительно присвоить регистрам используемой периферии
значения после POWER-UP, а потом инициализировать обычным путем?

Ничто не мешает, только это далеко не всегда эквивалентно сбросу.
Вы вот всегда так поступаете? И уверены, что сможете просчитать все возможные побочные эффекты?

Определенное состояние всегда следует предпочитать неопределенному, только и всего.
forever_student
Цитата(aaarrr @ Mar 30 2011, 16:32) *
...Вы вот всегда так поступаете? И уверены, что сможете просчитать все возможные побочные эффекты?

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

Нет, я не всегда так поступаю.
Но в некоторых МК WDT с непрограммируемым таймаутом.
Ждать ...надцать секунд не всегда хорошо, и если МК не висит - такой сброс помогает.
aaarrr
Цитата(forever_student @ Mar 30 2011, 17:22) *
Но в некоторых МК WDT с непрограммируемым таймаутом.
Ждать ...надцать секунд не всегда хорошо, и если МК не висит - такой сброс помогает.

Возможно. Но называть это действие сбросом все-таки нельзя.
forever_student
Цитата(aaarrr @ Mar 30 2011, 17:33) *
Возможно. Но называть это действие сбросом все-таки нельзя.


ОК. Рестарт sm.gif
defunct
Цитата(aaarrr @ Mar 30 2011, 12:45) *
Тоже будете вручную выбираться из неопределенного состояния после перехода на 0? То что прощается сейчас по причине примитивности контроллера в будущем вылезет изрядными граблями. Лучше изначально использовать правильный подход.

Иногда просто нет другого выхода кроме как выбираться вручную. Но лучше это сделать до перехода на 0.
Код
/***********************************************
* RunApplication()                             *
*    This routine shuts-off peripherals used   *
* by the bootloader and performs jump to 0x0   *
* address                                      *
*                                              *
***********************************************/
void RunApplication(U8 PrintMsg)
{
    V32 tmp = 500000;
    if (PrintMsg)
        pgm_print("trying to run application...\n");
    
    if (brmContext.iapActivityDetected)
    {
        // try to confirm that CRC still OK
        iap_Finalize(); // make sure all flash operations are completed and RWW re-enabled
        brmContext.appSectionCRC = iap_CheckCRC();
        brmContext.iapActivityDetected = FALSE;
    }

    if (brmContext.appSectionCRC)
    {  
        // CRC changed (section corrupted)
        if(PrintMsg)
            pgm_print("app section CRC error detected, cant leave BRM\n");
        return;
    }

    while(tmp--);

    cli(); // disabale interrupts

    // stop timers
    ETIMSK = 0; // disable Extended timers int sources
    TIMSK  = 0; // disable timers int sources

    TCCR3B = 0; // stop timer3
    TCCR2  = 0; // stop timer2
    TCCR1B = 0; // stop timer1
    TCCR0  = 0; // stop timer0

    // stop uarts
    UCSR1B = 0; // stop UART1
    UCSR0B = 0; // stop UART0

    // stop SPIs
    SPCR   = 0; // stop SPI0

    // stop TWI bus
    TWCR   = 0; // stop TWI module
        
    // reset used ports
    DDRF   = 0;
    PORTF  = 0;
    
    DDRE   = 0;
    PORTE  = 0;
    
    DDRB   = 0;
    PORTB  = 0;

    // switch interrupt vector table to app section
    MCUCR = (1 << IVCE);
    MCUCR = (0 << IVSEL);

    // jump to zero address
    ((void(*)(void))0x0)();
}
zheka
Господа, необходимость железного сброса продиктована прежде всего любовью к порядку. Во-первых, есть еще и периферия, есть куча проинициализированных переменных, eeprom в том числе. А во-вторых - с логической точки зрения - клиент хочет чтобы устройство выключалось, дык пусть оно выключается.

Ну да ладно. Пока что у меня возникли проблемы со спящим режимом.
Код
SMCR =(1<<SE)|(1<<SM1); // ВХодим в POwerDown


КОнтроллер молча читает эту команду и идет дальше. Может еще что надо?
Внимание! В ATMega644p управление спящими режимами возложено на SMCR регистр, в MCUCR другие параметры.
aaarrr
Ну а собственно sleep где?
zheka
Код
Ну а собственно sleep где?


Да уже исправил. Все ОК. ПРосто никогда не работал раньше с этим режимом.
А еще я никогда не работал с собачьим таймером. Сейчас ковыряюсь, авось все получится.
zheka
Так... работаю со сторожевым таймером...
Господа объясните мне, если контроллер ушел в PowerDown, а собачий таймер настроен на генерацию прерывания, то что происходит при его переполнении? Он будит контроллер только для того чтобы обработать прерывание и усыпляет его дальше? Или же нужно усыплять контроллер в конце обработчика прерывания от таймера

У меня примерно такой код:
Код
interrupt [WDT] void wdt_timeout_isr(void)
   {
    
//Check();
  //            #asm("SLEEP");  
   }


////////////////

if (ButtonNumber==255)
  {
   while ((x!=0)&&(y!=0)) {GetTouchStat(touch_x,touch_y);}   // При нажатии на виртуальную кнопку на дисплее запускается таймер
     #asm("cli");
#pragma optsize-
#asm("wdr")
WDTCSR |= (1<<WDCE) | (1<<WDE);
/* Set new prescaler(time-out) value = 64K cycles (~0.5 s) */
WDTCSR = (1<<WDIE) | (1<<WDP2) | (1<<WDP1);
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
    
#asm("sei");  

     SMCR =(1<<SE)|(1<<SM1);   //А затем усыпляем контроллер в PowerDOwn
     #asm("SLEEP");    

//    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0); // Настройка SPI


  }

}


Так вот - если в обработчике сторожевого таймера не усыплять контроллер, то основной цикл программы работает, и функция Check() срабатывает раз в 1 секунду.
Если же убрать комментарий в обработчике, т.е. усыплять контроллер по окончании обработки - функция Check() срабатывает лишь однажды - видимо усыпление контроллера не позволяет выйти из обработчика...

Суть в чем - мне нужно усыпить контроллер, но раз в 1 секунду в обработчике прерывания от сторожевого таймера нужно проверять некое условие и если оно истинно будить контроллер, если ложно - спать дальше.
Как нужно сделать?
forever_student
Цитата(zheka @ Mar 30 2011, 23:05) *
...Суть в чем - мне нужно усыпить контроллер, но раз в 1 секунду в обработчике прерывания от сторожевого таймера нужно проверять некое условие и если оно истинно будить контроллер, если ложно - спать дальше.
Как нужно сделать?

После проверки условия, если оно истинно - ставите флаг.
В основном цикле проверяете флаг. Если есть - работаете, нет - засыпаете.
ILYAUL
Цитата(aaarrr @ Mar 30 2011, 14:45) *
Логика USART'а сброшена не будет такой инициализацией. Нужно было сначала сбросить RXEN и TXEN в 0, чтобы получить то же состояние, что и после хардварного сброса.

Не понимаю , а зачем мне логика USART , которая у меня по-сути была , если наступили условия при которых я делаю программный сброс . Ну был включён у меня передатчик и что с того - условия наступили перезапускается вся система.
Вы представьте задачку с МЕНЮ , в котором Вы можете вкл. и выкл. устройства и Вы отключили USART совсем, для новых условий задачи он Вам не нужен т.е при программном сбросе - Вы пропишите в него 000 чтобы не мешал. Я не вижу смыла записать сначала 000 USART, а затем ещё раз записать в него же необходимые числа , если преполагается использование USART
aaarrr
Цитата(ILYAUL @ Mar 31 2011, 15:38) *
Не понимаю , а зачем мне логика USART , которая у меня по-сути была , если наступили условия при которых я делаю программный сброс . Ну был включён у меня передатчик и что с того - условия наступили перезапускается вся система.

Только вот после "сброса" приемный регистр может содержать старые данные, и после разрешения приема вы тут же их получите. А оно надо?
С каким-нибудь SPI может быть то же самое - SPIF в "1", первый обмен будет испорчен.

Цитата(ILYAUL @ Mar 31 2011, 15:38) *
Вы представьте задачку с МЕНЮ , в котором Вы можете вкл. и выкл. устройства и Вы отключили USART совсем, для новых условий задачи он Вам не нужен т.е при программном сбросе - Вы пропишите в него 000 чтобы не мешал.

Это о чем? Давайте не будем придумывать меню и другие избыточные сущности в контексте обсуждения проблемы программного сброса.

Цитата(ILYAUL @ Mar 31 2011, 15:38) *
Я не вижу смыла записать сначала 000 USART, а затем ещё раз записать в него же необходимые числа , если преполагается использование USART

А он есть.
ILYAUL
Цитата(aaarrr @ Mar 31 2011, 15:54) *
Только вот после "сброса" приемный регистр может содержать старые данные, и после разрешения приема вы тут же их получите. А оно надо?
С каким-нибудь SPI может быть то же самое - SPIF в "1", первый обмен будет испорчен.

Да , спасибо. Запомню
zheka
Хм.. я обошелся вообще без флажка для WDT. В смысле, флажки есть, но они не относятся к WDT, а в обработчике прерывания WDT вообще пусто. Т.Е. прерывание генрируется, выполняется единственно важная функция - выход из спящего режима. А вот уже по выходу в основной цикл проверяется условие.

КРоме того, я таки сделал более человчно: при старте у меня контроллер усыпляет дисплей и засыпает сам, просыпаясь чтобы проверить тачпанель. А вот при выключеии запускается сторожевой таймер, который при переполнении ресетит контроллер. Пока вроде все работает.
ILYAUL
Цитата(zheka @ Mar 31 2011, 16:56) *
КРоме того, я таки сделал более человчно: при старте у меня контроллер усыпляет дисплей и засыпает сам, просыпаясь чтобы проверить тачпанель. А вот при выключеии запускается сторожевой таймер, который при переполнении ресетит контроллер. Пока вроде все работает.

Это как , при старте засыпает?
defunct
Цитата(ILYAUL @ Mar 31 2011, 16:02) *
Это как , при старте засыпает?

Наверно чтобы подключить девайс к питанию - и он сразу в sleep, зато если провести пальцем по таблу - он тут же проявит признаки жизни.
ILYAUL
Цитата(defunct @ Mar 31 2011, 20:36) *
Наверно чтобы подключить девайс к питанию - и он сразу в sleep, зато если провести пальцем по таблу - он тут же проявит признаки жизни.

И что получается опрос 1 раз в сек, а если я секунду палец не держал , то и касания не было т.к. дисплей тоже спит
zheka
defunct, именно так.
Дело в том, что питание будет подаваться при подсоедниении к клеммам аккумулятора - а это всерьез и надолго. Выключения и включения физической коммутацией нет, обесточивания при выключении питания не будет. в этом и задумка. Подключили к аккумулятору - нужно еще и на панельку нажать. А далее - нажал кнопку выключения - заработал сторожевой таймер и сбросил контроллер, контроллер стартовал и, ничего не включая сразу в режим сна, просыпаясь раз в секунду, дабы узнать не давит ли кто на тачпанель. Если да - то дальше по тексту программы. Выглядит это все как включение и выключение от тачпанели.

ILYAUL, а что вам не понравилось? У вас мобильник от простого нажатия кнопки включается? Правильно, нет, подержать нужно. По этому принципу работают многие современные устройства. К тому же сенсорная панель - это одна большая кнопка, сам бог велел защитить ее от случайного касания.
Есть другой минус - человеческие рефлексы. Челове должне привыкнуть, что прикасаться нужно в течение секунды, однако возможны варианты, когда влючение произойдет практически сразу после нажатия (в зависимости от текущего состояния таймера) И вот это будет раздражать. Как это поправить - мыслей нет. МОжно конечно настроить на 16 мс, а потом просто ждать секунду, но тогда теряется смысл засыпаний - опрос тачпанели занимает 1 мс, еще какое -то время на танцы вокруг этого опроса, соотношение рабочего и спящего режимов получается невелико...

Выглядит это так:
Код
   StartUP();
   PowerDown();
   delay_ms(3);

//  SetBackLight(0);

    #asm("cli");
    #pragma optsize-
    #asm("wdr")
    WDTCSR |= (1<<WDCE) | (1<<WDE);
    WDTCSR = (1<<WDIE) | (1<<WDP2) | (1<<WDP1);
    #ifdef _OPTIMIZE_SIZE_
    #pragma optsize+
    #endif
    #asm("sei");  
        
     SMCR =(1<<SE)|(1<<SM1);            
     sleep_flag=1;
     #asm("SLEEP")
    
     SPCR_tmp=SPCR;
     SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0); // Настройка SPI
     while(sleep_flag)
     {
      GetTouchStat(touch_x,touch_y);
      if ((x==0)||(y==0)) {sleep_flag=1; #asm("SLEEP");} else sleep_flag=0;
     }    
  
   PowerUp();
   delay_ms(10);
   SPCR=SPCR_tmp;


Повторюсь - в обработчике прерывания то собачьего таймера ничего нет, он просто лает на контроллер и тот просыпается от страха.
ILYAUL
Может 0,5 сек опрос
zombi
Цитата(zheka @ Mar 31 2011, 16:56) *
КРоме того, я таки сделал более человчно: при старте у меня контроллер усыпляет дисплей и засыпает сам, просыпаясь чтобы проверить тачпанель. А вот при выключеии запускается сторожевой таймер, который при переполнении ресетит контроллер. Пока вроде все работает.

Вроде правильно все, только перед засыпанием после первого включения надобы WDT разрешить biggrin.gif
zheka
Так ведь он разрешен или я чего-то не понимаю...
В любом случае - работает и я доволен.
zombi
Цитата(zheka @ Apr 1 2011, 10:02) *
Так ведь он разрешен или я чего-то не понимаю...

Да, если фуз WDTON запрограммирован.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.