|
|
  |
Покритикуйте алгоритм включения и выключения устройства на AVR |
|
|
|
Mar 30 2011, 09:57
|

Профессионал
    
Группа: Свой
Сообщений: 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 как тут предлагали при определённых условиях
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Mar 30 2011, 11:04
|
Местный
  
Группа: Участник
Сообщений: 256
Регистрация: 5-04-09
Из: Москва
Пользователь №: 47 180

|
Цитата(aaarrr @ Mar 30 2011, 14:45)  ...Логика USART'а сброшена не будет такой инициализацией. Нужно было сначала сбросить RXEN и TXEN в 0, чтобы получить то же состояние, что и после хардварного сброса. То же самое касается SPI и прочих интерфейсов... А что мешает в INIT сначала принудительно присвоить регистрам используемой периферии значения после POWER-UP, а потом инициализировать обычным путем?
|
|
|
|
|
Mar 30 2011, 13:22
|
Местный
  
Группа: Участник
Сообщений: 256
Регистрация: 5-04-09
Из: Москва
Пользователь №: 47 180

|
Цитата(aaarrr @ Mar 30 2011, 16:32)  ...Вы вот всегда так поступаете? И уверены, что сможете просчитать все возможные побочные эффекты?
Определенное состояние всегда следует предпочитать неопределенному, только и всего. Нет, я не всегда так поступаю. Но в некоторых МК WDT с непрограммируемым таймаутом. Ждать ...надцать секунд не всегда хорошо, и если МК не висит - такой сброс помогает.
|
|
|
|
|
Mar 30 2011, 15:04
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Господа, необходимость железного сброса продиктована прежде всего любовью к порядку. Во-первых, есть еще и периферия, есть куча проинициализированных переменных, eeprom в том числе. А во-вторых - с логической точки зрения - клиент хочет чтобы устройство выключалось, дык пусть оно выключается. Ну да ладно. Пока что у меня возникли проблемы со спящим режимом. Код SMCR =(1<<SE)|(1<<SM1); // ВХодим в POwerDown КОнтроллер молча читает эту команду и идет дальше. Может еще что надо? Внимание! В ATMega644p управление спящими режимами возложено на SMCR регистр, в MCUCR другие параметры.
Сообщение отредактировал zheka - Mar 30 2011, 15:10
|
|
|
|
|
Mar 30 2011, 19:05
|
Гуру
     
Группа: Участник
Сообщений: 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 секунду в обработчике прерывания от сторожевого таймера нужно проверять некое условие и если оно истинно будить контроллер, если ложно - спать дальше. Как нужно сделать?
|
|
|
|
|
Mar 30 2011, 20:02
|
Местный
  
Группа: Участник
Сообщений: 256
Регистрация: 5-04-09
Из: Москва
Пользователь №: 47 180

|
Цитата(zheka @ Mar 30 2011, 23:05)  ...Суть в чем - мне нужно усыпить контроллер, но раз в 1 секунду в обработчике прерывания от сторожевого таймера нужно проверять некое условие и если оно истинно будить контроллер, если ложно - спать дальше. Как нужно сделать? После проверки условия, если оно истинно - ставите флаг. В основном цикле проверяете флаг. Если есть - работаете, нет - засыпаете.
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|