Переключение настроек с выводом на один индикатор. AVR

Обсуждаем контроллеры компании Atmel.
Ответить
Встал на лапы
Аватара пользователя
Сообщения: 118
Зарегистрирован: Вт апр 21, 2020 07:44:24
Откуда: Сумы, Украина

Сообщение Alek_von_German »

Доброго здравия, друзья! Я уже писал здесь по-поводу часов, но тогда я делал их большими и из функционала мне нужно было только вывод времени и настройка. Теперь же мои хотелки неугомонные захотели сделать малюсенькие часики на рабочий стол. Сказано-сделано. В предидущих часах я использовал 4 74hc595+4uln2803, в этот раз ограничился двумя регистрами. DS3231 c Atmega8 связал, инициализировал всё, индикаторы подключил с кнопичками, всё работает, лучше йух придумаешь)) Хотел прилепить файл шпротеуса, но почему-то не выходит. Ну да ладно, лирика закончилась, когда я решил, что часики точные, резервное питание присутствует, не мешало бы и будильничек прилепить. И на этом мой энтузиазм пал смертью храбрых. Как сохранить данные в еепром я знаю. Но встал вопрос о том как настройку бцдильника и часов организовать правильно. Сейчас при нажатии кнопки SET мы заходим, если так сказать можно, в настройку часов, кнопками UP\DOWN изменяем значение, OK перекидывает с часов на минуты, после минут сохраняет настройки и вылазит из настройки. Теперь я немогу даже примерно представить как организовать настройку так, чтоб при нажатии кнопки СЕТ мы сразу заходим в настройки будильника, а потом уже перекидываемся в настройки часов. При этом в настройках нужно чтоб на дисплее это отображалось. .
ЧАСЫ1.jpg
(78.25 КБ) 275 скачиваний
Спойлер

Код: Выделить всё

 #define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define sw PIND
#define set 4
#define ok 3
#define up 2
#define down 1
#define setEvent (sw & (1<<set))
#define okEvent (sw & (1<<ok))
#define upEvent (sw & (1<<up))
#define downEvent (sw & (1<<down))

uint8_t sec, min, hr;
int day,dd,mm,yy;
char setFlag;
volatile uint8_t count,count1;

#define timeFormat 24
uint8_t d0,d1,d2,d3;
enum
{
    hour=1,
    minute,
    
};
void init_ports()
{
    DDRB  = 0xFF;
    PORTB = 0x00;
    DDRD=0x00;
    PORTD=0xff;
}

void update_Time();

int bcd_to_char(int8_t num)
{
    return ((num/16 * 10) + (num % 16));
}

int dec_to_bcd(int8_t num)
{
    return ((num/10)<<4) + (num % 10);
}

void RTC_start()
{
    TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
    while((TWCR&0x80)==0x00);
}

void device()
{
    TWDR=0xD0;                                         //RTC write (slave address)
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
    
    TWDR=0x00;                                        // word address write
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void RTC_stp()
{
    TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);           //stop communication
}

void RTC_read()
{
    TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
    while((TWCR&0x80)==0x00);
    TWDR=0xD0;                                         //RTC write (slave address)
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
    TWDR=0x00;                                         //RTC write (word address)
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
    TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);              //start RTC  communication again
    while ((TWCR&0x80)==0x00);
    TWDR=0xD1;                                        // RTC command to read
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void sec_init(int8_t d)
{
    TWDR=d;                                       //second init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void min_init(int8_t d)
{
    TWDR=d;                                       //minute init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void hr_init(int8_t d)
{
    TWDR=d;                                        //hour init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void day_init(int8_t d)
{
    TWDR=d;                                          //days init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void date_init(int8_t d)
{
    TWDR=d;                                          //date init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void month_init(int8_t d)
{
    TWDR=d;                                         //month init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void yr_init(int8_t d)
{
    TWDR=d;                                         //year init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

int sec_rw()
{
    
    TWCR|=(1<<TWINT)|(1<<TWEA);                         //RTC second read
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

int min_rw()
{
    TWCR|=(1<<TWINT);                                   //RTC minute read
    TWCR|=(1<<TWEA);
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

int hr_rw()
{
    TWCR|=(1<<TWINT)|(1<<TWEA);                         //RTC hour read
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

int day_rd()
{
    TWCR|=(1<<TWINT)|(1<<TWEA);                         //RTC day read
    while((TWCR&0x80)==0x00);
    return bcd_to_char(TWDR);
}

int date_rw()
{
    TWCR|=(1<<TWINT)|(1<<TWEA);                      //RTC date read
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

int month_rw()
{
    TWCR|=(1<<TWINT)|(1<<TWEA);                     //RTC month read
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

int yr_rw()
{
    TWCR|=(1<<TWINT);                                 //RTC year read
    TWCR&=(~(1<<TWEA));
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

void setTime()
{
    RTC_start();
    device();
    sec_init(0);
    min_init(dec_to_bcd(min));
    hr_init(dec_to_bcd(hr));
    
    RTC_stp();
}

void RTC()
{
    RTC_read();
    sec=sec_rw();
    min=min_rw();
    hr=hr_rw();
    day=day_rd();
    dd=date_rw();
    mm=month_rw();
    yy=yr_rw();
    RTC_stp();
}

char get_SETTINGS(uint8_t count)
{
    while(1)
    {
        update_Time();
        if(!upEvent)
        {
            
            count++;
            
            if(setFlag == hour)
            {
                
                if(timeFormat == 24)
                {
                    if(count > 23)
                    count=0;
                }
                
                hr=count;

            }
            
            else if(setFlag == minute)
            {
                if(count>59)
                count=0;
                min=count;
            }
            _delay_ms(100);
            
        }
        
        else if(!(downEvent))
        {
            
            count--;
            
            if(setFlag == hour)
            {
                if(timeFormat == 24)
                {
                    if(count > 23)
                    count=0;
                }
                
                hr=count;
            }
            
            else if(setFlag == minute)
            {
                if(count>59)
                count=0;
                min=count;
            }
            _delay_ms(100);
        }
        else if(!okEvent)
        {
            _delay_ms(500);
            return count;
        }
    }
}

void setting_Time()
{
    setFlag=1;
    hr=get_SETTINGS(hr);
    setFlag++;
    min=get_SETTINGS(min);
    setFlag=0;

}

void update_Time()
{
    d0=min%10;//минуты
    d1=min/10;//десятки минут
    d2=hr%10;//часы
    d3=hr/10;//десятки часов
}

const uint8_t dig[] = {
    0b10000001, //0
    0b11110011, //1
    0b01001001, //2
    0b01100001, //3
    0b00110011, //4
    0b00100101, //5
    0b00000101, //6
    0b11110001, //7
    0b00000001, //8
    0b00100001, //9
    0b00000000,//пусто
    0b00000001}; //точка

const uint8_t razr[] = {
    0b11111110,
    0b11111101,
    0b11111011,
    0b11110111};

uint8_t display[2];
volatile  uint8_t i, a=0,k;
volatile  uint16_t  dot=0;
uint8_t dig1, dig2, dig3, dig4;

void init_timer0()
{
    TIMSK =(1<<TOIE0);  // timer0 enable
    TCCR0 = (1<<CS01); // prescaler 1/1024
    TCNT0=128;
    sei();
}

void write_display(unsigned char *data)
{
    unsigned char mask,i;
    for(i = 0; i < 2; i++)
    {
        mask = 0x80;
        
        for(char k = 0; k < 8; k++)
        {
            // Сравниваем каждый бит с единицей
            if(data[i] & mask)
            {
                PORTB |= (1 << 0); // DATA 1
                PORTB |= (1 << 1); // CLK 1
                PORTB &= ~(1 <<1); // CLK 0
            }
            else
            {
                PORTB &= ~(1 << 0); // DATA 0
                PORTB |= (1 << 1); // CLK 1
                PORTB &= ~(1 << 1); // CLK 0
            }
            mask = mask >> 1; // Сдвигаем биты
        }
    }
    // Защелкиваем регистр
    PORTB |= (1 << 2);
    PORTB &= ~(1 << 2);
}

ISR (TIMER0_OVF_vect)
{
    
    (k == 4) ? k = 0: k++;

    switch(k)
    {
        case 0:
        dig4=dig[d3] ;
        display[0] =  razr[3];
        display[1] = ~ dig4;
        write_display(display);
        break;

        case 1:
        dig3=dig[d2];
        display[0] =  razr[2];
        display[1] = ~ dig3;
        write_display(display);
        break;

        case 2:
        dig2=dig[d1];
        display[0] =  razr[1];
        display[1] =  ~dig2;
        write_display(display);
        break;

        case 3:
        dig1=dig[d0];
        display[0] =razr[0];    // в крайний левый символ
        display[1] =~ dig1;        // выводится цифра
        write_display(display);
        break;

        case 4:
        dig3=dig[d2];
        display[0] =razr[2];    // в крайний левый символ
        display[1] =dig[10|dot];        // выводится цифра
        write_display(display);
        break;
    }
}

int main(void)
{
    init_ports();
    init_timer0();
    
    while (1)
    {
        RTC();
        update_Time();
        
        if (sec&1) dot=0;
        else
        {
            dot=dig[11];
        }

        if (!setEvent)
        {
            setting_Time();
            setTime();
        }
    }
}

Хочется всё и сразу, а получаешь нихрена и постепенно...
Реклама
Друг Кота
Аватара пользователя
Сообщения: 15592
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

DS3231 имеет в своем составе аж два будильника... Используйте ее функционал в полной мере, а уж ежли не хватит - тогда ставим чего дополнительного.
Зачем еще чего-то с ЕЕПРОМ придумывать?
:dont_know:
Реклама
Самсусамыч

Сообщение Самсусамыч »

[uquote="Alek_von_German",url="/forum/viewtopic.php?p=3863143#p3863143"]Теперь я немогу даже примерно представить как организовать настройку так, чтоб при нажатии кнопки СЕТ мы сразу заходим в настройки будильника, а потом уже перекидываемся в настройки часов. При этом в настройках нужно чтоб на дисплее это отображалось.[/uquote]
Организуйте функцию короткого и длинного нажатия кнопки… короткое нажатие – установка будильника, длинное нажатие – установка часов.
Встал на лапы
Аватара пользователя
Сообщения: 118
Зарегистрирован: Вт апр 21, 2020 07:44:24
Откуда: Сумы, Украина

Сообщение Alek_von_German »

[uquote="BOB51",url="/forum/viewtopic.php?p=3863307#p3863307"]DS3231 имеет в своем составе аж два будильника... Используйте ее функционал в полной мере, а уж ежли не хватит - тогда ставим чего дополнительного.
Зачем еще чего-то с ЕЕПРОМ придумывать?
:dont_know:[/uquote]
Спасибо за ответ. Об этом я уже думал. Одного будильника более чем достаточно. Тем более, если я правильно понял даташит, их можно конфигурировать на срабатывание от секунд до дней в самом RTC. Это не есть сложность. Меня загнала в тупик совершенно тривиальная задача- выводить на индикатор значение будильника при настройке. Функцию вывода времени сделать не тяжело, если бы был ещё один индикатор рядом то я смог бы на нём отдельно организовать вывод значений будильника, но вот, чтобы это всё переключалось на одном индикаторе....туплю.

здесь настройка часов:
Спойлер

Код: Выделить всё

char get_SETTINGS(uint8_t count)
{
    while(1)
    {
        update_Time();
        if(!upEvent)
        {
            count++;
            if(setFlag == hour)
            {
                if(timeFormat == 24)
                {
                    if(count > 23)
                    count=0;
                }
                hr=count;
            }
            else if(setFlag == minute)
            {
                if(count>59)
                count=0;
                min=count;
            }
            _delay_ms(100);
        }
        else if(!(downEvent))
        {
            count--;
            if(setFlag == hour)
            {
                if(timeFormat == 24)
                {
                    if(count > 23)
                    count=0;
                }
                hr=count;
            }
            else if(setFlag == minute)
            {
                if(count>59)
                count=0;
                min=count;
            }
            _delay_ms(100);
        }
        else if(!okEvent)
        {
            _delay_ms(500);
            return count;
        }
    }
}
здесь переход настроек с часов на минуты:
Спойлер

Код: Выделить всё

void setting_Time()
{
    setFlag=1;
    hr=get_SETTINGS(hr);
    setFlag++;
    min=get_SETTINGS(min);
    setFlag=0;

}
а здесь уже идет сам вывод на индикатор:
Спойлер

Код: Выделить всё

ISR (TIMER0_OVF_vect)
{
    
    (k == 4) ? k = 0: k++;

    switch(k)
    {
        case 0:
        dig4=dig[d3] ;
        display[0] =  razr[3];
        display[1] = ~ dig4;
        write_display(display);
        break;

        case 1:
        dig3=dig[d2];
        display[0] =  razr[2];
        display[1] = ~ dig3;
        write_display(display);
        break;

        case 2:
        dig2=dig[d1];
        display[0] =  razr[1];
        display[1] =  ~dig2;
        write_display(display);
        break;

        case 3:
        dig1=dig[d0];
        display[0] =razr[0];    // в крайний левый символ
        display[1] =~ dig1;        // выводится цифра
        write_display(display);
        break;

        case 4:
        dig3=dig[d2];
        display[0] =razr[2];    // в крайний левый символ
        display[1] =dig[10|dot];        // выводится цифра
        write_display(display);
        break;
    }
}
Мне кажется так.
Мне нужно добавить новую функцию вывода но уже на будидьник, или использовать имеющуюся.
При этом, нужно добавить в функцию setting_Time() вход в будильник.
Ну а в самой char get_SETTINGS организовывать изменение значений и сохранение их.
Правильно?
Хочется всё и сразу, а получаешь нихрена и постепенно...
Реклама
Эиком - электронные компоненты и радиодетали
Самсусамыч

Сообщение Самсусамыч »

[uquote="Alek_von_German",url="/forum/viewtopic.php?p=3863324#p3863324"]но вот, чтобы это всё переключалось на одном индикаторе....туплю.[/uquote]
Конфигурацией свечения точек можно всё организовать… или дополнительным светодиодом. :)
Реклама
Встал на лапы
Аватара пользователя
Сообщения: 118
Зарегистрирован: Вт апр 21, 2020 07:44:24
Откуда: Сумы, Украина

Сообщение Alek_von_German »

[uquote="Самсусамыч",url="/forum/viewtopic.php?p=3863329#p3863329"]Конфигурацией свечения точек можно всё организовать… или дополнительным светодиодом. :)[/uquote]
Не-не, я о другом, это индикация вкл\выкл, это естественно элементарно.
Я не могу сообразить вот что,
на часах допустим 12.49
нажимаем СЕТ и сразу на дисплее 00.00- мы вошли в настройки блудильника.
Понажимали кнопочек, настроили, нажали ОК- настройки сохранились и переключаемся в настройки времени.
на дисплее теперешнее время 12.49
снова тыкаем кнопочки, настроились, нажали ОК- сохранились и вышли с настроек.
Вот.
Хочется всё и сразу, а получаешь нихрена и постепенно...
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3784
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

[uquote="Alek_von_German",url="/forum/viewtopic.php?p=3863324#p3863324"]но вот, чтобы это всё переключалось на одном индикаторе....туплю.[/uquote]В качестве ещё одной идеи, посмотрите как это сделано на видео к статье. А вообще, советую подумать о добавке к часам WiFi/Bluetooth модуля для реализации установки времени/будильника, например, через смартфон, который позволяет несложно организовать несравненно более приветливый интерфейс с пользователем.
Встал на лапы
Аватара пользователя
Сообщения: 118
Зарегистрирован: Вт апр 21, 2020 07:44:24
Откуда: Сумы, Украина

Сообщение Alek_von_German »

[uquote="Ser60",url="/forum/viewtopic.php?p=3863338#p3863338"]В качестве ещё одной идеи, посмотрите как это сделано на видео к статье. А вообще, советую подумать о добавке к часам WiFi/Bluetooth модуля для реализации установки времени/будильника, например, через смартфон, который позволяет несложно организовать несравненно более приветливый интерфейс с пользователем.[/uquote]

Просмотрел Вашу ссылку, всё красиво сделано, но в данный момент не для моего умишка. А особенно для меня вообще не актуально беспроводная связь. В будущем может быть, когда азы освою :dont_know:
Хочется всё и сразу, а получаешь нихрена и постепенно...
Открыл глаза
Сообщения: 42
Зарегистрирован: Вс сен 03, 2017 19:43:57

Сообщение technik-1017 »

Во вложении исходники одного проекта (управление освещением по расписанию)
chip: : PIC18F2620
compiler: HI-TECH PICC-18 COMPILER (Microchip PIC micro) V9.50PL1

Основное для вас это массивы указателей на функции ShowModes (какой экран отображаем), Function (какая кнопка в каком экране меню нажата) и работа с ними в функции main.
Входными данными этих массивов являются номер текущего экрана меню и код нажатой клавиши (обработка в interrupt.c).

Т.к. это обычный Си, то перенос на AVR не должен составить проблем.

Проект не коммерческий (был сделан для нужд некогда родного предприятия).
Вложения
light.7z
(86.21 КБ) 215 скачиваний
Контактная информация:
Самсусамыч

Сообщение Самсусамыч »

[uquote="Alek_von_German",url="/forum/viewtopic.php?p=3863336#p3863336"]на часах допустим 12.49[/uquote]
Зачем из режима установки будильника входить в режим установки часов? ИМХО Из любого режима лучше выходить в дежурный режим.

Даже если у Вас индикатор только с такими точками…
1.png
То при отображении допустим хода часов, средняя точка мигает в такт секундам (12.49), что указывает обычный ход часов… при входе в режим корректировки часов, средняя точка перестаёт мигать и светит постоянно (12.49), при входе в режим установки будильника к немигающей средней точке, дополнительно зажигаете крайнюю правую точку (00.00.), которая указывает на режим установки будильника. При выходе в дежурный режим, крайняя точка может сигнализировать о включении/отключении будильника.
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

кажется понял, чего надо ТСу - ему поможет конечный автомат: (расшийрую) создай переменную, отображающую твоё положение в меню (unsigned char menu=0;) и пусть она соответствует например
0- нормальная работа
1- настройка часов
2- настройка минут (если они отдельно настраиваются)
3- настройка часов будильника
4- настройка минут будильника (——//——)
и.т.д.
опиши вывод на дисплей, действие кнопок для каждого значения переменной меню, нарисуй карту переходов (по какой кнопке из какого в какое состояние переходим)
получится ввитч-кейс:
свитч (меню)
{
кейс 0:
кнопки не нажаты - выводим часы
нажата кнопка 1 - выводим будильник
нажата кнопка 2 - меню=1; ,выводим часы
нажата кнопка 3 - меню=3; ,выводим будильник
брейк;
кейс 1:
кнопки не нажаты - выводим часы
нажата кнопка 1 - добавляем к часам 1, выводим часы
нажата кнопка 2...,...и.т.д.
брейк;
кейс 3:
кнопки не нажаты - выводим будильник
нажата кнопка 1 - добавляем 1 к часам будильника, выводим будильник
и.т.д...}
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Вымогатель припоя
Сообщения: 593
Зарегистрирован: Ср янв 06, 2010 10:01:46

Сообщение metan »

Я думаю можно реализовать меню следующим образом:
1. Кнопкой SET выбираем режим. На экране последовательно меняются, например:
фразы "F1" - установка времени, "F2" - установка будильника, "F3" - установка даты ... , и далее по кругу.
2. выбрав режим, нажимаем ОК
3. Правим параметр (UP\DOWN\OK), нажимаем SET. При этом параметр заносится в память и происходит выход в основной рабочий режим.
Встал на лапы
Аватара пользователя
Сообщения: 118
Зарегистрирован: Вт апр 21, 2020 07:44:24
Откуда: Сумы, Украина

Сообщение Alek_von_German »

Спасибо всем за ответы. Решил добавить в схему еще одну кнопку ALARM. Таким образом будильник можно настраивать не касаясь других настроек.
На данный момент я вывел только вход в настройки будильника и вывод на индикатор. Пока без индикации состояния и без сохранения. Но мне кажется это уже прогресс..))

Просмотрите код, если кому интересно.
Спойлер

Код: Выделить всё

#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define sw PIND
#define alarm 5
#define set 4
#define ok 3
#define up 2
#define down 1
#define alarmEvent (sw &(1<<alarm))
#define setEvent (sw & (1<<set))
#define okEvent (sw & (1<<ok))
#define upEvent (sw & (1<<up))
#define downEvent (sw & (1<<down))
volatile  uint16_t  dot=0;
uint8_t sec, min, hr;
uint8_t min_al=0, hr_al=0;
int day,dd,mm,yy;
char setFlag;
volatile uint8_t count,count1;

#define timeFormat 24
uint8_t d0,d1,d2,d3;
enum
{
    hour=1, hour_al=1,
    minute=2, minute_al=2,
   
    
};

void init_ports()
{
    DDRB  = 0xFF;
    PORTB = 0x00;
    DDRD=0x00;
    PORTD=0xff;
}

void update_Time();




int bcd_to_char(int8_t num)
{
    return ((num/16 * 10) + (num % 16));
}

int dec_to_bcd(int8_t num)
{
    return ((num/10)<<4) + (num % 10);
}

void RTC_start()
{
    TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
    while((TWCR&0x80)==0x00);
}

void device()
{
    TWDR=0xD0;                                         //RTC write (slave address)
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
    
    TWDR=0x00;                                        // word address write
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void RTC_stp()
{
    TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);           //stop communication
}

void RTC_read()
{
    TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
    while((TWCR&0x80)==0x00);
    TWDR=0xD0;                                         //RTC write (slave address)
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
    TWDR=0x00;                                         //RTC write (word address)
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
    TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);              //start RTC  communication again
    while ((TWCR&0x80)==0x00);
    TWDR=0xD1;                                        // RTC command to read
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void sec_init(int8_t d)
{
    TWDR=d;                                       //second init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void min_init(int8_t d)
{
    TWDR=d;                                       //minute init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void hr_init(int8_t d)
{
    TWDR=d;                                        //hour init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void day_init(int8_t d)
{
    TWDR=d;                                          //days init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void date_init(int8_t d)
{
    TWDR=d;                                          //date init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void month_init(int8_t d)
{
    TWDR=d;                                         //month init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void yr_init(int8_t d)
{
    TWDR=d;                                         //year init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

int sec_rw()
{
    
    TWCR|=(1<<TWINT)|(1<<TWEA);                         //RTC second read
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

int min_rw()
{
    TWCR|=(1<<TWINT);                                   //RTC minute read
    TWCR|=(1<<TWEA);
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

int hr_rw()
{
    TWCR|=(1<<TWINT)|(1<<TWEA);                         //RTC hour read
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

int day_rd()
{
    TWCR|=(1<<TWINT)|(1<<TWEA);                         //RTC day read
    while((TWCR&0x80)==0x00);
    return bcd_to_char(TWDR);
}

int date_rw()
{
    TWCR|=(1<<TWINT)|(1<<TWEA);                      //RTC date read
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

int month_rw()
{
    TWCR|=(1<<TWINT)|(1<<TWEA);                     //RTC month read
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

int yr_rw()
{
    TWCR|=(1<<TWINT);                                 //RTC year read
    TWCR&=(~(1<<TWEA));
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

void setTime()
{
    RTC_start();
    device();
    sec_init(0);
    min_init(dec_to_bcd(min));
    hr_init(dec_to_bcd(hr));
    
    RTC_stp();
}

void RTC()
{
    RTC_read();
    sec=sec_rw();
    min=min_rw();
    hr=hr_rw();
    day=day_rd();
    dd=date_rw();
    mm=month_rw();
    yy=yr_rw();
    RTC_stp();
}

char get_SETTINGS(uint8_t count)
{
    while(1)
    {
        update_Time();
        if(!upEvent)
        {
            count++;
            if(setFlag == hour)
            {
                if(timeFormat == 24)
                {
                    if(count > 23)
                    count=0;
                }
                hr=count;
            }
            else if(setFlag == minute)
            {
                if(count>59)
                count=0;
                min=count;
            }
            _delay_ms(100);
        }
        else if(!(downEvent))
        {
            count--;
            if(setFlag == hour)
            {
                if(timeFormat == 24)
                {
                    if(count > 23)
                    count=0;
                }
                hr=count;
            }
            else if(setFlag == minute)
            {
                if(count>59)
                count=0;
                min=count;
            }
            _delay_ms(100);
        }
        else if(!okEvent)
        {
            _delay_ms(500);
            return count;
        }
    }
}
void upd_alarm()
{
     d0=min_al%10;//минуты
     d1=min_al/10;//десятки минут
     d2=hr_al%10;//часы
     d3=hr_al/10;//десятки часов
}
char get_set_alarm (uint8_t count2)
{
while(1)
{
    upd_alarm();
    if(!upEvent)
    {
        count2++;
        if(setFlag == hour_al)
        {
            if(timeFormat == 24)
            {
                if(count2 > 23)
                count2=0;
            }
            hr_al=count2;
        }
        else if(setFlag == minute_al)
        {
            if(count>59)
            count2=0;
            min_al=count2;
        }
        _delay_ms(100);
    }
    else if(!(downEvent))
    {
        count2--;
        if(setFlag == hour_al)
        {
            if(timeFormat == 24)
            {
                if(count2 > 23)
                count2=0;
            }
            hr_al=count2;
        }
        else if(setFlag == minute_al)
        {
            if(count2>59)
            count2=0;
            min_al=count2;
        }
        _delay_ms(100);
    }
    else if(!okEvent)
    {
        _delay_ms(500);
        return count2;
    }
}
}

void setting_Time()
{
    setFlag=1;
    hr=get_SETTINGS(hr);
    setFlag++;
    min=get_SETTINGS(min);
    setFlag=0;

}
void set_aiarm()
{
 setFlag=1;
 hr_al=get_set_alarm(hr_al);
 setFlag++;
 min_al=get_set_alarm(min_al);
 setFlag=0;
}
void update_Time()
{
    d0=min%10;//минуты
    d1=min/10;//десятки минут
    d2=hr%10;//часы
    d3=hr/10;//десятки часов
}



const uint8_t dig[] = {
    0b10000001, //0
    0b11110011, //1
    0b01001001, //2
    0b01100001, //3
    0b00110011, //4
    0b00100101, //5
    0b00000101, //6
    0b11110001, //7
    0b00000001, //8
    0b00100001, //9
    0b00000000,//пусто
0b00000001}; //точка

const uint8_t razr[] = {
    0b11111110,
    0b11111101,
    0b11111011,
0b11110111};

uint8_t display[2];
volatile  uint8_t i, a=0,k, al;

uint8_t dig1, dig2, dig3, dig4;

void init_timer0()
{
    TIMSK =(1<<TOIE0);  // timer0 enable
    TCCR0 = (1<<CS01); // prescaler 1/1024
    TCNT0=128;
    sei();
}

void write_display(unsigned char *data)
{
    unsigned char mask,i;
    for(i = 0; i < 2; i++)
    {
        mask = 0x80;
        
        for(char k = 0; k < 8; k++)
        {
            // Сравниваем каждый бит с единицей
            if(data[i] & mask)
            {
                PORTB |= (1 << 0); // DATA 1
                PORTB |= (1 << 1); // CLK 1
                PORTB &= ~(1 <<1); // CLK 0
            }
            else
            {
                PORTB &= ~(1 << 0); // DATA 0
                PORTB |= (1 << 1); // CLK 1
                PORTB &= ~(1 << 1); // CLK 0
            }
            mask = mask >> 1; // Сдвигаем биты
        }
    }
    // Защелкиваем регистр
    PORTB |= (1 << 2);
    PORTB &= ~(1 << 2);
}

void clock_disp()
{
    (k == 4) ? k = 0: k++;

    switch(k)
    {
        case 0:
        dig4=dig[d3] ;
        display[0] =  razr[3];
        display[1] = ~ dig4;
        write_display(display);
        break;

        case 1:
        dig3=dig[d2];
        display[0] =  razr[2];
        display[1] = ~ dig3;
        write_display(display);
        break;

        case 2:
        dig2=dig[d1];
        display[0] =  razr[1];
        display[1] =  ~dig2;
        write_display(display);
        break;

        case 3:
        dig1=dig[d0];
        display[0] =razr[0];    // в крайний левый символ
        display[1] =~ dig1;        // выводится цифра
        write_display(display);
        break;

        case 4:
        dig3=dig[d2];
        display[0] =razr[2];    // в крайний левый символ
        display[1] =dig[10|dot];        // выводится цифра
        write_display(display);
        break;
    }
}

void alarm_disp()
{
    ( al == 3) ? al = 0: al++;

    switch(al)
    {
        case 0:
        dig4=dig[d3] ;
        display[0] =  razr[3];
        display[1] = ~ dig4;
        write_display(display);
        break;

        case 1:
        dig3=dig[d2];
        display[0] =  razr[2];
        display[1] = ~ dig3;
        write_display(display);
        break;

        case 2:
        dig2=dig[d1];
        display[0] =  razr[1];
        display[1] =  ~dig2;
        write_display(display);
        break;

        case 3:
        dig1=dig[d0];
        display[0] =razr[0];    // в крайний левый символ
        display[1] =~ dig1;        // выводится цифра
        write_display(display);
        break;

       
    }
}

ISR (TIMER0_OVF_vect)
{
    clock_disp();
   alarm_disp();
}

int main(void)
{
    init_ports();
    init_timer0();
    
    while (1)
    {
        RTC();
        update_Time();
        
        if (sec&1) dot=0;
        else
        {
            dot=dig[11];
        }

        if (!setEvent)
        {
            setting_Time();
            setTime();
           
        }

        if (!alarmEvent)
        {
        set_aiarm();
        }
    }
}
Добавлено after 3 hours 15 minutes 34 seconds:
Переписал кодец немного. Будило сохраняется пока в памяти ЕЕПРОМ, настройки работают, при включенном состоянии горит светодиод , при сработке будильника с ноги PD0 высокий уровень заводит активный зуммер.
Пока мне всё нравится. В дальнейшем думаю всё же указывать горящими точками какие разряды настраиваются...
Что скажите?
Спойлер

Код: Выделить всё

#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/eeprom.h>
unsigned char alarm_hour;
unsigned char alarm_min;
unsigned char alarm_on;
unsigned char al_on;                // переменная состояния будильника (вкл / выкл)
unsigned char _al;                   // переменная сработки будильника
uint8_t alarm_hour_ee EEMEM = 0;
uint8_t alarm_min_ee EEMEM = 0;
uint8_t alarm_on_ee EEMEM = 0;
#define sw PIND
#define alarm 5
#define set 4
#define ok 3
#define up 2
#define down 1
#define alarmEvent (sw &(1<<alarm))
#define setEvent (sw & (1<<set))
#define okEvent (sw & (1<<ok))
#define upEvent (sw & (1<<up))
#define downEvent (sw & (1<<down))
volatile  uint16_t  dot=0;
uint8_t sec, min, hr;

int day,dd,mm,yy;
char setFlag;
volatile uint8_t count,count1;

#define timeFormat 24
uint8_t d0,d1,d2,d3;
enum
{
    hour=1, hour_al=1,
    minute=2, minute_al=2,
    alarm_on_=3,
    
};

void init_ports()
{
    DDRB  = 0xFF;
    PORTB = 0x00;
    DDRD|=0b00000001;
    PORTD|=0b11111110;
    DDRC|=0b00000001;
    PORTC|=0b00000000;
}

void update_Time();




int bcd_to_char(int8_t num)
{
    return ((num/16 * 10) + (num % 16));
}

int dec_to_bcd(int8_t num)
{
    return ((num/10)<<4) + (num % 10);
}

void RTC_start()
{
    TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
    while((TWCR&0x80)==0x00);
}

void device()
{
    TWDR=0xD0;                                         //RTC write (slave address)
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
    
    TWDR=0x00;                                        // word address write
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void RTC_stp()
{
    TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);           //stop communication
}

void RTC_read()
{
    TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
    while((TWCR&0x80)==0x00);
    TWDR=0xD0;                                         //RTC write (slave address)
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
    TWDR=0x00;                                         //RTC write (word address)
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
    TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);              //start RTC  communication again
    while ((TWCR&0x80)==0x00);
    TWDR=0xD1;                                        // RTC command to read
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void sec_init(int8_t d)
{
    TWDR=d;                                       //second init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void min_init(int8_t d)
{
    TWDR=d;                                       //minute init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void hr_init(int8_t d)
{
    TWDR=d;                                        //hour init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void day_init(int8_t d)
{
    TWDR=d;                                          //days init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void date_init(int8_t d)
{
    TWDR=d;                                          //date init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void month_init(int8_t d)
{
    TWDR=d;                                         //month init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

void yr_init(int8_t d)
{
    TWDR=d;                                         //year init
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)));
}

int sec_rw()
{
    
    TWCR|=(1<<TWINT)|(1<<TWEA);                         //RTC second read
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

int min_rw()
{
    TWCR|=(1<<TWINT);                                   //RTC minute read
    TWCR|=(1<<TWEA);
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

int hr_rw()
{
    TWCR|=(1<<TWINT)|(1<<TWEA);                         //RTC hour read
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

int day_rd()
{
    TWCR|=(1<<TWINT)|(1<<TWEA);                         //RTC day read
    while((TWCR&0x80)==0x00);
    return bcd_to_char(TWDR);
}

int date_rw()
{
    TWCR|=(1<<TWINT)|(1<<TWEA);                      //RTC date read
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

int month_rw()
{
    TWCR|=(1<<TWINT)|(1<<TWEA);                     //RTC month read
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

int yr_rw()
{
    TWCR|=(1<<TWINT);                                 //RTC year read
    TWCR&=(~(1<<TWEA));
    while((TWCR & 0x80)==0x00);
    return bcd_to_char(TWDR);
}

void setTime()
{
    RTC_start();
    device();
    sec_init(0);
    min_init(dec_to_bcd(min));
    hr_init(dec_to_bcd(hr));
    
    RTC_stp();
}

void RTC()
{
    RTC_read();
    sec=sec_rw();
    min=min_rw();
    hr=hr_rw();
    day=day_rd();
    dd=date_rw();
    mm=month_rw();
    yy=yr_rw();
    RTC_stp();
}

char get_SETTINGS(uint8_t count)
{
    while(1)
    {
        update_Time();
        if(!upEvent)
        {
            count++;
            if(setFlag == hour)
            {
                if(timeFormat == 24)
                {
                    if(count > 23)
                    count=0;
                }
                hr=count;
            }
            else if(setFlag == minute)
            {
                if(count>59)
                count=0;
                min=count;
            }
            _delay_ms(100);
        }
        else if(!(downEvent))
        {
            count--;
            if(setFlag == hour)
            {
                if(timeFormat == 24)
                {
                    if(count > 23)
                    count=0;
                }
                hr=count;
            }
            else if(setFlag == minute)
            {
                if(count>59)
                count=0;
                min=count;
            }
            _delay_ms(100);
        }
        else if(!okEvent)
        {
            _delay_ms(500);
            return count;
        }
    }
}
void upd_alarm()
{
     d0=alarm_min%10;//минуты
     d1=alarm_min/10;//десятки минут
     d2=alarm_hour%10;//часы
     d3=alarm_hour/10;//десятки часов
}
char get_set_alarm (uint8_t count2)
{
while(1)
{
    upd_alarm();
    if(!upEvent)
    {
        count2++;
        if(setFlag == hour_al)
        {

            if(timeFormat == 24)
            {
                if(count2 > 23)
                count2=0;
            }
           alarm_hour=count2;
        }
        else if(setFlag == minute_al)
        {
            if(count2>59)
            count2=0;
            alarm_min=count2;
            
        }
         else if (setFlag==alarm_on_)
         {
         if (count2>1)
         
         count2=0;
         alarm_on=count2;
         
         }
         
              
       _delay_ms(200);
    }
    else if(!(downEvent))
    {
        count2--;
        if(setFlag == hour_al)
        {
            if(timeFormat == 24)
            {
                if(count2 > 23)
                count2=0;
            }
            alarm_hour=count2;
        }
        else if(setFlag == minute_al)
        {
            if(count2>59)
            count2=0;
            alarm_min=count2;
        }
      
        _delay_ms(200);
    }
    else if(!okEvent)
    {
        _delay_ms(500);
        
        
        eeprom_write_byte(&alarm_hour_ee, alarm_hour);
        eeprom_write_byte(&alarm_min_ee, alarm_min);
        eeprom_write_byte(&alarm_on_ee, alarm_on);
        return count2;
        }
    }
}


void setting_Time()
{
    setFlag=1;
    hr=get_SETTINGS(hr);
    setFlag++;
    min=get_SETTINGS(min);
    setFlag=0;

}
void set_aiarm()
{
 setFlag=1;
 alarm_hour=get_set_alarm(alarm_hour);
 setFlag++;
 alarm_min=get_set_alarm(alarm_min);
 setFlag++;
 alarm_on=get_set_alarm(alarm_on);
 setFlag=0;
}
void update_Time()
{
    d0=min%10;//минуты
    d1=min/10;//десятки минут
    d2=hr%10;//часы
    d3=hr/10;//десятки часов
}



const uint8_t dig[] = {
    0b10000001, //0
    0b11110011, //1
    0b01001001, //2
    0b01100001, //3
    0b00110011, //4
    0b00100101, //5
    0b00000101, //6
    0b11110001, //7
    0b00000001, //8
    0b00100001, //9
    0b00000000,//пусто
0b00000001}; //точка

const uint8_t razr[] = {
    0b11111110,
    0b11111101,
    0b11111011,
0b11110111};

uint8_t display[2];
volatile  uint8_t i, a=0,k, al;

uint8_t dig1, dig2, dig3, dig4;

void init_timer0()
{
    TIMSK =(1<<TOIE0);  // timer0 enable
    TCCR0 = (1<<CS01); // prescaler 1/1024
    TCNT0=128;
    sei();
}

void write_display(unsigned char *data)
{
    unsigned char mask,i;
    for(i = 0; i < 2; i++)
    {
        mask = 0x80;
        
        for(char k = 0; k < 8; k++)
        {
            // Сравниваем каждый бит с единицей
            if(data[i] & mask)
            {
                PORTB |= (1 << 0); // DATA 1
                PORTB |= (1 << 1); // CLK 1
                PORTB &= ~(1 <<1); // CLK 0
            }
            else
            {
                PORTB &= ~(1 << 0); // DATA 0
                PORTB |= (1 << 1); // CLK 1
                PORTB &= ~(1 << 1); // CLK 0
            }
            mask = mask >> 1; // Сдвигаем биты
        }
    }
    // Защелкиваем регистр
    PORTB |= (1 << 2);
    PORTB &= ~(1 << 2);
}

void clock_disp()
{
    (k == 4) ? k = 0: k++;

    switch(k)
    {
        case 0:
        dig4=dig[d3] ;
        display[0] =  razr[3];
        display[1] = ~ dig4;
        write_display(display);
        break;

        case 1:
        dig3=dig[d2];
        display[0] =  razr[2];
        display[1] = ~ dig3|dot;
        write_display(display);
        break;

        case 2:
        dig2=dig[d1];
        display[0] =  razr[1];
        display[1] =  ~dig2;
        write_display(display);
        break;

        case 3:
        dig1=dig[d0];
        display[0] =razr[0];    // в крайний левый символ
        display[1] =~ dig1;        // выводится цифра
        write_display(display);
        break;

        case 4:
        dig3=dig[d2];
        display[0] =razr[2];    // в крайний левый символ
        display[1] =dig[10|dot];        // выводится цифра
        write_display(display);
        break;
    }
}

void alarm_disp()
{
    ( al == 3) ? al = 0: al++;

    switch(al)
    {
        case 0:
        dig4=dig[d3] ;
        display[0] =  razr[3];
        display[1] = ~ dig4;
        write_display(display);
        break;

        case 1:
        dig3=dig[d2];
        display[0] =  razr[2];
        display[1] = ~ dig3;
        write_display(display);
        break;

        case 2:
        dig2=dig[d1];
        display[0] =  razr[1];
        display[1] =  ~dig2;
        write_display(display);
        break;

        case 3:
        dig1=dig[d0];
        display[0] =razr[0];    // в крайний левый символ
        display[1] =~ dig1;        // выводится цифра
        write_display(display);
        break;

       
    }
}

ISR (TIMER0_OVF_vect)
{
if (!alarmEvent)
{
alarm_disp();
} 
else
{
clock_disp();
}
    
   
   if (alarm_on==1)
   {
       PORTD|=(1<<0);
   }
   else PORTD&=~(1<<0);
}

int main(void)
{
    init_ports();
    init_timer0();
    alarm_hour = eeprom_read_byte(&alarm_hour_ee);
    alarm_min = eeprom_read_byte(&alarm_min_ee);
    alarm_on = eeprom_read_byte(&alarm_on_ee);
    while (1)
    {
        RTC();
        update_Time();
        
        if (sec&1) dot=0;
        else
        {
            dot=dig[11];
        }

        if (!setEvent)
        {
            setting_Time();
            setTime();
           
        }

        if (!alarmEvent)
        {
        set_aiarm();
        }
        if(alarm_on==1)       {
            if(alarm_hour==hr)  {
                if(alarm_min==min)    {
                    if(sec==1)            {
                        _al=1;
                    }
                }
            }
        }
        
        if (!okEvent)
        { _al=0; }
        
    
        // при сработке будильника совершит действие
        if (_al==1)
        {

            PORTC |= (1<<0);

        }

        else
        {

            PORTC &=~(1<<0);

        }
    }
}
Хочется всё и сразу, а получаешь нихрена и постепенно...
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

привычней настраивать с миганием... какие разряды мигают - те и настраиваем
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Встал на лапы
Аватара пользователя
Сообщения: 118
Зарегистрирован: Вт апр 21, 2020 07:44:24
Откуда: Сумы, Украина

Сообщение Alek_von_German »

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3863754#p3863754"]привычней настраивать с миганием... какие разряды мигают - те и настраиваем[/uquote] Об этом тоже думал, скорее всего так и сделаю. Денёк еще помучаюсь)))
Хочется всё и сразу, а получаешь нихрена и постепенно...
Друг Кота
Аватара пользователя
Сообщения: 15592
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Четыре кнопки:
+
-
ввод
сброс/отмена
Возможна и спецкомбинация для активации режима настроек (N кноп одновременно и/или зажатая при подаче питания кнопа).
Далее два - три индикатора для отображения указателя позиции в меню настроек
к примеру J1-JF
и четыре позиции под индикацию, в каждой из которых задействованы кнопки +/- как в режиме единичного нажатия, так и в режиме скоростного приращения (короткое/длительное удержание), прокручивающие параметр по кольцу с учетом ограничений для каждого из параметров. Возможно дробление "единого значения" на составляющие, к примеру - текущее время на часы, минуты и секунды.
Подтверждение/сброс прокручивают таблицу менюшек по кругу.
В самом перечне менюшек включена позиция выхода из настроек (или автовыход при отсутствии активации кноп определенное время).
Ну и не исключено применение "вложенных менюшек".
Как вариант в адуринке - сменный указатель на функцию в цикле swith/case селектора комбинации клавиатуры.
8)
В принципе это ТВОРЧЕСТВО АВТОРА ПРОЕКТА - каждый делает так, как считает лучшим для восприятия пользователя устройства.
:beer:
Встал на лапы
Аватара пользователя
Сообщения: 118
Зарегистрирован: Вт апр 21, 2020 07:44:24
Откуда: Сумы, Украина

Сообщение Alek_von_German »

Та я бы и не против так сделать. Просто, туго соображаю, как это программно сделать. До сих пор не выходит заставить мигать разряды. А на счёт комбинаций клавиш это интересно, тем более я и не думал даже об этом.
Хочется всё и сразу, а получаешь нихрена и постепенно...
Самсусамыч

Сообщение Самсусамыч »

[uquote="Alek_von_German",url="/forum/viewtopic.php?p=3863865#p3863865"]До сих пор не выходит заставить мигать разряды.[/uquote]
Ну это не сложно… вот как один из вариантов… у DS3231 есть вывод SQW который можно настроить на 1 Гц. Так вот данный сигнал подать на ногу МК и при необходимости (когда нужно мигать циферками) отслеживать данный сигнал и по его значению или выводить текущую цифру, или пропускать разряд не зажигая его. Тем самым получаем мигание разряда с частотой 1 Гц. :)
Друг Кота
Аватара пользователя
Сообщения: 15592
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Динамическая индикация обычно совмещается со сканером клавиатуры (побочный эфект - сколько разрядов, столько и кнопок).
Вывод на индикацию выполняется из буфера ОЗУ овидеопамяти, помимо которого может иметься буфер предобработки.
Через определенное время в соответствующие позиции выводим бланкирующий код, затем восстанавливаем предшественник из буфера предобработки.
Можно и два буфера видео ОЗУ ставить, включив в программу регенерации попеременный вывод из каждого буфера (один с текущим кодом отображения, второй с бланк-кодами.
:roll:
Встал на лапы
Аватара пользователя
Сообщения: 118
Зарегистрирован: Вт апр 21, 2020 07:44:24
Откуда: Сумы, Украина

Сообщение Alek_von_German »

А зачем брать с ds- ки сигнал если мы можем просто тупо сравнивать с секундой вот так например if (sec&1){dot=dig[11]}

Добавлено after 1 minute 2 seconds:
Я таким образом секундную точку мигать заставил.

Добавлено after 6 hours 10 minutes 4 seconds:
Сделал мигание разрядами в настройках будильника и времени. Оказывается это не так и сложно.
Я делал через If-else

Код: Выделить всё

void blink_al_h4()
{
    
    if (setFlag==minute)
    {
        count_blink2++;
        if (count_blink2<300)
        {
            dig1=dig[d0] ;
            display[0] =  razr[0];
            display[1] = 0;
            
        }
        else if (count_blink2>300)
        {
            dig1=dig[d0] ;
            display[0] =  razr[0];
            display[1] =~ dig1;
            if (count_blink2>600)
            {
                count_blink2=0;
            }
            
        }

    }
    else
    {
        dig1=dig[d0] ;
        display[0] =  razr[0];
        display[1] =~ dig1;
    }
}
Хочется всё и сразу, а получаешь нихрена и постепенно...
Ответить

Вернуться в «AVR»