Помогите пожалуйста написать прогу для управления подсветкой дисплея!

prosto_andriy
Offline
Зарегистрирован: 09.12.2012

Решил добавить в мультиметр подсветку! Сначала думал вкл./выкл. её обычной кнопкой (типа рубильника), но потом решил, что неплохо было бы добавить:

- регулировку яркости (например 5 уровней) с переключением между ними коротким нажатием кнопки (от 1 до 5 и обратно). С этим все понятно – можно использовать ШИМ (PWM) сигнал с вывода контроллера.

- автоотключение (например через 15 минут).

- выключение длительным нажатием (удержание кнопки 1 с или больше)

Можно ли сделать все это при помощи обычной функции «delay();»?
По идее, такая прога должна поместиться даже в обычный Attiny13! Желательно конечно, чтобы сам контроллер потреблял как можно меньше! Поэтому наверно стоит выбрать тактовую частоту минимальной!

P.S.: Ещё позже мне пришла в голову идея – заменить кнопку таким сенсором (чтобы не сверлить корпус мультиметра)! Подскажите пожалуйста, сколько этот сенсор потребляет в ждущем режиме, и стоит ли запихивать его в мультиметр - не будет ли создавать помехи при измерениях?
 

prosto_andriy
Offline
Зарегистрирован: 09.12.2012

Почитал даташит - оказывается в ATtiny13 только ОДИН восьми-битный таймер!!!

 Возник вопрос: можно ли с его помощью :

- отслеживать длительность нажатия кнопки;

- переходить в спящий режим через заданный интервал времени!

- и к тому же генерировать PWM (ШИМ) сигнал!

ATtiny13 подключаю по такой схеме:

TevatroN
Offline
Зарегистрирован: 17.11.2013

Может купите мультиметр? Я серьезно, как вы встроите подсветку в LCD в которой ее нет?

Не реклама, у меня в MS8222H есть подсветка, а выключается чере 15 минут сам мультиметр, а подсветка через 10 секунд.

В счетчике гейгера я сделал автоматическое ON OFF от фоторезистора, более не надо.

А 5 порогов яркости, или не яркости (зависит от фантазии) можно использовать в чем то более полезном.

prosto_andriy
Offline
Зарегистрирован: 09.12.2012

TevatroN пишет:

Может купите мультиметр? Я серьезно, как вы встроите подсветку в 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 биты неправильно стоят?

 

 

Добавил в код ещё строчку:

#include <sleep.h>

Всё равно ATtiny13A не засыпает- потребление около 6mA!!! Что за странный глюк? Помогите пожалуйста разобраться!