Включение и выключение микроконтроллера одной кнопкой
Приветствую, друзья.
Сегодня мы рассмотрим способ включения и выключения устройства на микроконтроллере посредством электронного ключа и слаботочной кнопки.
При использовании устройств на микроконтроллерах с батарейным питанием используют различные схемы с электронными ключами для экономии энергии батареи.
Так, например, схема, изображенная на рис. 1, отличается тем, что при замыкании кнопки S1 на резисторе R1 возникает падение напряжения, открывающие p-канальный МОП-транзистор VT1.
Питание батареи подается на линейный стабилизатор или понижающий DC-DC преобразователь, вырабатывающие питание для микроконтроллера. Конденсатор С1 заряжается до этого напряжения.
Старт микроконтроллера
Пока нажата кнопка, на вход Reset микроконтроллера подается лог. 0, поэтому он находится в состоянии сброса. После отпускания кнопки сигнал сброса снимается. Напряжение с заряженного конденсатора С1 подается на выводы питания микроконтроллера, и он стартует.
После того, как питание на микроконтроллер подано, он сразу устанавливает на своем выводе PORTX.Y лог. 1, которая открывает n-канальный МОП транзистор VT2. Через открытый транзистор VT2 нижний (по схеме) вывод резистора R2 подключается к общему проводу. При этом падение напряжения на резисторе R1 уменьшается, но его хватает, чтобы транзистор VT1 оставался в открытом состоянии. Резистор R4 держит транзистор VT2 закрытым, когда микроконтроллер обесточен, и кнопка S1 не нажата.
Достоинством данной схемы является то, что в качестве S1 может использоваться миниатюрная слаботочная кнопка.
Повторное нажатие кнопки S1 (когда микроконтроллер включен) генерирует лог. 0 на входе RESET, и микроконтроллер сбрасывается. Однако, так как конденсатор С1 заряжен, при отпускании кнопки микроконтроллер успевает стартовать и выставить на своем выводе PORTX.Y лог. 1.
Иными словами, выключить такую схему кнопкой S1 нельзя. Ее можно выключить только программно.
Выключение микронтроллера
Однако если использовать ту же электрическую схему и вход внешнего прерывания микроконтроллера, можно включить и выключить устройство одной кнопкой и, кроме того, осуществить селекцию времени нажатия кнопки. Это послужит дополнительной защитой от случайного выключения. Сказанное иллюстрирует рис. 2. Используется линейный стабилизатор 78L05, микроконтроллер ATtiny15L и внешнее прерывание INT0.
Теперь выключение происходит только в том случае, если кнопка S1 нажата не менее чем в течение определенного промежутка времени (в данном случае – около 2-х секунд).
Иллюстрация включения и выключения одной кнопкой
Для иллюстрации процесса включения-выключения к выходу PB1 порта PORTB микроконтроллера подключён светодиод HL1. После нажатия кнопки S1 на выходе PB0 порта PORTB устанавливается лог.1, открывающая транзистор VT2. Начинает мигать светодиод HL1 с частотой около 2 Гц (240 мс горит, 240 мс не горит). Для выключения микроконтроллера надо нажать на кнопку S1. При этом светодиод HL1 загорается, переставая мигать, и генерируется внешнее прерывание по спаду фронта на входе PB2 порта PORTB микроконтроллера.
Структурная схема программы изображена на рис.3. В процессе обработки прерывания проверяется факт нажатия кнопки и длительность ее нажатия. Если кнопка нажата менее 2 с, выключения контроллера не происходит, осуществляется возврат из прерывания в основной модуль программы.
Если время нажатия больше двух секунд, на выходах PB0 и PB1 устанавливается лог.0, светодиод индикации гаснет, транзистор VT2 закрывается. Но питание на микроконтроллер продолжает подаваться, если кнопка S1 нажата (и, соответственно, транзистор VT1 открыт). Этот факт следует учитывать в реальных конструкциях.
Для формирования временных промежутков используется встроенный таймер T0 микроконтроллера. Он работает по прерыванию от переполнения и сконфигурирован так, что переполнение происходит примерно раз в 40 миллисекунд.
В качестве источника тактового сигнала используется встроенный RC генератор микроконтроллера (по умолчанию включена частота 1,6 МГц).
Текст программы на ассемблере
;================================
.include «tn15def.inc»
;================================
;Объявления
.def temp = r16 ;временный регистр
.def RegDEL_1 = r17 ;первый регистр задержек
.def RegDEL_2 = r18 ;второй регистр задержек
.def RegDEL_3 = r20 ;третий регистр задержек
.def RegDEL_4 = r19 ;четвертый регистр задержек
.equ Work_LED = PB1 ;выход, управляющий светодиодом
.equ MCU_ON = PB0 ;выход, подхватывающий включение контроллера
.equ MCU_OFF = PB2 ;вход выключения контроллера
.cseg
;================================
;Начало программы
.org 0 rjmp INIT
.org INT0addr rjmp INTERRUPT_0 ;обработа внешнего прерывания INT0
.org OVF0addr rjmp TIMER0_Overflow;обработка прерываний от переполнения таймера Т0
.org 10
;================================
;Инициализация
INIT:
ldi temp,0b00000011 ;PB2 — вход, PB0, PB1 — выходы
out DDRB,temp
ser temp ;подтяжка для входа PB2
out PORTB,temp ;и лог.1 для выходов PB0, PB1 (MCU включен, HL1 зажжен)
ldi temp,1<<PSR0
out SFIOR,temp ;сброс предделителя таймера T0
ldi temp,1<<TOIE0
out TIMSK,temp ;разрешение прерывания от таймера T0
ldi temp,1<<TOV0
out TIFR,temp ;сброс флага переполнения таймера T0
sei ;глобальное разрешение прерываний
ldi temp,1<<CS02
out TCCR0,temp ;запуск таймера T0 с делением на 256
ldi temp,(0<<ISC00|1<<ISC01)
out MCUCR,temp ;прерывание от спада фронта уровня на INT0
ldi temp,1<<INT0
out GIMSK,temp ;разрешение внешнего прерывания INT0 (со входа PB2)
;================================
;Основное тело программы
START:
clr RegDEL_1 ;обнуление регистра задержек
Work_1:
cpi RegDEL_1,6 ;если кнопка не нажата, проверить прошло ли 240 мс
brne Work_1 ;если не прошло, ждать
cbi PORTB,Work_LED ;если прошло, погасить светодиод индикации
clr RegDEL_1 ;и обнулить регистр задержек
Work_2:
cpi RegDEL_1,6 ;если кнопка не нажата, проверить прошло ли 240 мс
brne Work_2 ;если не прошло, ждать
sbi PORTB,Work_LED ;если прошло, зажечь светодиод индикации
clr RegDEL_1 ;и обнулить регистр задержек
rjmp Work_1
;================================
;Обработка внешнего прерывания INT0
INTERRUPT_0:
in temp,SREG ;сохранение регистра состояния SREG
sbi PORTB,Work_LED ;зажечь светодиод индикации
ldi RegDEL_4,40 ;запись константы для задержки 2 с (40 раз по 50 мс)
ldi RegDEL_3,100 ;запись константы для задержки 50 мс (100 раз по 0,5 мс)
Work_4:
ldi RegDEL_2,200 ;запись константы для задержки 0,5 мс
Work_3: ;4 такта по 0,625 мкс х 200 = 500 мкс
nop ;команда длиной 1 такт
subi RegDEL_2,1 ;команда длиной 1 такт
brne Work_3 ;команда длиной 2 такта
subi RegDEL_3,1
brne Work_4
Button_press:
sbic PINB,MCU_OFF ;если кнопка вкл/выкл нажата,
rjmp Int_Out_0
ldi RegDEL_3,100 ;запись константы для задержки 50 мс (100 раз по 0,5 мс)
Work_5: ;4 такта по 0,625 мкс х 200 = 500 мкс
ldi RegDEL_2,200 ;запись константы для задержки 0,5 мс
Work_6:
nop ;команда длиной 1 такт
subi RegDEL_2,1 ;команда длиной 1 такт
brne Work_6 ;команда длиной 2 такта
subi RegDEL_3,1
brne Work_5
subi RegDEL_4,1
cpi RegDEL_4,0
brne Button_press ;если 2 с не прошло, перейти по метке
ldi temp,0<<CS02 ;если 2 с прошло и кнопка вкл/выкл нажата, то
out TCCR0,temp ;остановить таймер T0
clr temp ;погасить светодиод индикации
out PORTB,temp ;и убрать самоблокировку микроконтроллера
Int_Out_0: ;если кнопка вкл/выкл не нажата, просто выйти из прерывания
out SREG,temp ;чтение регистра состояния SREG
reti
;Обработка прерываний от таймера T0
TIMER0_Overflow:
in temp,SREG ;сохранение регистра состояния SREG
inc RegDEL_1 ;инкремент RegDEL_1 — таймер T0 переполнился (прошло около 40 мс)
out SREG,temp ;чтение регистра состояния SREG
reti
;================================
Конец программы
;================================
Можно еще почитать:
какой ток потребляет устройство в ожидании (выкл)?
ТЗ не предусматривало энергосберегающих режимов, поэтому они не реализованы. Но вы подали идею, спасибо.