Помогите разобраться с сабжем... первый опыт... Цель: выключить и включить МК одной кнопкой. Например, длинное нажатие - выкл, короткое - вкл. Дано: тини2313V-10PU, на шестой ноге висит кнопка на корпус, на ногах 12-13 (PB0-PB1) пара светодиодов для индикации. Разжевать надо для меня, т.е. для чайника, которому непонятны даже те вещи, которые для некоторых из вас настолько очевидны, что не требуют упоминания. Для меня - требуют Продвигаться попрошу мелкими шажками, чтобы было максимально понятно.
Итак, шаг 1 - учимся выключать в Powerdown Желаемый результат - ток потребления единицы микроампер, как указано в даташите. пишем простой код, по которому МК должен заснуть сразу же после включения:
RESET: ldi r16, low(RAMEND); Main program start out SPL,r16 ; Set Stack Pointer to top of RAM
sei ; enable interrupts
ldi r16, 0b01110000 ; set up MCUCR - sleep mode config out MCUCR,r16 ldi r16, 0b11100000 ; set up external INTs masks out GIMSK,r16 ; for future waking up out EIFR, r16
ldi r16, 0b11111111 ;port B to output (LEDs) out DDRB,r16 ldi r16, 0b11111000 ;port D bit 0..2 to in, 3-6 to out out DDRD,r16
sleep ; go to bed
компилируем, шьем, что видим: после включения ток потребления 0,5 мА.... многовато... при нажатии кнопки до 8 мА - ну, типа прерывание сработало, да? но почему в покое так много? (500 мкА) он, что не спит? а для кого тогда sleep написано? что я делаю не так?
RESET: ldi r16, low(RAMEND); Main program start out SPL,r16 ; Set Stack Pointer to top of RAM
sei ; enable interrupts
Delay: ; задержка на старте ldi R17,0 ldi R18,0 ldi R19,5 Loop: dec R17 brne Loop dec R18 brne Loop dec R19 brne Loop
ldi r16, 0b01110000 ; set up MCUCR - sleep mode config out MCUCR,r16
; ldi r16, 0b11100000 ; set up external INTs masks ; out GIMSK,r16 ; for future waking up ; out EIFR, r16
ldi r16, 0b11111111 ;port B to output (LEDs) out DDRB,r16
ldi r16, 0b11111000 ;port D bit 0..2 to in, 3-6 to out out DDRD,r16
sleep ; go to bed
поведение МК в корне поменялось Старт - сначала 2-3мА, когда задержка кончилась - 0.22 мкА - в точном соответствии даташиту! То есть мы-таки ушли в повердаун зато если нажать кнопку, ток подпрыгивает аж до 46 мА после отпускания законным путем возвращаясь к 0.22 мкА
так, а теперь, внимание, вопрос - чем ему мешали маски прерываний? они не так настроены? а что конкретно не так?
Ах да, совсем забыл. под замес убран и обработчик прерывания.
Утекал лишний ток через порты внешних прерываний. Когда их отключили всё стало нормально. Ткнитесь высокоомным осциллографом на INT0 INT1 в слипе. Какой там уровень? Для слипа и для обшей работы схемы самое страшное VCC/2 (неопределённое) напряжение на входах.
Утекал лишний ток через порты внешних прерываний. Когда их отключили всё стало нормально. Ткнитесь высокоомным осциллографом на INT0 INT1 в слипе. Какой там уровень? Для слипа и для обшей работы схемы самое страшное VCC/2 (неопределённое) напряжение на входах.
Нету такого осциллографа... да и не понимаю я смысл - ведь при замыкании кнопки уровень на INT0 гарантированно уходит в ноль тему ту видел, да не о том она... у меня не стоит проблемы, как уменьшить потребление, у меня стоит проблема как включить и выключить устройство одной кнопкой
Допустим, такой вечный цикл:
Код:
Main: что-то делаем если получена команда на выключение идем на Slp иначе идем на Main
Slp: разрешаем прерывания sleep запрещаем прерывания отправляемся на Main
Казалось бы, принцип ясен, чего уж проще? Но когда начинаешь писать код, получается хрень
можно упростить код:
Код:
Main: сигнал "ща выключусь" разрешаем прерывания sleep запрещаем прерывания сигнал "я включился" пауза отправляемся на Main
.cseg .org 0 rjmp RESET ; Reset Handler .org INT0addr ldi r17, 0b11111111 ; зажигаем светодиод в знак того, что сработало прерывание out PORTB, r17 ldi r16, 0b00000000 ; это для сброса флага "слип разрешен" (при попадании в MCUCR запрещает слип) reti
RESET: ldi r16, low(RAMEND); Main program start out SPL,r16 ; Set Stack Pointer to top of RAM
ldi r16, 0b11111111 ;port B to output (LEDs) out DDRB,r16 ldi r16, 0b01000000 ; set up external INTs masks ; out GIMSK,r16 ; [b][color=#FF0000]очень интересная строка[/color][/b] ; out EIFR, r16
ldi r16, 0b01110000 ; set up MCUCR - sleep mode config
Start: out MCUCR,r16
Delay: ; стартовая задержка ldi R17,0 ldi R18,0 ldi R19,5 Loop: dec R17 brne Loop dec R18 brne Loop dec R19 brne Loop
sei ; enable interrupts sleep ; go to bed rjmp Start
Что получается:
если строка с установкой маски прерываний отсутствует, то МК после стартовой задержки уходит в слип и не возвращается оттуда, прерывание не срабатывает, светодиод не зажигается
если строка с установкой маски прерываний существует, то по нажатию кнопки срабатывает обработчик и светодиод зажигается, но МК не уходит в sleep. Вообще никогда, даже при старте до нажатия кнопки. потребляемый ток не падает ниже 0.5 мА, а это недопустимо.
Вопрос: что опять не так? как совместить одно с другим, чтобы и в слип уходил, и прерывание работало?
.cseg .org 0 rjmp RESET ; Reset Handler .org INT0addr ldi r17, 0b11111111 ; зажигаем светодиод в знак того, что сработало прерывание out PORTB, r17 ldi r16, 0b00000000 ; это для сброса флага "слип разрешен" (при попадании в MCUCR запрещает слип) reti
RESET: ldi r16, low(RAMEND); Main program start out SPL,r16 ; Set Stack Pointer to top of RAM
ldi r16, 0b11111111 ;port B to output (LEDs) out DDRB,r16 ldi r16, 0b01000000 ; set up external INTs masks ; out GIMSK,r16 ; [b][color=#FF0000]очень интересная строка[/color][/b] ; out EIFR, r16
ldi r16, 0b01110000 ; set up MCUCR - sleep mode config
Start: out MCUCR,r16
Delay: ; стартовая задержка ldi R17,0 ldi R18,0 ldi R19,5 Loop: dec R17 brne Loop dec R18 brne Loop dec R19 brne Loop
sei ; enable interrupts sleep ; go to bed rjmp Start
Что получается:
если строка с установкой маски прерываний отсутствует, то МК после стартовой задержки уходит в слип и не возвращается оттуда, прерывание не срабатывает, светодиод не зажигается
если строка с установкой маски прерываний существует, то по нажатию кнопки срабатывает обработчик и светодиод зажигается, но МК не уходит в sleep. Вообще никогда, даже при старте до нажатия кнопки. потребляемый ток не падает ниже 0.5 мА, а это недопустимо.
Вопрос: что опять не так? как совместить одно с другим, чтобы и в слип уходил, и прерывание работало?
А светодиод пробывали гасить? Он ведь в слип режиме светиться как прежде и кушает не меньше.
А светодиод пробывали гасить? Он ведь в слип режиме светиться как прежде и кушает не меньше.
В данном случае проблема в том, что ток потребления ДО зажигания светодиода 0,5 мА - а это много т.е. не уходит в PowerDown после включения, как было без установки GIMSK
Вроде как нашли причину - на шестой ноге висел Clock, отсюда вся кривизна работы Перевесил кнопку на INT1, стало гораздо лучше Отдельное спасибо rlab с канала #ru_embedded а также всем откликнувшимся, и здесь и там
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения