Например TDA7294

Форум РадиоКот • Просмотр темы - Регулятор для паяльника
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Вт июл 29, 2025 23:10:54

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 377 ]     ... , , , 15, , , ,  
Автор Сообщение
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 05:52:28 
Опытный кот
Аватар пользователя

Карма: 9
Рейтинг сообщений: 60
Зарегистрирован: Пт авг 31, 2018 21:53:52
Сообщений: 844
Откуда: ул. Островидова, общага напротив
Рейтинг сообщения: 0
Спасибо. Переделаю и отпишусь.

Добавлено after 49 seconds:
Уточните, какое максимальное время работы указать и на какое максимальное значение исправить?? От фонаря?

Добавлено after 5 minutes 5 seconds:
Извиняюсь, упустил.
Цитата:
Максимальное значение нужно исправить на необходимое, но не более 255.
- это для максимальное время работы указать и для максимальное значение?

_________________
Варкалось. Хливкие шорьки
Пырялись по нове,
И хрюкотали зелюки,
Как мюмзики в мове.

:)))


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 06:00:16 
Друг Кота
Аватар пользователя

Карма: 23
Рейтинг сообщений: 288
Зарегистрирован: Пт мар 09, 2007 15:01:52
Сообщений: 3078
Откуда: Биробиджан
Рейтинг сообщения: 1
Медали: 1
Получил миской по аватаре (1)
Да. Сейчас стоит максимум 60, но благодаря множителю 10, время работы получается 600 минут. Так как ты хочешь убрать множитель 10, то у тебя получится время 60 минут. Если ты поставишь туда скажем 120, то получишь время работы 2 часа, а если 255, то чуть больше 4 часов.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 06:02:24 
Опытный кот
Аватар пользователя

Карма: 9
Рейтинг сообщений: 60
Зарегистрирован: Пт авг 31, 2018 21:53:52
Сообщений: 844
Откуда: ул. Островидова, общага напротив
Рейтинг сообщения: 0
Это В функции проверки кнопок.
Код:
// В функции проверки кнопок
void key_action(void){
//....
    if (regim==ST_TIM_OFF){
        inc_dec_param(&Setting.TimOff, 255, 0, 1); // Вместо 60 указать максимальное время работы
//....    
А здесь что ставить?
Код:
// В функции проверки памяти
static void read_struct_eep(void){
//....
// Setting.TimOff исправить максимальное значение
if ( crc!= Setting.crc || Setting.TimOff > 60 // Здесь тоже 255 вместо 60 ?
                              || Setting.TimAlarm > 10 // Здесь тоже 255 вместо 10 ?
                              || Setting.TimAlarm == (Setting.TimOff*10)) // Здесь тоже 255 вместо 10 ?

//....

_________________
Варкалось. Хливкие шорьки
Пырялись по нове,
И хрюкотали зелюки,
Как мюмзики в мове.

:)))


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 06:09:07 
Друг Кота
Аватар пользователя

Карма: 23
Рейтинг сообщений: 288
Зарегистрирован: Пт мар 09, 2007 15:01:52
Сообщений: 3078
Откуда: Биробиджан
Рейтинг сообщения: 1
Медали: 1
Получил миской по аватаре (1)
Да, в проверке памяти то-же такое значение.
TimOff - это время отключения
TimAlarm - это время предупреждения. Это значение нужно править, только если ты изменишь максимально возможное время для предупреждения с 10 минут, на своё значение.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 06:29:58 
Опытный кот
Аватар пользователя

Карма: 9
Рейтинг сообщений: 60
Зарегистрирован: Пт авг 31, 2018 21:53:52
Сообщений: 844
Откуда: ул. Островидова, общага напротив
Рейтинг сообщения: 0
Уже понял.
Код:
// В функции проверки памяти
static void read_struct_eep(void){
//....
// Setting.TimOff исправить максимальное значение
if ( crc!= Setting.crc || Setting.TimOff > 255 // 255 вместо 60
                              || Setting.TimAlarm > 10
                              
|| Setting.TimAlarm == (Setting.TimOff*10))
//....
Здесь
Код:
inc_dec_param(&Setting.TimOff, 255, 0, 1); // Вместо 60 указать максимальное время работы 
и здесь
Код:
if ( crc!= Setting.crc || Setting.TimOff > 255 // 255 вместо 60 
значение
Код:
Setting.TimOff, 255
должно быть одно.

Добавлено after 49 seconds:
Цитата:
максимально возможное время для предупреждения с 10 минут, на своё значение
А условие здесь?
Код:
    if (regim==ST_TIM_ALARM){
        if (Setting.TimAlarm == 0) Setting.TimAlarm=1;
        if (Setting.TimOff==1){ // Максимальное время не более времени отключение и не более 10 минут
            MaxVol=9;
            if (Setting.TimOff*10 == Setting.TimAlarm) Setting.TimAlarm=MaxVol; 
            
}
MaxVol=9 без изменений или не больше TimAlarm? Т.е.,
Код:
MaxVol=TimAlarm-1; // максимальное значение может быть MaxVol <= TimAlarm-1 
?

Добавлено after 14 minutes 2 seconds:
сохранение настроек происходит каждый раз при переходе к следующему параметру
Если не заходить в настройки, а только перебирать пресеты, еепром тоже перезаписывается?

_________________
Варкалось. Хливкие шорьки
Пырялись по нове,
И хрюкотали зелюки,
Как мюмзики в мове.

:)))


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 06:57:41 
Друг Кота
Аватар пользователя

Карма: 23
Рейтинг сообщений: 288
Зарегистрирован: Пт мар 09, 2007 15:01:52
Сообщений: 3078
Откуда: Биробиджан
Рейтинг сообщения: 1
Медали: 1
Получил миской по аватаре (1)
if (regim==ST_TIM_ALARM) нужно полностью переписать, новый код я привёл. Там больше нет MavVol=9.
Код:

    
if (regim==ST_TIM_ALARM){
        if (
Setting.TimAlarm == 0Setting.TimAlarm=1;      
        if ((
Setting.TimOff <= Setting.TimAlarm) && (Setting.TimOff 10)){ // 10 - это максимальное время до предупреждения
            
MaxVol Setting.TimOff 1;
        }
        else{
            
MaxVol=10// это то-же максимальное время.
            
}
        
inc_dec_param(&Setting.TimAlarmMaxVol11);
        if (
Key==KEY_SET) {
            
save_struct_eep(); 
            
regim=ST_END;
            }        
        
Key=0;
        return;
        }
 

MaxVol самое большее может быть на единицу меньше времени выключения TimOff.

Если не заходить в настройки, то eeprom только читается.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 07:09:04 
Опытный кот
Аватар пользователя

Карма: 9
Рейтинг сообщений: 60
Зарегистрирован: Пт авг 31, 2018 21:53:52
Сообщений: 844
Откуда: ул. Островидова, общага напротив
Рейтинг сообщения: 0
Хм... Если
шаг таймера и так 1 минута, просто отображается как 10 и обрабатывается как 10, а хранится как 1 минута.
, то почему изменение отображения (при настройке?) с 10 на 1 не позволяет и дальше использовать 60*10 // 10 часов , а время уменьшилось до 255 // ~4 часов ? :dont_know:

На всякий случай...
Eeprom Update вместо Write
Подсмотрел здесь: EEPROM handling.

_________________
Варкалось. Хливкие шорьки
Пырялись по нове,
И хрюкотали зелюки,
Как мюмзики в мове.

:)))


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 07:33:10 
Друг Кота
Аватар пользователя

Карма: 23
Рейтинг сообщений: 288
Зарегистрирован: Пт мар 09, 2007 15:01:52
Сообщений: 3078
Откуда: Биробиджан
Рейтинг сообщения: 1
Медали: 1
Получил миской по аватаре (1)
Если в моём варианте в памяти сохранить число 255, то с множителем 10 мы получим 2550 минут или 42 часа. Поэтому я и ограничил на 10 часов.

Ты убираешь множитель 10 и соответственно даже при 255 в памяти, получишь 255 минут.

При описании я имел в виду что инкремент равен 1, а не 10 как отображается

Что касается eeprom.h, то он не используется и функция записи реализована иначе.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 09:26:07 
Опытный кот
Аватар пользователя

Карма: 9
Рейтинг сообщений: 60
Зарегистрирован: Пт авг 31, 2018 21:53:52
Сообщений: 844
Откуда: ул. Островидова, общага напротив
Рейтинг сообщения: 0
После правки шаг настройки отключения нагрузки стал 1 минута, но есть вопросы.
Код:
// В обоих строчка 600 заменить на 60
            if (++TimeOff>((Setting.TimOff*600*10)-(Setting.TimAlarm*60*10))){ // Задержка на начало мигания
                Flag|=MIGANIE;
                if (TimeOff>(Setting.TimOff*600*10)) PowerTmp=0;
1. 600 здесь как бы не в 2 строчках, а в трех.
2. Вместо 300 указать за какое время должна включиться пищалка, время в секундах умноженное на 10 - в каком формате - 6*10 или 60 (для 60 секунд)?
Код:
// Вместо 300 указать за какое время должна включиться пищалка, время в секундах умноженное на 10.
                if ( Blank && TimeOff>((Setting.TimOff*600*10)-300) ) ON(BUZZER);    else OFF(BUZZER);
Должно быть так?
Код:
// В обоих строчка 600 заменить на 60
            if (++TimeOff>((Setting.TimOff*60*10)-(Setting.TimAlarm*60*10))){ // Задержка на начало мигания
                Flag|=MIGANIE;
                if (TimeOff>(Setting.TimOff*60*10)) PowerTmp=0;
//...
// Вместо 300 указать за какое время должна включиться пищалка, время в секундах умноженное на 10.
                if ( Blank && TimeOff>((Setting.TimOff*600*10)-6*10) ) ON(BUZZER);    else OFF(BUZZER);
Почему везде 60 меняем на 255, а здесь 600 на 60?

Все правки (main.c).
Спойлер
Код:
// main.c
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h> /*F_CPU = 4000000; _delay_ms max = 65,535ms; _delay_us max = 192us */

#include "main.h"
#include "pin_macros.h" 

#define BCD_SIZEOF    5
#define LARGE_LIMIT_FI    145

#if defined (__AVR_ATmega8__)
#warning  ATmega8  4Meg
//4 Meg
    //1 1 The rising edge  //1 0 The falling edge of INT1 generates an interrupt request.
    //External Interrupt Request 0 Enable
#    define    EXT_ISR_ENABLE    GICR=_BV(INT0); \
                            MCUCR=(1<<ISC01)|(0<<ISC00);
#    define    PRESCALER_RESET    SFIOR|=_BV(PSR2)
#    define    OCR    OCR2
#    define    TIMER2_COMPARE    TIMER2_COMP_vect
#    define    EN_ISR_TIMER2_COMPARE    TIMSK=_BV(OCIE2)
#    define    TCCR2_INIT    TCCR2=(1<<CS22)|(1<<CS21)|(0<<CS20);// предделитель 256
#    define    R_TIFR    TIFR
#    define    OCR1A_INIT    OCR1A=4000;//время 1 милисекунда
#elif defined (__AVR_ATmega48__)
#warning  ATmega48 1 meg
// 1 meg
    //1 1 The rising edge  //1 0 The falling edge of INT1 generates an interrupt request.
    //External Interrupt Request 0 Enable
#    define    EXT_ISR_ENABLE    EIMSK=_BV(INT0); \
                            EICRA=(1<<ISC01)|(0<<ISC00);
#    define    PRESCALER_RESET    GTCCR|=_BV(PSRASY)    
#    define    OCR    OCR2A
#    define    TIMER2_COMPARE    TIMER2_COMPA_vect
#    define    EN_ISR_TIMER2_COMPARE    TIMSK2|=_BV(OCIE2A)
#    define    TCCR2_INIT    TCCR2B=(1<<CS22)|(0<<CS21)|(0<<CS20);// предделитель 64
#    define    R_TIFR    TIFR1
#    define    OCR1A_INIT    OCR1A=1000;//время 1 милисекунда
#elif defined (__AVR_ATmega168P__)
#warning  ATmega168p 8 meg
// 8 meg
    //1 1 The rising edge  //1 0 The falling edge of INT1 generates an interrupt request.
    //External Interrupt Request 0 Enable
#    define    EXT_ISR_ENABLE    EIMSK=_BV(INT0); \
                            EICRA=(1<<ISC01)|(0<<ISC00);
#    define    PRESCALER_RESET    GTCCR|=_BV(PSRASY)    
#    define    OCR    OCR2A
#    define    TIMER2_COMPARE    TIMER2_COMPA_vect
#    define    EN_ISR_TIMER2_COMPARE    TIMSK2|=_BV(OCIE2A)
#    define    TCCR2_INIT    TCCR2B=(1<<CS22)|(1<<CS21)|(0<<CS20);// предделитель 256
#    define    R_TIFR    TIFR1
#    define    OCR1A_INIT    OCR1A=4000;//время 1 милисекунда
#else
    #error "device type not defined"
#endif

ISR(INT0_vect)//прерывание по падующему фронту.
{
    PRESCALER_RESET;//SFIOR|=_BV(PSR2);// Bit 0 – PSR10: Prescaler Reset Timer/Counter1 and Timer/Counter0
    TCNT2=255;//!!!!
    OCR=TriacGate;
    FlagIsr=1;
    EnTriac=1;
}

ISR(TIMER2_COMPARE){//управляющий импульс на симистор
if (OCR<LARGE_LIMIT_FI){
    if (EnTriac) 
    ON
(TRIAC);
    _delay_us(25);
    OFF(TRIAC);
    }
}

static void avr_init(void)
{
    //TCCR0=_BV(CS00);
    TCCR1B=(1<<CS10)|(1<<WGM12);// ctc mode
    
    
//MCUCR=(1<<ISC01)|(0<<ISC00);//1 1 The rising edge  //1 0 The falling edge of INT1 generates an interrupt request.
    //GICR=_BV(INT0);//External Interrupt Request 0 Enable
    EXT_ISR_ENABLE;
    
    EN_ISR_TIMER2_COMPARE
;//TIMSK=_BV(OCIE2);
    OCR1A_INIT;//OCR1A=4000;//время 1 милисекунда
    OCR=220;//156 ~= 10mSek, 220 - за пределами полупериода, TCNT2 до этого значения не дойдет, будет сброшен в ISR(SIG_INTERRUPT0)
    TCCR2_INIT;//TCCR2=(1<<CS22)|(1<<CS21)|(0<<CS20);// предделитель 256
    

    DRIVER
(TRIAC,OUT);
    DRIVER(PIN_INT,PULLUP);
    
    DRIVER
(COM_DIG_0,OUT);
    DRIVER(COM_DIG_1,OUT);
    DRIVER(COM_DIG_2,OUT);
    
    DRIVER
(SEG_0,OUT);
    DRIVER(SEG_1,OUT);
    DRIVER(SEG_2,OUT);
    DRIVER(SEG_3,OUT);
    DRIVER(SEG_4,OUT);
    DRIVER(SEG_5,OUT);
    DRIVER(SEG_6,OUT);
    DRIVER(SEG_7,OUT);
    DRIVER(BUZZER,OUT);

    sei();

    return;
}

#if defined (__AVR_ATmega8__)
//----------
static inline unsigned char EEPROM_read(unsigned int uiAddress)
{
    while(EECR & (1<<EEWE));
    EEAR = uiAddress;
    EECR |= (1<<EERE);
    return EEDR;
}

static void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{
    if ( EEPROM_read(uiAddress)!=ucData){
        while(EECR & (1<<EEWE));
        cli();
        //asm("wdr");//сброс сторожевого таймера
        EEAR = uiAddress;
        EEDR = ucData;
        EECR |= (1<<EEMWE);
        EECR |= (1<<EEWE);
        sei();
        }
}
#else
static inline unsigned char EEPROM_read(unsigned int uiAddress)
{
    while(EECR & (1<<EEPE));
    EEAR = uiAddress;
    EECR |= (1<<EERE);
    return EEDR;
}
static void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{
    if ( EEPROM_read(uiAddress)!=ucData){
        while(EECR & (1<<EEPE));
        cli();
        asm("wdr");//сброс сторожевого таймера
        EEAR = uiAddress;
        EEDR = ucData;
        EECR |= (1<<EEMPE);
        EECR |= (1<<EEPE);
        sei();
        }
}
#endif

static void save_struct_eep(void)
{
    uint8_t * a= (uint8_t *)&Setting;
    Setting.crc=0;
        for(uint16_t j=0, i=EEP_ADR; j<sizeof(Setting); i++, j++, a++)
            {
            if (j<sizeof(Setting)-2) Setting.crc+=*a;
            EEPROM_write( i, *a);
            }
        eeprom_eer=0;
}

static void read_struct_eep(void)
{
    uint16_t crc=0;
    
    uint8_t 
*a= (uint8_t *)&Setting;
    for(uint16_t j=0, i=EEP_ADR; j<sizeof(Setting); i++, j++, a++)
        {*a=EEPROM_read(i);
        if (j<sizeof(Setting)-2) crc+=*a;
        }
#warning правка 1 Setting.TimOff > 60 исправить максимальное значение на 255
    if ( crc!= Setting.crc || Setting.TimOff > 255 || Setting.TimAlarm > 10 || Setting.TimAlarm == (Setting.TimOff*10)) {
        eeprom_eer=1;
        Setting.IncPower=1;
        Setting.TimOff=1;
        Setting.TimAlarm=1;
        }
        else
        
{
        LargeLimitReg=100;
        if (Setting.RegimFi) //if Fi
            if (Setting.FiNumView) LargeLimitReg=LARGE_LIMIT_FI;// if Num
        }
}

static void led_off(void)
{
    //потушили цифру
    OFF(COM_DIG_0);
    OFF(COM_DIG_1);
    OFF(COM_DIG_2);
    
    OFF
(SEG_0);
    OFF(SEG_1);
    OFF(SEG_2);
    OFF(SEG_3);
    OFF(SEG_4);
    OFF(SEG_5);
    OFF(SEG_6);
    OFF(SEG_7);
}

//----------
static void led_on(void)
{
    if ( led_buffer[znmesto] & _BV(0) ) ON(SEG_0);
    if ( led_buffer[znmesto] & _BV(1) ) ON(SEG_1);
    if ( led_buffer[znmesto] & _BV(2) ) ON(SEG_2);
    if ( led_buffer[znmesto] & _BV(3) ) ON(SEG_3);
    if ( led_buffer[znmesto] & _BV(4) ) ON(SEG_4);
    if ( led_buffer[znmesto] & _BV(5) ) ON(SEG_5);
    if ( led_buffer[znmesto] & _BV(6) ) ON(SEG_6);
    if ( led_buffer[znmesto] & _BV(7) ) ON(SEG_7);

    if ( znmesto==)    ON(COM_DIG_0);
    else
    if 
( znmesto==)    ON(COM_DIG_1);
    else
    if 
( znmesto==)    ON(COM_DIG_2);
}

//----------
static void skan_key(void){
// 4mSek
    //Key=KEY_VOID;

#ifdef KATOD
    PORT_BUTTON |= BTNS_PULLUP;
#else
    PORT_BUTTON &= ~COM_BTN; 
#endif
    DDR_BUTTON &= ~BTNS_PULLUP;
    _delay_us(15);
    uint8_t pin=PIN_BUTTON;
#ifdef KATOD
    PORT_BUTTON &= ~BTNS_PULLUP;
#else
    PORT_BUTTON |= COM_BTN;
#endif
    DDR_BUTTON |= BTNS_PULLUP;
    
//----------
#define KEY_PRESS(Key)    ((pin & (Key))==0)
//----------    
    //static uint8_t antdr, count_press, povtor;
    if ( KEY_PRESS(BTN_PLUS) || KEY_PRESS(BTN_MINUS) || KEY_PRESS(BTN_SET) ){// была нажата любая кнопка 
        if ( antdr>=pause_after_press[count_press] ) antdr=0;
        
        if 
(++antdr==3){
            //if ( KEY_PRESS(BTN_PLUS ) && KEY_PRESS(BTN_MINUS) )
            //    Key=KEY_OBE;
            //else
            if ( KEY_PRESS(BTN_PLUS) )
                Key=KEY_PLUS;
            if ( KEY_PRESS(BTN_MINUS ) )
                Key|=KEY_MINUS;
            if ( KEY_PRESS(BTN_SET ) ){
                Key|=KEY_SET;
                ViewReg=10;
                Flag|=VIEWREG;
                }
                
            if 
(count_press<sizeof(pause_after_press)-1) count_press++;
            if (++povtor>=sizeof(pause_after_press)+20) Inc=3;
            TimeState=200;
            }
        }
        else{
        Key=KEY_VOID;
        antdr=count_press=povtor=0;
        Inc=1;
        }
}

void inc_dec_param(uint8_t *p, uint8_t max, uint8_t min, uint8_t inc){    
    if 
(Key==KEY_PLUS){
        if ( ((*p)+inc)<=max ) (*p)+=inc; else (*p)=min;
        }
    if (Key==KEY_MINUS){
        if ( ((*p)-inc)>=min ) (*p)-=inc; else (*p)=max;
        }
}

//----------
void key_action(void){

    if (Key) {//если экран мигает и нажата кнопка, то отменить таймер откл, и выйти из ф. без обработки кнопки
        TimeOff=0;
        if (Flag & MIGANIE) {
            Flag &= ~MIGANIE;
            Blank=0;
            Key=0;
            return;
            }
        }
    
    if 
(regim==0){
        if (Key&KEY_SET) 
            regim
=ST_INPUT_REG;
            else
            inc_dec_param
(&PowerTmp, LargeLimitReg, 0, Inc+(Setting.IncPower-1));
        Key=0;
        return;
        }
    
    if 
(regim==ST_INPUT_REG){
        if (povtor>0){// povtor - кнопка удерживается (долгое нажатие)
            if (povtor>2) {
                regim=ST_INPUT_TIP_REG; 
                Var
=ST_TIP_REG;
                }
            if ( (Key&(KEY_SET|KEY_MINUS)) == (KEY_SET|KEY_MINUS) ) {
                PowerTmp=0;
                regim=ST_INPUT_TIP_REG; 
                Var
=0;
                }
            if ( (Key&(KEY_SET|KEY_PLUS)) == (KEY_SET|KEY_PLUS) ) {
                PowerTmp=LargeLimitReg;
                regim=ST_INPUT_TIP_REG; 
                Var
=0;
                }
            }
            else
            
{ 
            if 
(Key==KEY_VOID) regim=ST_PRESET;
            }
        return;
        }
    
    if 
(regim==ST_INPUT_TIP_REG){
        if (Key==KEY_VOID) {
            Flag &= ~VIEWREG;
            regim=Var;
            } 
        return
;
        }
    
    if 
(regim==ST_TIP_REG){
        inc_dec_param(&Setting.RegimFi, 1, 0, 1);
        if (Key==KEY_SET){ 
            StepPreset
=NUM_PRESET-1;//настраиваем счетчик пресетов, что бы при выходе по первому нажатию рег вкл на 1-е значение
            PowerTmp=0;//выключаем управление симистором
            save_struct_eep();
            if (Setting.RegimFi) regim=ST_SET_VIEW_FI;
                else  {Var=0; regim=ST_SETTING_PRESET;}
            }
        Key=0;
        return;
        }
    
    if 
(regim==ST_SET_VIEW_FI){
        inc_dec_param(&Setting.FiNumView, 1, 0, 1);
        if (Key==KEY_SET) {
            save_struct_eep(); 
            Var
=0; 
            regim
=ST_SETTING_PRESET;
            }
        Key=0;
        return;
        }
    
    if 
( Key & (KEY_PLUS|KEY_MINUS))//выход и обнуление(завершение) режима названия параметра
        if (Flag & VIEWREG) {
            Flag &= ~VIEWREG;
            Key=0;
            return;
            }
            
    if 
(regim==ST_SETTING_PRESET){
        uint8_t P=0;
        LargeLimitReg=100; 
        if 
(Setting.RegimFi){ //if Fi
            if (Setting.FiNumView){ 
                LargeLimitReg
=LARGE_LIMIT_FI;
                P=NUM_PRESET;
                } 
                else 
                if 
(PowerTmp>100) PowerTmp=0;
            }
            else
            if 
(PowerTmp>100) PowerTmp=0;

        inc_dec_param(&Setting.Preset[Var+P], LargeLimitReg, 0, Inc);
        if (Key==KEY_SET) {
            if (++Var>=NUM_PRESET-1){
                Setting.Preset[NUM_PRESET-1]=Setting.Preset[NUM_PRESET*2-1]=0;//обнуляем последние значения Preset, для OFF
                regim=ST_INC_POWER;
                }
            save_struct_eep();
            }
        Key=0;
        return;
        }
    if (regim==ST_INC_POWER){
        inc_dec_param(&Setting.IncPower, 20, 1, 1);
    //    if (Setting.IncPower==0) Setting.IncPower=1;
        if (Key==KEY_SET) {
            save_struct_eep(); 
            regim
=ST_TIM_OFF;
            }
        Key=0;
        return;
        }
    if (regim==ST_TIM_OFF){
#warning правка 2 Вместо 60 указать максимальное время работы
        inc_dec_param(&Setting.TimOff, 255, 0, 1); // Ограничение максимального времени в 60*10 минут (10 часов)
        if (Setting.TimOff==0) Blank=0;
        if (Key==KEY_SET) {
            save_struct_eep(); 
            if 
(Setting.TimOff==0){
            //    Setting.TimAlarm=0;
                regim=ST_END;
                }
            else{
                regim=ST_TIM_ALARM;
                }
            }
        Key=0;
        return;
        }
/*----------
// Для отладки, Setting.TimOff еденицы минут 
    if (regim==ST_TIM_ALARM){
        if (Setting.TimOff>10){ // Максимальное время не более времени отключение и не более 10 минут 
            inc_dec_param(&Setting.TimAlarm, 10, 1); 
            }
        else{
            if (Setting.TimOff <= Setting.TimAlarm) Setting.TimAlarm=Setting.TimOff-1;
            inc_dec_param(&Setting.TimAlarm, Setting.TimOff-1, 1);
            }
        if (Setting.TimAlarm==0) Setting.TimAlarm=1;
        if (Key==KEY_SET) {
            save_struct_eep(); 
            regim=ST_END;
            }        
        Key=0;
        return;
        }
----------*/
#warning правка 3 Условие времени таймера старое
/* 
    if (regim==ST_TIM_ALARM){
        if (Setting.TimAlarm == 0) Setting.TimAlarm=1;
        if (Setting.TimOff==1){ // Максимальное время не более времени отключение и не более 10 минут
            MaxVol=9;
            if (Setting.TimOff*10 == Setting.TimAlarm) Setting.TimAlarm=MaxVol; 
            }
        else{
            MaxVol=10;
            }
        inc_dec_param(&Setting.TimAlarm, MaxVol, 1, 1);
        if (Key==KEY_SET) {
            save_struct_eep(); 
            regim=ST_END;
            }        
        Key=0;
        return;
        }
    if (regim==ST_END){
        if ( Key || ((Flag&VIEWREG)==0) ) {
            Flag &= ~VIEWREG;
            regim=0;
            Key=0;
            }
        return;
        }
*/
// Условие времени таймера новое
    if (regim==ST_TIM_ALARM){
        if (Setting.TimAlarm == 0) Setting.TimAlarm=1;      
        if 
((Setting.TimOff <= Setting.TimAlarm) && (Setting.TimOff < 10)){
            MaxVol = Setting.TimOff - 1;
        }
        else{
            MaxVol=10;
            }
        inc_dec_param(&Setting.TimAlarm, MaxVol, 1, 1);
        if (Key==KEY_SET) {
            save_struct_eep(); 
            regim
=ST_END;
            }        
        Key
=0;
        return;
        }

// ----------

    //----------
    if (regim==ST_PRESET){
        if (++StepPreset>NUM_PRESET-1){
            StepPreset=0;
            }
        uint8_t P=0;
        if (Setting.RegimFi) //if Fi
            if (Setting.FiNumView){ 
                P
=NUM_PRESET;
                }
        PowerTmp=Setting.Preset[StepPreset+P];
        Flag &= ~VIEWREG;
        regim=0;
        Key=0;
        return;
        }
}


void itoa2(int16_t Val, uint8_t * Buf)
{
const uint16_t step[BCD_SIZEOF]={10000,1000,100,10,1};
#if BCD_SIZEOF != 5 
#warning *** BCD_SIZEOF!=sizeof(step)! ***
#endif
int16_t Subtract, Value;
uint8_t i, Dig;

    Value=Val;
    for (i=0; i<BCD_SIZEOF; i++)
    {
    Subtract=step[i];
    Dig=0;
    while(Value >= Subtract)
        {
        Dig++;
        Value-=Subtract;
        }
    Buf[i]=Dig;
    }
}

void data_led(void){
uint8_t buf[BCD_SIZEOF];
    led_buffer[0]=0;
    led_buffer[1]=0;
    led_buffer[2]=0;
    
    if 
((regim==0)||(regim==ST_PRESET)||(regim==ST_INPUT_REG)){
        if (eeprom_eer){
            led_buffer[0]=font[f_E];
            led_buffer[1]=font[f_E];
            led_buffer[2]=font[f_P];
            }
            else
            
{
            if (EnTriac==0){
                led_buffer[0]=font[f_n];
                led_buffer[1]=font[f_o];
                led_buffer[2]=font[f_C]|sH;
                }
            else
            if 
(PowerTmp==0){
                led_buffer[0]=sD;//font[0];
                led_buffer[1]=sD;//font[f_F];
                led_buffer[2]=sD;//font[f_F];
                }
                else{
                if (Blank==0)
                {
                itoa2(PowerTmp, buf);
                led_buffer[0]=font[buf[2]];
                led_buffer[1]=font[buf[3]];
                led_buffer[2]=font[buf[4]];
                }
                }
            }
        return;
        }
    
        
    if 
(regim==ST_INPUT_TIP_REG){
        if ( (Key&(KEY_SET|KEY_MINUS)) == (KEY_SET|KEY_MINUS) ) {
            led_buffer[0]=font[0];
            led_buffer[1]=font[f_F];
            led_buffer[2]=font[f_F];
            }
        else
        if 
( (Key&(KEY_SET|KEY_PLUS)) == (KEY_SET|KEY_PLUS) ) {
            led_buffer[0]=0;
            led_buffer[1]=font[f_o];
            led_buffer[2]=font[f_n];
            }
        else{
            led_buffer[0]=font[f_P];
            led_buffer[1]=font[f_E];
            led_buffer[2]=font[f_G];
        //    ON(BUZZER); // Звуковое оповещение о входе в настройки
            }
        return;
        }
    if (regim==ST_TIP_REG){
        if (Setting.RegimFi){
            led_buffer[1]=font[f_F];
            led_buffer[2]=font[f_I];
            }
            else{
            led_buffer[0]=font[f_P];
            led_buffer[1]=font[f_A];
            led_buffer[2]=font[f_U];
            }    
        return
;
        }    
    if 
(regim==ST_SET_VIEW_FI){
        if (Setting.FiNumView){
            led_buffer[0]=font[4];
            led_buffer[1]=font[f_U];
            led_buffer[2]=font[f_C];//ЧИС
            }
            else{
            led_buffer[0]=font[f_N];
            led_buffer[1]=font[f_P];
            led_buffer[2]=font[f_U]|sH;//ПРЦ
            }    
        return
;
        }
    
        
    if 
(regim==ST_SETTING_PRESET)//
        {
        if (Flag & VIEWREG)
            {
            led_buffer[0]=sG;
            led_buffer[1]=font[Var+1];
            led_buffer[2]=sG;
            }
            else{
            uint8_t P;
            if ((Setting.RegimFi) && (Setting.FiNumView)) P=NUM_PRESET; else P=0;
            itoa2(Setting.Preset[Var+P], buf);
            led_buffer[0]=font[buf[2]];
            led_buffer[1]=font[buf[3]];
            led_buffer[2]=font[buf[4]];
            }
        return;
        }
        
    if 
(regim==ST_INC_POWER)//
        {
        if (Flag & VIEWREG)
            {
            led_buffer[0]=font[f_i];
            led_buffer[1]=font[f_n];
            led_buffer[2]=font[f_c];
            }
            else{
            itoa2(Setting.IncPower, buf);
            //led_buffer[0]=font[buf[2]];
            led_buffer[1]=font[buf[3]];
            led_buffer[2]=font[buf[4]];
            }
        return;
        }
        
    if 
(regim==ST_TIM_OFF) // Таймер отключения нагрузки
        {
        if (Flag & VIEWREG)
            {
            led_buffer[0]=font[f_t];
            led_buffer[1]=font[0];
            led_buffer[2]=font[f_F];
            }
            else{
                itoa2(Setting.TimOff, buf);
#warning правка 4 исправить индикацию для режима настройки таймера отключения
//                led_buffer[0]=font[buf[3]];
//                led_buffer[1]=font[buf[4]];
//                led_buffer[2]=font[0];
// На вот такое
                led_buffer[0]=font[buf[2]];
                led_buffer[1]=font[buf[3]];
                led_buffer[2]=font[buf[4]];
            }
        return;
        }

    if (regim==ST_TIM_ALARM) // Таймер предупреждения
        {
        if (Flag & VIEWREG)
            {
            led_buffer[0]=font[f_t];
            led_buffer[1]=font[f_A];
            led_buffer[2]=font[f_L];
            }
            else{
            itoa2(Setting.TimAlarm, buf);
            led_buffer[1]=font[buf[3]];
            led_buffer[2]=font[buf[4]];
            }
        return;
        }
        
    if 
(regim==ST_END)//
        {
        led_buffer[0]=font[f_E];
        led_buffer[1]=font[f_n];
        led_buffer[2]=font[f_d];
        return;
        }
}

int main(void)
{
uint8_t TimeBlank=1;//Tim10msek=10,
uint8_t Tim100msek=10, TimLed=4,ChangePower=0;

avr_init();
read_struct_eep();
TriacGate=LARGE_LIMIT_FI;//выключен
OFF(BUZZER);//выключен по-умолчанию

while(1)
{


if (Setting.RegimFi==0)
{
// Режим пропуска периодов
    if (FlagIsr)
    {
    FlagIsr=0;
    //u8 Power; //требуемое значение мощности
    //Power = MyPower; //задаем требуемое значение мощности
    #define MAXPOW 100; //число, соотв. макс. мощности
    static uint8_t Phase = MAXPOW;//инициализация, делать 1 раз
    static int8_t Delta;

    //делать по вылавливанию перехода через 0:
    Delta = Power + Delta;
    if (Delta < 0)
        {
        TriacGate=LARGE_LIMIT_FI;//TriacOff();
        }
        else
        
{
        TriacGate=0;//TriacOn();
        Delta = Delta - MAXPOW;
        /*
            ON(TRIAC);
            _delay_us(10);
            OFF(TRIAC);*/
        }
    Phase = Phase - 1;
    if (Phase == 0)
        {
        Phase = MAXPOW;
        Delta = - (Phase / 2);
        }
    
    if 
(Power==0) {    TriacGate=LARGE_LIMIT_FI;}
    }
}

if (R_TIFR & _BV(OCF1A)) // 0.001 sek
    {
    R_TIFR = _BV(OCF1A);

    
    if 
( --TimLed==)// 
        {
        TimLed=4;
        led_off();// потушить цифру
        //asm("wdr");//сброс сторожевого таймера
        skan_key();
        key_action();
        led_on();// вкл. цифру
        if (++znmesto>=3)
            {
            znmesto=0x00;
            data_led();
            }
        }
    
    if 
(ChangePower!=PowerTmp){
        ChangePower=PowerTmp;
        //TimeOff=0;
        if (Setting.RegimFi) {//ФИ режим
            if (Setting.FiNumView==0){// если в процентах
                TriacGate=LARGE_LIMIT_FI-((LARGE_LIMIT_FI)*PowerTmp)/100;
                }
                else{
                TriacGate=LARGE_LIMIT_FI-PowerTmp;
                }
            }
            else{
            Power=PowerTmp;// Режим пропуска периодов
            }
        }
    {uint8_t tcnt2=TCNT2;
    if ( tcnt2>LARGE_LIMIT_FI+30){
        if ( tcnt2!=255)
            EnTriac=0;
        }
    }
        //if (Setting.RegimFi) TriacGate=Power;
    //----------=----------.1-Sek---------------------------------------
    if ( --Tim100msek==)    //0.1sek
        {
        OFF(BUZZER);//выключен
        Tim100msek=100;
        TimeState--;
        if (TimeState==0) regim=0;
        if (--ViewReg==0) Flag&=~VIEWREG;
        
        if 
(PowerTmp==0) StepPreset=NUM_PRESET-1;//настраиваем счетчик пресетов, что бы при выходе по первому нажатию рег вкл на 1-е значение
        
        if 
(Setting.TimOff>0) // Если задержка отключения больше ноля, то отрабатываем таймер
            {
            //-------Мигание_и_выключение------------
            if (PowerTmp)
            {
#warning правка 5 В обоих строчка 600 заменить на 60
            if (++TimeOff>((Setting.TimOff*60*10)-(Setting.TimAlarm*60*10))){ // Задержка на начало мигания
                Flag|=MIGANIE;
                if (TimeOff>(Setting.TimOff*60*10)) PowerTmp=0;//д.стоять ниже по коду if (ChangePower!=PowerTmp)
                if (--TimeBlank==0)
                    {
                    if ( Blank && TimeOff>((Setting.TimOff*600*10)-6*10) ) ON(BUZZER);    else OFF(BUZZER);
                    if ( Blank )
                        {// параметр будет виден
                        Blank=0;
                        TimeBlank=5;//0.5sek
                    //    ON(BUZZER); // 0.5sek
                        }
                    else
                        
{
                        Blank=1;
                        TimeBlank=2;
                    //    OFF(BUZZER); // 0.2 sec
                        }
                    }
                }
            }
            else{ 
            Blank
=0;
            TimeBlank=1;
            }
            }
        }    
    
    
}

}
    
С такими изменениями доходит до END и из режима настроек не выходит.

При настройке - может, сделать автоматический выход из режима настроек если ни одна кнопка не была нажата, скажем, в течение 10 секунд. Таким образом, изменив настройку, скажем, только пресета, можно остальные нстройки не листать и таким образом в еепром ничего лишнего не перезаписывать.

Компилировал для Atmega48.

В архиве протеус и main.c

Добавлено after 7 minutes 10 seconds:
Если
Цитата:
инкремент равен 1, а не 10 как отображается
, для чего менять общее время (60*10 на 255)? Просто изменить
Цитата:
10 как отображается
на 1 без изменения максимального времени отключения нагрузки нельзя? Понять это таки не могу.


Вложения:
Heater_Step1-01.zip [48.42 KiB]
Скачиваний: 214

_________________
Варкалось. Хливкие шорьки
Пырялись по нове,
И хрюкотали зелюки,
Как мюмзики в мове.

:)))
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 09:56:19 
Друг Кота
Аватар пользователя

Карма: 23
Рейтинг сообщений: 288
Зарегистрирован: Пт мар 09, 2007 15:01:52
Сообщений: 3078
Откуда: Биробиджан
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
1. 600 нужно править на 60 везде. То есть в трёх строчках.
2. Не имеет значение как запишешь, это просто математика и мне было удобней число разбить. Для 60 секунд надо писать 600. Основной цикла срабатывает каждые 100мс, потому и приходится всё умножать на 10 что-бы получить 1с.

Вначале 60 меняли на 255 птому что задавали максимальное значение. В моём варианте в TimOff хранятся десятки минут. Например если там 2, то значит 20 минут, если 5, то 50 минут.
В основном теле 60 это перевод из секунд в минут, а 600 переводит в десятки минут.
Код:
(Setting.TimOff*600*10)-(Setting.TimAlarm*60*10)

Вот этот кусок кода берёт то что записано в TimOff (время отключения) и переводит в десятки минут, а TimAlarm в еденицы минут. То есть если в TimOff будет записано 3, то контроллер поймёт что имеется в виду 30 минут, а если в TimAlarm 3 значит 3 минут.
Вот простой пример (я опущу поправку 100мс):
TimOff = 3; (записано в установках)
TimAlarm = 3; (записано в установках)
(3*600) - (3*60) = 1800 - 180 = 1620 секунд или 27 минут
Значит когда TimeOff (эта переменная постоянно увеличивается) намотает 1620 секунд начнётся мигание.

После блока if (regim==ST_TIM_ALARM) и перед if (regim==ST_PRESET) должен быть вот этот код, а ты его удалил
Код:

    if 
(regim==ST_END){
        if ( Key || ((Flag&VIEWREG)==0) ) {
            Flag &= ~VIEWREG;
            regim=0;
            Key=0;
            }
        return;
        }


Если ты оставишь максимальное значение времени работы 60, то твой нагреватель будет работать максимум 60 минут. Это математика.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 10:17:05 
Опытный кот
Аватар пользователя

Карма: 9
Рейтинг сообщений: 60
Зарегистрирован: Пт авг 31, 2018 21:53:52
Сообщений: 844
Откуда: ул. Островидова, общага напротив
Рейтинг сообщения: 0
Да, не там закрыл комментарий, извините.
Цитата:
1. 600 нужно править на 60 везде. То есть в трёх строчках.
2. Не имеет значение как запишешь, это просто математика и мне было удобней число разбить. Для 60 секунд надо писать 600.
Да, но если записать так:
Код:
#warning правка 5 В обоих строчка 600 заменить на 60
            if (++TimeOff>((Setting.TimOff*60*10)-(Setting.TimAlarm*60*10))){ // Задержка на начало мигания
                Flag|=MIGANIE;
                if (TimeOff>(Setting.TimOff*60*10)) PowerTmp=0;//д.стоять ниже по коду if (ChangePower!=PowerTmp)
                if (--TimeBlank==0)
                    {
                    if ( Blank && TimeOff>((Setting.TimOff*60*10)-60*10) ) ON(BUZZER);    else OFF(BUZZER);
                    if ( Blank )
То (Setting.TimOff*60*10)-(Setting.TimAlarm*60*10) даст 0 (?) .

_________________
Варкалось. Хливкие шорьки
Пырялись по нове,
И хрюкотали зелюки,
Как мюмзики в мове.

:)))


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 10:30:43 
Друг Кота
Аватар пользователя

Карма: 23
Рейтинг сообщений: 288
Зарегистрирован: Пт мар 09, 2007 15:01:52
Сообщений: 3078
Откуда: Биробиджан
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
В первом случае ноля не будет, так как благодаря MaxVol = Setting.TimOff - 1; значение TimAlarm всегда на единицу меньше времени отключения.
Во втором случае если время отключения выставлено 1 минута, то он даже мигать не будет, если две минуты, то будет мигать и пищать одновременно. При больших значениях сначала будет мигать, а потом ещё и пищать.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 10:48:59 
Опытный кот
Аватар пользователя

Карма: 9
Рейтинг сообщений: 60
Зарегистрирован: Пт авг 31, 2018 21:53:52
Сообщений: 844
Откуда: ул. Островидова, общага напротив
Рейтинг сообщения: 0
Если так:
- задаем время отключения нагрузки 2 мин;
- задаем продолжительность аларма 1 мин;
- код:
Код:
#warning правка 5 В обоих строчках 600 заменить на 60
            if (++TimeOff>((Setting.TimOff*60*10)-(Setting.TimAlarm*60*10))){ // Задержка на начало мигания
                Flag|=MIGANIE;
                if (TimeOff>(Setting.TimOff*60*10)) PowerTmp=0;//д.стоять ниже по коду if (ChangePower!=PowerTmp)
                if (--TimeBlank==0)
                    {
#warning правка 6 вместо 300 указать за какое время должна включиться пищалка, время в секундах умноженное на 10
                    if ( Blank && TimeOff>((Setting.TimOff*60*10)-60*10) ) ON(BUZZER);    else OFF(BUZZER);
- отрабатывает 2 минуты но нагрузку не отключает, начинает мигать таймер аларма, нагрузку отключает после отключения мигания аларма на протяжении 1 минуты, т.е., время, заданное для таймера отключения нагрузки суммируется с временем таймера отключения аларма.

Добавлено after 38 seconds:
Так в протеусе, если с правкой все правильно, прошью в железе.

Добавлено after 16 minutes 10 seconds:
Проверил несколько раз:
- таймер 2
- аларм 1
- начало мигания - через 75 сек после включения
- отключение - через 2 мин 30 сек после включения (включая время мигания аларма).
Код.
Спойлер
Код:
// !!! в main.h задати час в роботі !!! поточний час - 2 хвилини !!!
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h> /*F_CPU = 4000000; _delay_ms max = 65,535ms; _delay_us max = 192us */

#include "main.h"
#include "pin_macros.h" 

#define BCD_SIZEOF    5
#define LARGE_LIMIT_FI    145

#if defined (__AVR_ATmega8__)
#warning  ATmega8  4Meg
//4 Meg
    //1 1 The rising edge  //1 0 The falling edge of INT1 generates an interrupt request.
    //External Interrupt Request 0 Enable
#    define    EXT_ISR_ENABLE    GICR=_BV(INT0); \
                            MCUCR=(1<<ISC01)|(0<<ISC00);
#    define    PRESCALER_RESET    SFIOR|=_BV(PSR2)
#    define    OCR    OCR2
#    define    TIMER2_COMPARE    TIMER2_COMP_vect
#    define    EN_ISR_TIMER2_COMPARE    TIMSK=_BV(OCIE2)
#    define    TCCR2_INIT    TCCR2=(1<<CS22)|(1<<CS21)|(0<<CS20);// предделитель 256
#    define    R_TIFR    TIFR
#    define    OCR1A_INIT    OCR1A=4000;//время 1 милисекунда
#elif defined (__AVR_ATmega48__)
#warning  ATmega48 1 meg
// 1 meg
    //1 1 The rising edge  //1 0 The falling edge of INT1 generates an interrupt request.
    //External Interrupt Request 0 Enable
#    define    EXT_ISR_ENABLE    EIMSK=_BV(INT0); \
                            EICRA=(1<<ISC01)|(0<<ISC00);
#    define    PRESCALER_RESET    GTCCR|=_BV(PSRASY)    
#    define    OCR    OCR2A
#    define    TIMER2_COMPARE    TIMER2_COMPA_vect
#    define    EN_ISR_TIMER2_COMPARE    TIMSK2|=_BV(OCIE2A)
#    define    TCCR2_INIT    TCCR2B=(1<<CS22)|(0<<CS21)|(0<<CS20);// предделитель 64
#    define    R_TIFR    TIFR1
#    define    OCR1A_INIT    OCR1A=1000;//время 1 милисекунда
#elif defined (__AVR_ATmega168P__)
#warning  ATmega168p 8 meg
// 8 meg
    //1 1 The rising edge  //1 0 The falling edge of INT1 generates an interrupt request.
    //External Interrupt Request 0 Enable
#    define    EXT_ISR_ENABLE    EIMSK=_BV(INT0); \
                            EICRA=(1<<ISC01)|(0<<ISC00);
#    define    PRESCALER_RESET    GTCCR|=_BV(PSRASY)    
#    define    OCR    OCR2A
#    define    TIMER2_COMPARE    TIMER2_COMPA_vect
#    define    EN_ISR_TIMER2_COMPARE    TIMSK2|=_BV(OCIE2A)
#    define    TCCR2_INIT    TCCR2B=(1<<CS22)|(1<<CS21)|(0<<CS20);// предделитель 256
#    define    R_TIFR    TIFR1
#    define    OCR1A_INIT    OCR1A=4000;//время 1 милисекунда
#else
    #error "device type not defined"
#endif

ISR(INT0_vect)//прерывание по падующему фронту.
{
    PRESCALER_RESET;//SFIOR|=_BV(PSR2);// Bit 0 – PSR10: Prescaler Reset Timer/Counter1 and Timer/Counter0
    TCNT2=255;//!!!!
    OCR=TriacGate;
    FlagIsr=1;
    EnTriac=1;
}

ISR(TIMER2_COMPARE){//управляющий импульс на симистор
if (OCR<LARGE_LIMIT_FI){
    if (EnTriac) 
    ON
(TRIAC);
    _delay_us(25);
    OFF(TRIAC);
    }
}

static void avr_init(void)
{
    //TCCR0=_BV(CS00);
    TCCR1B=(1<<CS10)|(1<<WGM12);// ctc mode
    
    
//MCUCR=(1<<ISC01)|(0<<ISC00);//1 1 The rising edge  //1 0 The falling edge of INT1 generates an interrupt request.
    //GICR=_BV(INT0);//External Interrupt Request 0 Enable
    EXT_ISR_ENABLE;
    
    EN_ISR_TIMER2_COMPARE
;//TIMSK=_BV(OCIE2);
    OCR1A_INIT;//OCR1A=4000;//время 1 милисекунда
    OCR=220;//156 ~= 10mSek, 220 - за пределами полупериода, TCNT2 до этого значения не дойдет, будет сброшен в ISR(SIG_INTERRUPT0)
    TCCR2_INIT;//TCCR2=(1<<CS22)|(1<<CS21)|(0<<CS20);// предделитель 256
    

    DRIVER
(TRIAC,OUT);
    DRIVER(PIN_INT,PULLUP);
    
    DRIVER
(COM_DIG_0,OUT);
    DRIVER(COM_DIG_1,OUT);
    DRIVER(COM_DIG_2,OUT);
    
    DRIVER
(SEG_0,OUT);
    DRIVER(SEG_1,OUT);
    DRIVER(SEG_2,OUT);
    DRIVER(SEG_3,OUT);
    DRIVER(SEG_4,OUT);
    DRIVER(SEG_5,OUT);
    DRIVER(SEG_6,OUT);
    DRIVER(SEG_7,OUT);
    DRIVER(BUZZER,OUT);

    sei();

    return;
}

#if defined (__AVR_ATmega8__)
//----------
static inline unsigned char EEPROM_read(unsigned int uiAddress)
{
    while(EECR & (1<<EEWE));
    EEAR = uiAddress;
    EECR |= (1<<EERE);
    return EEDR;
}

static void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{
    if ( EEPROM_read(uiAddress)!=ucData){
        while(EECR & (1<<EEWE));
        cli();
        //asm("wdr");//сброс сторожевого таймера
        EEAR = uiAddress;
        EEDR = ucData;
        EECR |= (1<<EEMWE);
        EECR |= (1<<EEWE);
        sei();
        }
}
#else
static inline unsigned char EEPROM_read(unsigned int uiAddress)
{
    while(EECR & (1<<EEPE));
    EEAR = uiAddress;
    EECR |= (1<<EERE);
    return EEDR;
}
static void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{
    if ( EEPROM_read(uiAddress)!=ucData){
        while(EECR & (1<<EEPE));
        cli();
        asm("wdr");//сброс сторожевого таймера
        EEAR = uiAddress;
        EEDR = ucData;
        EECR |= (1<<EEMPE);
        EECR |= (1<<EEPE);
        sei();
        }
}
#endif

static void save_struct_eep(void)
{
    uint8_t * a= (uint8_t *)&Setting;
    Setting.crc=0;
        for(uint16_t j=0, i=EEP_ADR; j<sizeof(Setting); i++, j++, a++)
            {
            if (j<sizeof(Setting)-2) Setting.crc+=*a;
            EEPROM_write( i, *a);
            }
        eeprom_eer=0;
}

static void read_struct_eep(void)
{
    uint16_t crc=0;
    
    uint8_t 
*a= (uint8_t *)&Setting;
    for(uint16_t j=0, i=EEP_ADR; j<sizeof(Setting); i++, j++, a++)
        {*a=EEPROM_read(i);
        if (j<sizeof(Setting)-2) crc+=*a;
        }
#warning правка 1 Setting.TimOff > 60 исправить максимальное значение на 255
    if ( crc!= Setting.crc || Setting.TimOff > 255 || Setting.TimAlarm > 10 || Setting.TimAlarm == (Setting.TimOff*10)) {
        eeprom_eer=1;
        Setting.IncPower=1;
        Setting.TimOff=1;
        Setting.TimAlarm=1;
        }
        else
        
{
        LargeLimitReg=100;
        if (Setting.RegimFi) //if Fi
            if (Setting.FiNumView) LargeLimitReg=LARGE_LIMIT_FI;// if Num
        }
}

static void led_off(void)
{
    //потушили цифру
    OFF(COM_DIG_0);
    OFF(COM_DIG_1);
    OFF(COM_DIG_2);
    
    OFF
(SEG_0);
    OFF(SEG_1);
    OFF(SEG_2);
    OFF(SEG_3);
    OFF(SEG_4);
    OFF(SEG_5);
    OFF(SEG_6);
    OFF(SEG_7);
}

//----------
static void led_on(void)
{
    if ( led_buffer[znmesto] & _BV(0) ) ON(SEG_0);
    if ( led_buffer[znmesto] & _BV(1) ) ON(SEG_1);
    if ( led_buffer[znmesto] & _BV(2) ) ON(SEG_2);
    if ( led_buffer[znmesto] & _BV(3) ) ON(SEG_3);
    if ( led_buffer[znmesto] & _BV(4) ) ON(SEG_4);
    if ( led_buffer[znmesto] & _BV(5) ) ON(SEG_5);
    if ( led_buffer[znmesto] & _BV(6) ) ON(SEG_6);
    if ( led_buffer[znmesto] & _BV(7) ) ON(SEG_7);

    if ( znmesto==)    ON(COM_DIG_0);
    else
    if 
( znmesto==)    ON(COM_DIG_1);
    else
    if 
( znmesto==)    ON(COM_DIG_2);
}

//----------
static void skan_key(void){
// 4mSek
    //Key=KEY_VOID;

#ifdef KATOD
    PORT_BUTTON |= BTNS_PULLUP;
#else
    PORT_BUTTON &= ~COM_BTN; 
#endif
    DDR_BUTTON &= ~BTNS_PULLUP;
    _delay_us(15);
    uint8_t pin=PIN_BUTTON;
#ifdef KATOD
    PORT_BUTTON &= ~BTNS_PULLUP;
#else
    PORT_BUTTON |= COM_BTN;
#endif
    DDR_BUTTON |= BTNS_PULLUP;
    
//----------
#define KEY_PRESS(Key)    ((pin & (Key))==0)
//----------    
    //static uint8_t antdr, count_press, povtor;
    if ( KEY_PRESS(BTN_PLUS) || KEY_PRESS(BTN_MINUS) || KEY_PRESS(BTN_SET) ){// была нажата любая кнопка 
        if ( antdr>=pause_after_press[count_press] ) antdr=0;
        
        if 
(++antdr==3){
            //if ( KEY_PRESS(BTN_PLUS ) && KEY_PRESS(BTN_MINUS) )
            //    Key=KEY_OBE;
            //else
            if ( KEY_PRESS(BTN_PLUS) )
                Key=KEY_PLUS;
            if ( KEY_PRESS(BTN_MINUS ) )
                Key|=KEY_MINUS;
            if ( KEY_PRESS(BTN_SET ) ){
                Key|=KEY_SET;
                ViewReg=10;
                Flag|=VIEWREG;
                }
                
            if 
(count_press<sizeof(pause_after_press)-1) count_press++;
            if (++povtor>=sizeof(pause_after_press)+20) Inc=3;
            TimeState=200;
            }
        }
        else{
        Key=KEY_VOID;
        antdr=count_press=povtor=0;
        Inc=1;
        }
}

void inc_dec_param(uint8_t *p, uint8_t max, uint8_t min, uint8_t inc){    
    if 
(Key==KEY_PLUS){
        if ( ((*p)+inc)<=max ) (*p)+=inc; else (*p)=min;
        }
    if (Key==KEY_MINUS){
        if ( ((*p)-inc)>=min ) (*p)-=inc; else (*p)=max;
        }
}

//----------
void key_action(void){

    if (Key) {//если экран мигает и нажата кнопка, то отменить таймер откл, и выйти из ф. без обработки кнопки
        TimeOff=0;
        if (Flag & MIGANIE) {
            Flag &= ~MIGANIE;
            Blank=0;
            Key=0;
            return;
            }
        }
    
    if 
(regim==0){
        if (Key&KEY_SET) 
            regim
=ST_INPUT_REG;
            else
            inc_dec_param
(&PowerTmp, LargeLimitReg, 0, Inc+(Setting.IncPower-1));
        Key=0;
        return;
        }
    
    if 
(regim==ST_INPUT_REG){
        if (povtor>0){// povtor - кнопка удерживается (долгое нажатие)
            if (povtor>2) {
                regim=ST_INPUT_TIP_REG; 
                Var
=ST_TIP_REG;
                }
            if ( (Key&(KEY_SET|KEY_MINUS)) == (KEY_SET|KEY_MINUS) ) {
                PowerTmp=0;
                regim=ST_INPUT_TIP_REG; 
                Var
=0;
                }
            if ( (Key&(KEY_SET|KEY_PLUS)) == (KEY_SET|KEY_PLUS) ) {
                PowerTmp=LargeLimitReg;
                regim=ST_INPUT_TIP_REG; 
                Var
=0;
                }
            }
            else
            
{ 
            if 
(Key==KEY_VOID) regim=ST_PRESET;
            }
        return;
        }
    
    if 
(regim==ST_INPUT_TIP_REG){
        if (Key==KEY_VOID) {
            Flag &= ~VIEWREG;
            regim=Var;
            } 
        return
;
        }
    
    if 
(regim==ST_TIP_REG){
        inc_dec_param(&Setting.RegimFi, 1, 0, 1);
        if (Key==KEY_SET){ 
            StepPreset
=NUM_PRESET-1;//настраиваем счетчик пресетов, что бы при выходе по первому нажатию рег вкл на 1-е значение
            PowerTmp=0;//выключаем управление симистором
            save_struct_eep();
            if (Setting.RegimFi) regim=ST_SET_VIEW_FI;
                else  {Var=0; regim=ST_SETTING_PRESET;}
            }
        Key=0;
        return;
        }
    
    if 
(regim==ST_SET_VIEW_FI){
        inc_dec_param(&Setting.FiNumView, 1, 0, 1);
        if (Key==KEY_SET) {
            save_struct_eep(); 
            Var
=0; 
            regim
=ST_SETTING_PRESET;
            }
        Key=0;
        return;
        }
    
    if 
( Key & (KEY_PLUS|KEY_MINUS))//выход и обнуление(завершение) режима названия параметра
        if (Flag & VIEWREG) {
            Flag &= ~VIEWREG;
            Key=0;
            return;
            }
            
    if 
(regim==ST_SETTING_PRESET){
        uint8_t P=0;
        LargeLimitReg=100; 
        if 
(Setting.RegimFi){ //if Fi
            if (Setting.FiNumView){ 
                LargeLimitReg
=LARGE_LIMIT_FI;
                P=NUM_PRESET;
                } 
                else 
                if 
(PowerTmp>100) PowerTmp=0;
            }
            else
            if 
(PowerTmp>100) PowerTmp=0;

        inc_dec_param(&Setting.Preset[Var+P], LargeLimitReg, 0, Inc);
        if (Key==KEY_SET) {
            if (++Var>=NUM_PRESET-1){
                Setting.Preset[NUM_PRESET-1]=Setting.Preset[NUM_PRESET*2-1]=0;//обнуляем последние значения Preset, для OFF
                regim=ST_INC_POWER;
                }
            save_struct_eep();
            }
        Key=0;
        return;
        }
    if (regim==ST_INC_POWER){
        inc_dec_param(&Setting.IncPower, 20, 1, 1);
    //    if (Setting.IncPower==0) Setting.IncPower=1;
        if (Key==KEY_SET) {
            save_struct_eep(); 
            regim
=ST_TIM_OFF;
            }
        Key=0;
        return;
        }
    if (regim==ST_TIM_OFF){
#warning правка 2 Вместо 60 указать максимальное время работы
        inc_dec_param(&Setting.TimOff, 255, 0, 1); // Ограничение максимального времени в 60*10 минут (10 часов)
        if (Setting.TimOff==0) Blank=0;
        if (Key==KEY_SET) {
            save_struct_eep(); 
            if 
(Setting.TimOff==0){
            //    Setting.TimAlarm=0;
                regim=ST_END;
                }
            else{
                regim=ST_TIM_ALARM;
                }
            }
        Key=0;
        return;
        }
/*----------
// Для отладки, Setting.TimOff еденицы минут 
    if (regim==ST_TIM_ALARM){
        if (Setting.TimOff>10){ // Максимальное время не более времени отключение и не более 10 минут 
            inc_dec_param(&Setting.TimAlarm, 10, 1); 
            }
        else{
            if (Setting.TimOff <= Setting.TimAlarm) Setting.TimAlarm=Setting.TimOff-1;
            inc_dec_param(&Setting.TimAlarm, Setting.TimOff-1, 1);
            }
        if (Setting.TimAlarm==0) Setting.TimAlarm=1;
        if (Key==KEY_SET) {
            save_struct_eep(); 
            regim=ST_END;
            }        
        Key=0;
        return;
        }
----------*/
#warning правка 3 Условие времени таймера старое
/* 
    if (regim==ST_TIM_ALARM){
        if (Setting.TimAlarm == 0) Setting.TimAlarm=1;
        if (Setting.TimOff==1){ // Максимальное время не более времени отключение и не более 10 минут
            MaxVol=9;
            if (Setting.TimOff*10 == Setting.TimAlarm) Setting.TimAlarm=MaxVol; 
            }
        else{
            MaxVol=10;
            }
        inc_dec_param(&Setting.TimAlarm, MaxVol, 1, 1);
        if (Key==KEY_SET) {
            save_struct_eep(); 
            regim=ST_END;
            }        
        Key=0;
        return;
        }
*/
    if (regim==ST_END){
        if ( Key || ((Flag&VIEWREG)==0) ) {
            Flag &= ~VIEWREG;
            regim=0;
            Key=0;
            }
        return;
        }
// Условие времени таймера новое
    if (regim==ST_TIM_ALARM){
        if (Setting.TimAlarm == 0) Setting.TimAlarm=1;      
        if 
((Setting.TimOff <= Setting.TimAlarm) && (Setting.TimOff < 10)){
            MaxVol = Setting.TimOff - 1;
        }
        else{
            MaxVol=10;
            }
        inc_dec_param(&Setting.TimAlarm, MaxVol, 1, 1);
        if (Key==KEY_SET) {
            save_struct_eep(); 
            regim
=ST_END;
            }        
        Key
=0;
        return;
        }

// ----------

    //----------
    if (regim==ST_PRESET){
        if (++StepPreset>NUM_PRESET-1){
            StepPreset=0;
            }
        uint8_t P=0;
        if (Setting.RegimFi) //if Fi
            if (Setting.FiNumView){ 
                P
=NUM_PRESET;
                }
        PowerTmp=Setting.Preset[StepPreset+P];
        Flag &= ~VIEWREG;
        regim=0;
        Key=0;
        return;
        }
}


void itoa2(int16_t Val, uint8_t * Buf)
{
const uint16_t step[BCD_SIZEOF]={10000,1000,100,10,1};
#if BCD_SIZEOF != 5 
#warning *** BCD_SIZEOF!=sizeof(step)! ***
#endif
int16_t Subtract, Value;
uint8_t i, Dig;

    Value=Val;
    for (i=0; i<BCD_SIZEOF; i++)
    {
    Subtract=step[i];
    Dig=0;
    while(Value >= Subtract)
        {
        Dig++;
        Value-=Subtract;
        }
    Buf[i]=Dig;
    }
}

void data_led(void){
uint8_t buf[BCD_SIZEOF];
    led_buffer[0]=0;
    led_buffer[1]=0;
    led_buffer[2]=0;
    
    if 
((regim==0)||(regim==ST_PRESET)||(regim==ST_INPUT_REG)){
        if (eeprom_eer){
            led_buffer[0]=font[f_E];
            led_buffer[1]=font[f_E];
            led_buffer[2]=font[f_P];
            }
            else
            
{
            if (EnTriac==0){
                led_buffer[0]=font[f_n];
                led_buffer[1]=font[f_o];
                led_buffer[2]=font[f_C]|sH;
                }
            else
            if 
(PowerTmp==0){
                led_buffer[0]=sD;//font[0];
                led_buffer[1]=sD;//font[f_F];
                led_buffer[2]=sD;//font[f_F];
                }
                else{
                if (Blank==0)
                {
                itoa2(PowerTmp, buf);
                led_buffer[0]=font[buf[2]];
                led_buffer[1]=font[buf[3]];
                led_buffer[2]=font[buf[4]];
                }
                }
            }
        return;
        }
    
        
    if 
(regim==ST_INPUT_TIP_REG){
        if ( (Key&(KEY_SET|KEY_MINUS)) == (KEY_SET|KEY_MINUS) ) {
            led_buffer[0]=font[0];
            led_buffer[1]=font[f_F];
            led_buffer[2]=font[f_F];
            }
        else
        if 
( (Key&(KEY_SET|KEY_PLUS)) == (KEY_SET|KEY_PLUS) ) {
            led_buffer[0]=0;
            led_buffer[1]=font[f_o];
            led_buffer[2]=font[f_n];
            }
        else{
            led_buffer[0]=font[f_P];
            led_buffer[1]=font[f_E];
            led_buffer[2]=font[f_G];
        //    ON(BUZZER); // Звуковое оповещение о входе в настройки
            }
        return;
        }
    if (regim==ST_TIP_REG){
        if (Setting.RegimFi){
            led_buffer[1]=font[f_F];
            led_buffer[2]=font[f_I];
            }
            else{
            led_buffer[0]=font[f_P];
            led_buffer[1]=font[f_A];
            led_buffer[2]=font[f_U];
            }    
        return
;
        }    
    if 
(regim==ST_SET_VIEW_FI){
        if (Setting.FiNumView){
            led_buffer[0]=font[4];
            led_buffer[1]=font[f_U];
            led_buffer[2]=font[f_C];//ЧИС
            }
            else{
            led_buffer[0]=font[f_N];
            led_buffer[1]=font[f_P];
            led_buffer[2]=font[f_U]|sH;//ПРЦ
            }    
        return
;
        }
    
        
    if 
(regim==ST_SETTING_PRESET)//
        {
        if (Flag & VIEWREG)
            {
            led_buffer[0]=sG;
            led_buffer[1]=font[Var+1];
            led_buffer[2]=sG;
            }
            else{
            uint8_t P;
            if ((Setting.RegimFi) && (Setting.FiNumView)) P=NUM_PRESET; else P=0;
            itoa2(Setting.Preset[Var+P], buf);
            led_buffer[0]=font[buf[2]];
            led_buffer[1]=font[buf[3]];
            led_buffer[2]=font[buf[4]];
            }
        return;
        }
        
    if 
(regim==ST_INC_POWER)//
        {
        if (Flag & VIEWREG)
            {
            led_buffer[0]=font[f_i];
            led_buffer[1]=font[f_n];
            led_buffer[2]=font[f_c];
            }
            else{
            itoa2(Setting.IncPower, buf);
            //led_buffer[0]=font[buf[2]];
            led_buffer[1]=font[buf[3]];
            led_buffer[2]=font[buf[4]];
            }
        return;
        }
        
    if 
(regim==ST_TIM_OFF) // Таймер отключения нагрузки
        {
        if (Flag & VIEWREG)
            {
            led_buffer[0]=font[f_t];
            led_buffer[1]=font[0];
            led_buffer[2]=font[f_F];
            }
            else{
                itoa2(Setting.TimOff, buf);
#warning правка 4 исправить индикацию для режима настройки таймера отключения
//                led_buffer[0]=font[buf[3]];
//                led_buffer[1]=font[buf[4]];
//                led_buffer[2]=font[0];
// На вот такое
                led_buffer[0]=font[buf[2]];
                led_buffer[1]=font[buf[3]];
                led_buffer[2]=font[buf[4]];
            }
        return;
        }

    if (regim==ST_TIM_ALARM) // Таймер предупреждения
        {
        if (Flag & VIEWREG)
            {
            led_buffer[0]=font[f_t];
            led_buffer[1]=font[f_A];
            led_buffer[2]=font[f_L];
            }
            else{
            itoa2(Setting.TimAlarm, buf);
            led_buffer[1]=font[buf[3]];
            led_buffer[2]=font[buf[4]];
            }
        return;
        }
        
    if 
(regim==ST_END)//
        {
        led_buffer[0]=font[f_E];
        led_buffer[1]=font[f_n];
        led_buffer[2]=font[f_d];
        return;
        }
}

int main(void)
{
uint8_t TimeBlank=1;//Tim10msek=10,
uint8_t Tim100msek=10, TimLed=4,ChangePower=0;

avr_init();
read_struct_eep();
TriacGate=LARGE_LIMIT_FI;//выключен
OFF(BUZZER);//выключен по-умолчанию

while(1)
{


if (Setting.RegimFi==0)
{
// Режим пропуска периодов
    if (FlagIsr)
    {
    FlagIsr=0;
    //u8 Power; //требуемое значение мощности
    //Power = MyPower; //задаем требуемое значение мощности
    #define MAXPOW 100; //число, соотв. макс. мощности
    static uint8_t Phase = MAXPOW;//инициализация, делать 1 раз
    static int8_t Delta;

    //делать по вылавливанию перехода через 0:
    Delta = Power + Delta;
    if (Delta < 0)
        {
        TriacGate=LARGE_LIMIT_FI;//TriacOff();
        }
        else
        
{
        TriacGate=0;//TriacOn();
        Delta = Delta - MAXPOW;
        /*
            ON(TRIAC);
            _delay_us(10);
            OFF(TRIAC);*/
        }
    Phase = Phase - 1;
    if (Phase == 0)
        {
        Phase = MAXPOW;
        Delta = - (Phase / 2);
        }
    
    if 
(Power==0) {    TriacGate=LARGE_LIMIT_FI;}
    }
}

if (R_TIFR & _BV(OCF1A)) // 0.001 sek
    {
    R_TIFR = _BV(OCF1A);

    
    if 
( --TimLed==)// 
        {
        TimLed=4;
        led_off();// потушить цифру
        //asm("wdr");//сброс сторожевого таймера
        skan_key();
        key_action();
        led_on();// вкл. цифру
        if (++znmesto>=3)
            {
            znmesto=0x00;
            data_led();
            }
        }
    
    if 
(ChangePower!=PowerTmp){
        ChangePower=PowerTmp;
        //TimeOff=0;
        if (Setting.RegimFi) {//ФИ режим
            if (Setting.FiNumView==0){// если в процентах
                TriacGate=LARGE_LIMIT_FI-((LARGE_LIMIT_FI)*PowerTmp)/100;
                }
                else{
                TriacGate=LARGE_LIMIT_FI-PowerTmp;
                }
            }
            else{
            Power=PowerTmp;// Режим пропуска периодов
            }
        }
    {uint8_t tcnt2=TCNT2;
    if ( tcnt2>LARGE_LIMIT_FI+30){
        if ( tcnt2!=255)
            EnTriac=0;
        }
    }
        //if (Setting.RegimFi) TriacGate=Power;
    //----------=----------.1-Sek---------------------------------------
    if ( --Tim100msek==)    //0.1sek
        {
        OFF(BUZZER);//выключен
        Tim100msek=100;
        TimeState--;
        if (TimeState==0) regim=0;
        if (--ViewReg==0) Flag&=~VIEWREG;
        
        if 
(PowerTmp==0) StepPreset=NUM_PRESET-1;//настраиваем счетчик пресетов, что бы при выходе по первому нажатию рег вкл на 1-е значение
        
        if 
(Setting.TimOff>0) // Если задержка отключения больше ноля, то отрабатываем таймер
            {
            //-------Мигание_и_выключение------------
            if (PowerTmp)
            {
#warning правка 5 В обоих строчках 600 заменить на 60
            if (++TimeOff>((Setting.TimOff*60*10)-(Setting.TimAlarm*60*10))){ // Задержка на начало мигания
                Flag|=MIGANIE;
                if (TimeOff>(Setting.TimOff*60*10)) PowerTmp=0;//д.стоять ниже по коду if (ChangePower!=PowerTmp)
                if (--TimeBlank==0)
                    {
#warning правка 6 вместо 300 указать за какое время должна включиться пищалка, время в секундах умноженное на 10
                    if ( Blank && TimeOff>((Setting.TimOff*60*10)-60*10) ) ON(BUZZER);    else OFF(BUZZER);
                    if ( Blank )
                        {// параметр будет виден
                        Blank=0;
                        TimeBlank=5;//0.5sek
                    //    ON(BUZZER); // 0.5sek
                        }
                    else
                        
{
                        Blank=1;
                        TimeBlank=2;
                    //    OFF(BUZZER); // 0.2 sec
                        }
                    }
                }
            }
            else{ 
            Blank
=0;
            TimeBlank=1;
            }
            }
        }    
    
    
}

}
    
}

_________________
Варкалось. Хливкие шорьки
Пырялись по нове,
И хрюкотали зелюки,
Как мюмзики в мове.

:)))


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 11:00:29 
Друг Кота
Аватар пользователя

Карма: 23
Рейтинг сообщений: 288
Зарегистрирован: Пт мар 09, 2007 15:01:52
Сообщений: 3078
Откуда: Биробиджан
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Нет. Таймеры не складываются, а вычитаются.

Код:
if (++TimeOff>((Setting.TimOff*60*10)-(Setting.TimAlarm*60*10))) 

Как только внутренний счётчик TimeOff станет больше чем TimOff - TimAlarm, то включится мигание.

Код:
if (TimeOff>(Setting.TimOff*60*10)) PowerTmp=0

Как только TimeOff станет больше TimOff произойдёт выключение

Код:
if ( Blank && TimeOff>((Setting.TimOff*60*10)-60*10) ) ON(BUZZER);    else OFF(BUZZER); 

Если экран потушен (переменная Blank = 1) и TimeOff больше чем TimOff - 1 минуту, то включиться пищалка.

Вот так оно должно быть


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 11:10:15 
Опытный кот
Аватар пользователя

Карма: 9
Рейтинг сообщений: 60
Зарегистрирован: Пт авг 31, 2018 21:53:52
Сообщений: 844
Откуда: ул. Островидова, общага напротив
Рейтинг сообщения: 0
По факту работает все так же:
- таймер 2
- аларм 1
- начало мигания - через 75 сек после включения
- отключение - через 2 мин 30 сек после включения (включая время мигания аларма).

Возможно, особенности протеуса. Иду прошью железо.

По ходу, не подскажете, что за глюк у меня выскакивает с rm.exe ?

Изображение

Используется WinAVR-20100110, WinAVR8GnuToolchain.

Добавлено after 1 minute 56 seconds:
Протеус с пищалкой и исходник.


Вложения:
Heater_Step1-02.zip [49.35 KiB]
Скачиваний: 211

_________________
Варкалось. Хливкие шорьки
Пырялись по нове,
И хрюкотали зелюки,
Как мюмзики в мове.

:)))
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 11:20:17 
Друг Кота
Аватар пользователя

Карма: 23
Рейтинг сообщений: 288
Зарегистрирован: Пт мар 09, 2007 15:01:52
Сообщений: 3078
Откуда: Биробиджан
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Склоняюсь к варианту особенностей протеуса. По ошибке читай статью: https://geekon.media/oshibka-pri-zapusk ... xc0000142/


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 11:43:43 
Опытный кот
Аватар пользователя

Карма: 9
Рейтинг сообщений: 60
Зарегистрирован: Пт авг 31, 2018 21:53:52
Сообщений: 844
Откуда: ул. Островидова, общага напротив
Рейтинг сообщения: 0
Вы правы.

В железе.
Atmega48, тактирование внутреннее 1MHz. Общий катод.
Прошивка/исходник в архиве.

Настройки.
tOF - 4 мин.
tAL - 1 мин.

Результат:
- срабатывание таймера аларма - через 3 мин. после включения;
- отключение нагрузки - через 4 мин. после включения.

Спасибо :) .

Добавлено after 7 minutes 24 seconds:
Ту статью читал, как только проявился глюк, рекомендации делал, такое у меня только с rm.exe, Виндовс 8.1. Думал, тут что-то специфическое касаемо WinAVR.


Вложения:
Heater_Step1-03.zip [9.28 KiB]
Скачиваний: 196

_________________
Варкалось. Хливкие шорьки
Пырялись по нове,
И хрюкотали зелюки,
Как мюмзики в мове.

:)))
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 11:48:28 
Друг Кота
Аватар пользователя

Карма: 23
Рейтинг сообщений: 288
Зарегистрирован: Пт мар 09, 2007 15:01:52
Сообщений: 3078
Откуда: Биробиджан
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
У меня винда семёрка, от того и глюка нет.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 13:28:04 
Опытный кот
Аватар пользователя

Карма: 9
Рейтинг сообщений: 60
Зарегистрирован: Пт авг 31, 2018 21:53:52
Сообщений: 844
Откуда: ул. Островидова, общага напротив
Рейтинг сообщения: 0
Та тот глюк не сильно напрягает, пусть будет :) .
автоматический выход из режима настроек
оказывается, таки есть, из любого пункта настроек.
Время задержки для этого "автоматический выход из режима настроек", похоже, задается здесь:
Спойлер
Код:
//----------    
    //static uint8_t antdr, count_press, povtor;
    if ( KEY_PRESS(BTN_PLUS) || KEY_PRESS(BTN_MINUS) || KEY_PRESS(BTN_SET) ){// была нажата любая кнопка 
        if ( antdr>=pause_after_press[count_press] ) antdr=0;
        if (++antdr==3){
            //if ( KEY_PRESS(BTN_PLUS ) && KEY_PRESS(BTN_MINUS) )
            //    Key=KEY_OBE;
            //else
            if ( KEY_PRESS(BTN_PLUS) )
                Key=KEY_PLUS;
            if ( KEY_PRESS(BTN_MINUS ) )
                Key|=KEY_MINUS;
            if ( KEY_PRESS(BTN_SET ) ){
                Key|=KEY_SET;
                ViewReg=10;
                Flag|=VIEWREG;
                }
            if (count_press<sizeof(pause_after_press)-1) count_press++;
            if (++povtor>=sizeof(pause_after_press)+20) Inc=3;
// Время задержки до выхода из меню настроек ?
            TimeState=200; // line 274
            }
        }
// ...
//----------=----------.1-Sek---------------------------------------
    if ( --Tim100msek==)    //0.1sek
        {
        OFF(BUZZER);//выключен
        Tim100msek=100;
        TimeState--; // line 806
        if (TimeState==0) regim=0;
Больше это TimeState=200 ни на что не влияет? Хотя это вообще мелочь.

Вот это действительно ощутимая проблема:
Цитата:
сохранение настроек происходит каждый раз при переходе к следующему параметру


Добавлено after 54 minutes 33 seconds:
Прошивка для Atmega8 и индикатора с общим катодом.


Вложения:
Комментарий к файлу: m8_OK_step.hex
m8_OK_step.zip [3.6 KiB]
Скачиваний: 235

_________________
Варкалось. Хливкие шорьки
Пырялись по нове,
И хрюкотали зелюки,
Как мюмзики в мове.

:)))
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Регулятор для паяльника
СообщениеДобавлено: Чт июн 06, 2019 14:01:37 
Друг Кота
Аватар пользователя

Карма: 23
Рейтинг сообщений: 288
Зарегистрирован: Пт мар 09, 2007 15:01:52
Сообщений: 3078
Откуда: Биробиджан
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Судя по коду TimeState это задержка для входа в меню. А автоматического выхода я не наблюдаю.


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 377 ]     ... , , , 15, , , ,  

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: Oleg.normalniy и гости: 9


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y