Страница 15 из 19
Re: Регулятор для паяльника
Добавлено: Чт июн 06, 2019 05:52:28
webtime
Спасибо. Переделаю и отпишусь.
Добавлено after 49 seconds:
Уточните, какое
максимальное время работы указать и на какое
максимальное значение исправить?? От фонаря?
Добавлено after 5 minutes 5 seconds:
Извиняюсь, упустил.
Максимальное значение нужно исправить на необходимое, но не более 255.
- это для
максимальное время работы указать и для
максимальное значение?
Re: Регулятор для паяльника
Добавлено: Чт июн 06, 2019 06:00:16
radteh
Да. Сейчас стоит максимум 60, но благодаря множителю 10, время работы получается 600 минут. Так как ты хочешь убрать множитель 10, то у тебя получится время 60 минут. Если ты поставишь туда скажем 120, то получишь время работы 2 часа, а если 255, то чуть больше 4 часов.
Re: Регулятор для паяльника
Добавлено: Чт июн 06, 2019 06:02:24
webtime
Это
В функции проверки кнопок.
Код: Выделить всё
// В функции проверки кнопок
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
radteh
Да, в проверке памяти то-же такое значение.
TimOff - это время отключения
TimAlarm - это время предупреждения. Это значение нужно править, только если ты изменишь максимально возможное время для предупреждения с 10 минут, на своё значение.
Re: Регулятор для паяльника
Добавлено: Чт июн 06, 2019 06:29:58
webtime
Уже понял.
Код: Выделить всё
// В функции проверки памяти
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
значение
должно быть одно.
Добавлено 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:
[uquote="radteh",url="/forum/viewtopic.php?p=3646099#p3646099"]сохранение настроек происходит каждый раз при переходе к следующему параметру[/uquote]Если не заходить в настройки, а только перебирать пресеты, еепром тоже перезаписывается?
Re: Регулятор для паяльника
Добавлено: Чт июн 06, 2019 06:57:41
radteh
if (regim==ST_TIM_ALARM) нужно полностью переписать, новый код я привёл. Там больше нет MavVol=9.
Код: Выделить всё
if (regim==ST_TIM_ALARM){
if (Setting.TimAlarm == 0) Setting.TimAlarm=1;
if ((Setting.TimOff <= Setting.TimAlarm) && (Setting.TimOff < 10)){ // 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;
}
MaxVol самое большее может быть на единицу меньше времени выключения TimOff.
Если не заходить в настройки, то eeprom только читается.
Re: Регулятор для паяльника
Добавлено: Чт июн 06, 2019 07:09:04
webtime
Хм... Если[uquote="radteh",url="/forum/viewtopic.php?p=3642386#p3642386"]шаг таймера и так 1 минута, просто отображается как 10 и обрабатывается как 10, а хранится как 1 минута.[/uquote], то почему изменение отображения (при настройке?) с 10 на 1 не позволяет и дальше использовать
60*10 // 10 часов , а время уменьшилось до
255 // ~4 часов ?
На всякий случай...[uquote="webtime",url="/forum/viewtopic.php?p=3646102#p3646102"]Eeprom Update вместо Write[/uquote]Подсмотрел здесь: EEPROM handling.
Re: Регулятор для паяльника
Добавлено: Чт июн 06, 2019 07:33:10
radteh
Если в моём варианте в памяти сохранить число 255, то с множителем 10 мы получим 2550 минут или 42 часа. Поэтому я и ограничил на 10 часов.
Ты убираешь множитель 10 и соответственно даже при 255 в памяти, получишь 255 минут.
При описании я имел в виду что инкремент равен 1, а не 10 как отображается
Что касается eeprom.h, то он не используется и функция записи реализована иначе.
Re: Регулятор для паяльника
Добавлено: Чт июн 06, 2019 09:26:07
webtime
После правки шаг настройки отключения нагрузки стал 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__)
//-------------------EEPROM-------------------------
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==0 ) ON(COM_DIG_0);
else
if ( znmesto==1 ) ON(COM_DIG_1);
else
if ( znmesto==2 ) 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;
}
// ---------------------------------------------------------------------------------------------
//------------PRESET-------------------------
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==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;
//----------=-------------------0.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 без изменения максимального времени отключения нагрузки нельзя? Понять это таки не могу.
Re: Регулятор для паяльника
Добавлено: Чт июн 06, 2019 09:56:19
radteh
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
webtime
Да, не там закрыл комментарий, извините.
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
radteh
В первом случае ноля не будет, так как благодаря MaxVol = Setting.TimOff - 1; значение TimAlarm всегда на единицу меньше времени отключения.
Во втором случае если время отключения выставлено 1 минута, то он даже мигать не будет, если две минуты, то будет мигать и пищать одновременно. При больших значениях сначала будет мигать, а потом ещё и пищать.
Re: Регулятор для паяльника
Добавлено: Чт июн 06, 2019 10:48:59
webtime
Если так:
- задаем время отключения нагрузки 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__)
//-------------------EEPROM-------------------------
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==0 ) ON(COM_DIG_0);
else
if ( znmesto==1 ) ON(COM_DIG_1);
else
if ( znmesto==2 ) 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;
}
// ---------------------------------------------------------------------------------------------
//------------PRESET-------------------------
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==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;
//----------=-------------------0.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;
}
}
}
}
}
}
Re: Регулятор для паяльника
Добавлено: Чт июн 06, 2019 11:00:29
radteh
Нет. Таймеры не складываются, а вычитаются.
Код: Выделить всё
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
webtime
По факту работает все так же:
- таймер 2
- аларм 1
- начало мигания - через 75 сек после включения
- отключение - через 2 мин 30 сек после включения (включая время мигания аларма).
Возможно, особенности протеуса. Иду прошью железо.
По ходу, не подскажете, что за глюк у меня выскакивает с
rm.exe ?
Используется WinAVR-20100110, WinAVR8GnuToolchain.
Добавлено after 1 minute 56 seconds:
Протеус с пищалкой и исходник.
Re: Регулятор для паяльника
Добавлено: Чт июн 06, 2019 11:20:17
radteh
Склоняюсь к варианту особенностей протеуса. По ошибке читай статью:
https://geekon.media/oshibka-pri-zapusk ... xc0000142/
Re: Регулятор для паяльника
Добавлено: Чт июн 06, 2019 11:43:43
webtime
Вы правы.
В железе.
Atmega48, тактирование внутреннее 1MHz. Общий катод.
Прошивка/исходник в архиве.
Настройки.
tOF - 4 мин.
tAL - 1 мин.
Результат:
- срабатывание таймера аларма - через 3 мин. после включения;
- отключение нагрузки - через 4 мин. после включения.
Спасибо

.
Добавлено after 7 minutes 24 seconds:
Ту статью читал, как только проявился глюк, рекомендации делал, такое у меня только с
rm.exe, Виндовс 8.1. Думал, тут что-то специфическое касаемо
WinAVR.
Re: Регулятор для паяльника
Добавлено: Чт июн 06, 2019 11:48:28
radteh
У меня винда семёрка, от того и глюка нет.
Re: Регулятор для паяльника
Добавлено: Чт июн 06, 2019 13:28:04
webtime
Та тот глюк не сильно напрягает, пусть будет

.
[uquote="webtime",url="/forum/viewtopic.php?p=3646179#p3646179"]автоматический выход из режима настроек[/uquote]оказывается, таки есть, из любого пункта настроек.
Время задержки для этого "автоматический выход из режима настроек", похоже, задается здесь:
Спойлер
Код: Выделить всё
//---------------------------------------------------------------------------------------
//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
}
}
// ...
//----------=-------------------0.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 и индикатора с общим катодом.
Re: Регулятор для паяльника
Добавлено: Чт июн 06, 2019 14:01:37
radteh
Судя по коду TimeState это задержка для входа в меню. А автоматического выхода я не наблюдаю.