Я решил написать программу для автоматического закрытия двери в блок общежития после 24:00 микроконтроллером.
Собственно столкнулся я огромным количеством подводных камней, и так как статей для того чтобы убрать камни я не нашел, а только методом научного тыка и статей на заграничных сайтах дошел до правильных действий, которые вам сейчас и опишу. Сами механизмы работы я описывать не буду. Ничего там сложного. Самое по моему мнению сложное для меня как новичка будет описано в этой статье.
Задание : Сделать асинхронные часы, которые будут работать от одной батарейки типа CR2032 при том что МК должен спать сладким сном и не кушать дорогую для нас силу тока, и когда наступает 0:00 микроконтроллер просыпался менял состояние ножки (подавал импульс единицу и ставил в ноль чтобы эл. замок провернулся) и в 6:00 утра обратно открывал, и ложился спать. Часы при этом работать должны были не отставая не на одну долисекунду. Представьте последствия этого если механизм будет работать годами, можно будет и утром не выйти на улицу.
Итак приступим. У меня есть МК Atmega16a-pu (собственно почти не отличается от Atmega16) и с помощью него вся схема будет управляться. Для того чтобы включить асинхронный режим нужен не только программный код, но и купленный на радиорынке Кварцевый резонатор на 32 768 Гц у меня он типа “спичка”, можете купить любой его тип. Нужно подключить его к пинам 28 и 29 по даташиту.
Так-же я обозначил пины 12 и 13, для большей стабильности к ним можно подключить кварц на 4 Мгц. И выставить фьюзы на внешней RC генератор, но это по вашему вкусу и надобности. Но то что схема станет стабильнее и правильнее это точно.
Ну и вроде-бы все что по технической части. Переходим к программе.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
/* * GccApplication1.cpp * * Created: 24.01.2022 15:39:08 * Author: Sokol */ #define F_CPU 1000000 // внутри МК процессор работает с частотой 1 мГц что равно 1 000 000 Гц. Указываем это, но не обязательно. #include <avr/io.h> //стандартная библиотека мк. #include <avr/sleep.h> //подключаем библиотеку сна #include <avr/delay.h> //подключаем задержки #include <avr/interrupt.h> //подключаем прерывания #define SLEEP_MODE_PWR_SAVE (_BV(SM0) | _BV(SM1)) //Заменяем фразу SLEEP_MODE_PWR_SAVE на (_BV(SM0) | _BV(SM1)) , чтобы потом было легче. volatile unsigned char second=0, minute=0, hour=0; //Инициализируем переменные ISR(TIMER2_COMP_vect) //Описываем вектор для нашего асинхронного прерывания (что будет выполняться кварцем.) { second++; if (second == 60) { PORTA = 0x01; //Выставляем в логическую единицу на пин 0. sleep_disable(); // Когда пройдет одна минута прерывание так сказать ущепнет МК, и он проснется сам ! (питание будет в районе 1 мА) second=0; minute++; if (minute==60) { minute=0; hour++; if (hour==24) { hour=0; } } } } int main(void) { DDRA = 0x01; asm("cli"); //Обязательно запрещаем прерывания //Стандартная постановка битов в МК для активации ухода в Асинхронный режим. ASSR |=(1<<AS2); while(ASSR != (0b00001000)) { asm("nop"); } TCCR2 |= (1<<CS21)|(1<<CS22)|(1<<WGM21); OCR2 = 127; TIMSK |= (1<<OCIE2); TIFR = 0; //Постановку окончили. (более детально про установку в асинхрон. можно найти в Даташите.) set_sleep_mode(SLEEP_MODE_PWR_SAVE); //Выбираем тип сна, в нашем случае это будет Power-Saver. sleep_enable(); //Выставляем соответствующие биты в МК. asm("sei"); //Разрешаем прерывания. Обязательно! _delay_ms(1000); //Делаем задержку для того чтобы Кварцевый резонатор (часовой) 32 768 Гц включился в асинхрон.режим. Это обязательно !. Число может быть и 500. Но я выбрал именно одну секунду. Для стабильности. while(1) { for(int a=0; a < 500; a++) // Тут все на ваше усмотрение что сделать до того как МК уйдет в сон. { asm ("nop"); } PORTA = 0x00; //Выставляем пин в логический ноль, чтобы лампочка один раз мигнула когда выйдет из сна if (second == 2) //Когда будет 2 секунды уйдем в сон. { sleep_cpu(); // Уход в сон. Снижение потребления энергии у меня не превышает 35 мкА (микро а не мили, не путать). } } } |
Такими действиями мы добились мизерного потребления электричества, по моим расчетам одна батарейка 220mA СR2032 будет работать один год без замены и подзарядки. Если подключить другой источник питания, например две пальчиковых батарейки, с 2500 мА то сами можете представить сколько схема будет работать
В моем коде программы все описано так, чтобы вы видели когда он вышел из сна. Сигнал подается не в 24:00 и 6:00, а так чтобы вам было все наглядно видно. Что-бы изменить программу и сделать ее полностью работоспособной нужно чуть-чуть подправить код. Но думаю вам это не составит труда.
Удачи ! Надеюсь я вам помог !
Использовались в работе: Atmel Studio 6.0, khazama avr programmer, программатор - usbasp.