реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Покритикуйте алгоритм включения и выключения устройства на AVR
aaarrr
сообщение Mar 29 2011, 20:44
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(ILYAUL @ Mar 30 2011, 00:34) *
Как будет написана инициализация MK так и будет выполнятся вне зависимости что ее вызвало, если только не учитываются флаги сброса

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

И сброс как делаете - "JMP 0"?
Go to the top of the page
 
+Quote Post
Atridies
сообщение Mar 29 2011, 20:56
Сообщение #17


Местный
***

Группа: Свой
Сообщений: 445
Регистрация: 7-02-05
Из: Зеленоград
Пользователь №: 2 468



Я не сильно знаю Атмегу, но на MSP430 я делал сброс WD-таймером. Банально в его регистр писал слово с неправильным ключом - он сбрасывался вообще без взвода таймера.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Mar 30 2011, 09:57
Сообщение #18


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(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 как тут предлагали при определённых условиях


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 30 2011, 10:45
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



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

А теперь представьте, что у вас в руках не мелкая AVR'ка, а достаточно приличный контроллер с десятком используемых периферийных блоков, контроллером прерываний и т.п. Тоже будете вручную выбираться из неопределенного состояния после перехода на 0? То что прощается сейчас по причине примитивности контроллера в будущем вылезет изрядными граблями. Лучше изначально использовать правильный подход.
Go to the top of the page
 
+Quote Post
forever_student
сообщение Mar 30 2011, 11:04
Сообщение #20


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 5-04-09
Из: Москва
Пользователь №: 47 180



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

А что мешает в INIT сначала принудительно присвоить регистрам используемой периферии
значения после POWER-UP, а потом инициализировать обычным путем?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 30 2011, 12:32
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



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

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

Определенное состояние всегда следует предпочитать неопределенному, только и всего.
Go to the top of the page
 
+Quote Post
forever_student
сообщение Mar 30 2011, 13:22
Сообщение #22


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 5-04-09
Из: Москва
Пользователь №: 47 180



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

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

Нет, я не всегда так поступаю.
Но в некоторых МК WDT с непрограммируемым таймаутом.
Ждать ...надцать секунд не всегда хорошо, и если МК не висит - такой сброс помогает.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 30 2011, 13:33
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



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

Возможно. Но называть это действие сбросом все-таки нельзя.
Go to the top of the page
 
+Quote Post
forever_student
сообщение Mar 30 2011, 13:45
Сообщение #24


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 5-04-09
Из: Москва
Пользователь №: 47 180



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


ОК. Рестарт sm.gif
Go to the top of the page
 
+Quote Post
defunct
сообщение Mar 30 2011, 13:51
Сообщение #25


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(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)();
}
Go to the top of the page
 
+Quote Post
zheka
сообщение Mar 30 2011, 15:04
Сообщение #26


Гуру
******

Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164



Господа, необходимость железного сброса продиктована прежде всего любовью к порядку. Во-первых, есть еще и периферия, есть куча проинициализированных переменных, eeprom в том числе. А во-вторых - с логической точки зрения - клиент хочет чтобы устройство выключалось, дык пусть оно выключается.

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


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

Сообщение отредактировал zheka - Mar 30 2011, 15:10
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 30 2011, 16:08
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Ну а собственно sleep где?
Go to the top of the page
 
+Quote Post
zheka
сообщение Mar 30 2011, 16:48
Сообщение #28


Гуру
******

Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164



Код
Ну а собственно sleep где?


Да уже исправил. Все ОК. ПРосто никогда не работал раньше с этим режимом.
А еще я никогда не работал с собачьим таймером. Сейчас ковыряюсь, авось все получится.
Go to the top of the page
 
+Quote Post
zheka
сообщение Mar 30 2011, 19:05
Сообщение #29


Гуру
******

Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164



Так... работаю со сторожевым таймером...
Господа объясните мне, если контроллер ушел в 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 секунду в обработчике прерывания от сторожевого таймера нужно проверять некое условие и если оно истинно будить контроллер, если ложно - спать дальше.
Как нужно сделать?
Go to the top of the page
 
+Quote Post
forever_student
сообщение Mar 30 2011, 20:02
Сообщение #30


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 5-04-09
Из: Москва
Пользователь №: 47 180



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

После проверки условия, если оно истинно - ставите флаг.
В основном цикле проверяете флаг. Если есть - работаете, нет - засыпаете.
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 12:03
Рейтинг@Mail.ru


Страница сгенерированна за 0.01518 секунд с 7
ELECTRONIX ©2004-2016