Помогите пожалуйста написать прогу для управления подсветкой дисплея!
- Войдите на сайт для отправки комментариев
Решил добавить в мультиметр подсветку! Сначала думал вкл./выкл. её обычной кнопкой (типа рубильника), но потом решил, что неплохо было бы добавить:
- регулировку яркости (например 5 уровней) с переключением между ними коротким нажатием кнопки (от 1 до 5 и обратно). С этим все понятно – можно использовать ШИМ (PWM) сигнал с вывода контроллера.
- автоотключение (например через 15 минут).
- выключение длительным нажатием (удержание кнопки 1 с или больше)
Можно ли сделать все это при помощи обычной функции «delay();»?
По идее, такая прога должна поместиться даже в обычный Attiny13! Желательно конечно, чтобы сам контроллер потреблял как можно меньше! Поэтому наверно стоит выбрать тактовую частоту минимальной!
P.S.: Ещё позже мне пришла в голову идея – заменить кнопку таким сенсором (чтобы не сверлить корпус мультиметра)! Подскажите пожалуйста, сколько этот сенсор потребляет в ждущем режиме, и стоит ли запихивать его в мультиметр - не будет ли создавать помехи при измерениях?
Почитал даташит - оказывается в ATtiny13 только ОДИН восьми-битный таймер!!!
Возник вопрос: можно ли с его помощью :
- отслеживать длительность нажатия кнопки;
- переходить в спящий режим через заданный интервал времени!
- и к тому же генерировать PWM (ШИМ) сигнал!
ATtiny13 подключаю по такой схеме:
Может купите мультиметр? Я серьезно, как вы встроите подсветку в LCD в которой ее нет?
Не реклама, у меня в MS8222H есть подсветка, а выключается чере 15 минут сам мультиметр, а подсветка через 10 секунд.
В счетчике гейгера я сделал автоматическое ON OFF от фоторезистора, более не надо.
А 5 порогов яркости, или не яркости (зависит от фантазии) можно использовать в чем то более полезном.
Может купите мультиметр? Я серьезно, как вы встроите подсветку в LCD в которой ее нет?
Дело в том, что дисплей подсветку поддерживает - там даже есть места под светодиоды, а припаять их - не проблема!
Код для управления подсветкой уже есть - причем даже лучший, чем думал написать я! Изначально он разрабатывался для фонарика - вкл./выкл. и плавное регулирование яркости всего одной кнопкой!
/***************************************************** This program was produced by the omercury Chip type : ATiny13 Program type : Application AVR Core Clock frequency: 9,600000 MHz *****************************************************/ #include <tiny13.h> //#include <delay.h> //Подключили библиотеку задержек #define secundes 900 // 60 секунд * 15 минут #define timDiv 600 // ~600 тиков таймера в секунду #define shortkey 0x80 //80 . Константа - минимум для короткого нажатия #define longkey 0xFE //240. Константа - минимум для длинного нажатия #define PWM_del 0x0A //15. Константа задержки изменения яркости #define PWM_start 0xF0 //125. Константа. Стартовое значение яркости unsigned int timCount = 0; // Счетчик тиков таймера unsigned int systemClock = 0; // Счетчик тиков таймера unsigned char tmpPWM = PWM_start; unsigned char count = 0; //Счетчик времени удержания кнопки unsigned char b_count = 0; //Счетчик задержки изменения яркости bit KeyEXE; //Флаг опроса кнопок bit KeyNew; //Флаг нового нажатия bit PWM_on; //Флаг признака включения фонаря bit Dir_on; //Флаг направления изменения PWM #define SBIT(ADDRESS,BIT) ((ADDRESS) |= (1<<(BIT))) #define CBIT(ADDRESS,BIT) ((ADDRESS) &= ~(1<<(BIT))) #define KeyPress (!PINB.1) //Вход кнопки #define led_on (PORTB.0) //Изменение яркости свечения(коэф. заполнения ШИМ) void bright_ch(void) { b_count++; //Инкремент счётчика задержки if (b_count>=PWM_del) //Если досчитали { if (Dir_on) //Если предидущее изменение было в + { OCR0A++; //Уменьшаем яркость if (OCR0A==0){OCR0A=0xFF;} //Тормозим на минимуме } else //Если предидущее изменение было в - { OCR0A--; //Увеличиваем яркость if (OCR0A==0xFF){ OCR0A=0;} //Тормозим на максимуме } b_count = 0x00; //Сброс четчика } } //Сброс переменных void clr_var(void) { count = 0; //Сбросили счётчик задержки срабатывания кнопки b_count = 0; //Сбросили счётчик задержки шага изменения PWM KeyNew = 0; //Сбрасываем флаг } //Включение/выключение фонаря void led_on_off(void) { if (PWM_on) //Если флаг установлен (включен) { tmpPWM = OCR0A; OCR0A=0xFF; //Гасим свет PWM_on = 0; //Сбросили флаг } else //А если выключен - включить { OCR0A=tmpPWM;//PWM_start; //Включаем PWM_on = 1; //Установили флаг } } //Сканирование кнопки void key_scan(void) { if KeyPress //Если кнопка нажата { //Проверим, давно ли её нажали if (KeyNew) //Если флаг установлен (значит "давно") { count++; //Увеличиваем счётчик задержки if (count>longkey) //Если длинное нажатие { bright_ch(); //Начинаем менять компаратор ШИМ count--; //Декремент счетчика(увеличивать-то его больше никчему) PWM_on = 1; } //Выход } else //Нажали только что, на это и укажем { KeyNew = 1; //Устанавливаем флаг } //Выход systemClock = 0; //Сброс таймаута выключения подсветка } else //Если кнопка не нажата Это может означать, { //что её и не нажимали или только что отпустили, вот это и проверим даьше if (KeyNew) //Если флаг установлен (только что отпустили) { //Проверим, до скольки успели досчитать if (count<longkey) //Если меньше длинного(короткое нажатие) {//Можно было и объединить, но не люблю я двойные условия, МК их всё равно по очереди сделает if (count>shortkey) //Если больше минимального (короткое, но не дребезг) { led_on_off(); //Включаем/выключаем фонарь } //Иначе - Это был дребезг } else {Dir_on=~Dir_on;} //Меняем направление изменения яркости } clr_var(); //Сброс переменных } //Выход KeyEXE = 0; //Запрет опроса кнопок #asm("sleep") //Усыпляем МК } // Time 0 overflow interrupt service routine // раз в 8 mS interrupt [TIM0_OVF] void Time0_ovf_isr(void) { KeyEXE = 1; //Разрешение опроса кнопок timCount++; if (timCount > timDiv) { timCount=0; systemClock++; } } // External Interrupt 0 service routine interrupt [EXT_INT0] void ext_int0_isr(void) { GIMSK=0x00; //Disable External Interrupt-0 TCCR0B=0x03; //CLK/64 Enable Timer } void main(void) { // Input/Output Ports initialization PORTB=0x00; DDRB=(1<<led_on); // Time/Counter 0 initialization // Clock source: System Clock/64 // Clock value: 585.9 Hz TCCR0A=0xC3;//Fast PWM (Mode 3) Set OC0B on Compare Match, clear OC0B at TOP TCCR0B=0x03;//CLK/64 TCNT0=0x00; OCR0A=PWM_start; OCR0B=0xFF; //На всякий случай))) tmpPWM=PWM_start; // Time(s)/Counter(s) Interrupt(s) initialization TIMSK0=0x02;//Timer Overflow Interrupt // Global enable interrupts #asm("sei") while (1) { if (KeyEXE) { key_scan(); } if (systemClock > secundes) { systemClock = 0; PWM_on = 1; led_on_off(); TCCR0B=0; //Disable timer MCUCR=2; //Rising Edge generate interrupt GIMSK=0x40; //Enable External Interrupt-0 #asm("sleep") //Усыпляем МК } } }Пробовал загружать его в ATtiny13A - работает! Только непонятно, почему микроконтроллер потребляет 7 mA даже когда светодиод не горит вообще! Такое впечатление, что спящий режим у него не работает! Кто в этом разбирается, подскажите пожалуйста, в чем может быть причина???
Может FUSE биты неправильно стоят?
Добавил в код ещё строчку:
Всё равно ATtiny13A не засыпает- потребление около 6mA!!! Что за странный глюк? Помогите пожалуйста разобраться!