Да. Сейчас стоит максимум 60, но благодаря множителю 10, время работы получается 600 минут. Так как ты хочешь убрать множитель 10, то у тебя получится время 60 минут. Если ты поставишь туда скажем 120, то получишь время работы 2 часа, а если 255, то чуть больше 4 часов.
Карма: 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 ?
//.... }
_________________ Варкалось. Хливкие шорьки Пырялись по нове, И хрюкотали зелюки, Как мюмзики в мове.
Да, в проверке памяти то-же такое значение. TimOff - это время отключения TimAlarm - это время предупреждения. Это значение нужно править, только если ты изменишь максимально возможное время для предупреждения с 10 минут, на своё значение.
Карма: 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
шаг таймера и так 1 минута, просто отображается как 10 и обрабатывается как 10, а хранится как 1 минута.
, то почему изменение отображения (при настройке?) с 10 на 1 не позволяет и дальше использовать 60*10 // 10 часов , а время уменьшилось до 255 // ~4 часов ?
Карма: 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
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; } }
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==0 )// { 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 )//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 без изменения максимального времени отключения нагрузки нельзя? Понять это таки не могу.
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 минут. Это математика.
Карма: 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 (?) .
_________________ Варкалось. Хливкие шорьки Пырялись по нове, И хрюкотали зелюки, Как мюмзики в мове.
В первом случае ноля не будет, так как благодаря MaxVol = Setting.TimOff - 1; значение TimAlarm всегда на единицу меньше времени отключения. Во втором случае если время отключения выставлено 1 минута, то он даже мигать не будет, если две минуты, то будет мигать и пищать одновременно. При больших значениях сначала будет мигать, а потом ещё и пищать.
Карма: 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
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; } }
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==0 )// { 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 )//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; } } }
}
} }
_________________ Варкалось. Хливкие шорьки Пырялись по нове, И хрюкотали зелюки, Как мюмзики в мове.
Карма: 9
Рейтинг сообщений: 60
Зарегистрирован: Пт авг 31, 2018 21:53:52 Сообщений: 844 Откуда: ул. Островидова, общага напротив
Рейтинг сообщения:0
По факту работает все так же: - таймер 2 - аларм 1 - начало мигания - через 75 сек после включения - отключение - через 2 мин 30 сек после включения (включая время мигания аларма).
Возможно, особенности протеуса. Иду прошью железо.
По ходу, не подскажете, что за глюк у меня выскакивает с rm.exe ?
Используется WinAVR-20100110, WinAVR8GnuToolchain.
Добавлено after 1 minute 56 seconds: Протеус с пищалкой и исходник.
Карма: 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.
оказывается, таки есть, из любого пункта настроек. Время задержки для этого "автоматический выход из режима настроек", похоже, задается здесь:Спойлер
Код:
//---------- //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 )//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
_________________ Варкалось. Хливкие шорьки Пырялись по нове, И хрюкотали зелюки, Как мюмзики в мове.
Сейчас этот форум просматривают: Oleg.normalniy и гости: 9
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения