Конечно странно, а у кого так работает? У меня будет 1023 какой разряд не меняй, при одной проверке.
Эффективность функции?Работа с 16 бит числом.Atmega16.
- Сообщения: 2089
- Зарегистрирован: Вс июн 19, 2016 09:32:03
[uquote="ARV",url="/forum/viewtopic.php?p=3440417#p3440417"]я делал вообще не совсем так. при поразрядном редактировании было бы странно, если бы при числе 1023 при попытке изменить третий разряд мы получали 1024.[/uquote]
Конечно странно, а у кого так работает? У меня будет 1023 какой разряд не меняй, при одной проверке.
Конечно странно, а у кого так работает? У меня будет 1023 какой разряд не меняй, при одной проверке.
- Реклама
Не менее странно, когда при макс. значении в 5000 и текущем 4800, при редактировании старшего разряда, устройство будет игнорировать кнопку "Up". Или вообще перескакивать на "0". Юзер может встать в ступор
Палка о двух концах...
Палка о двух концах...
- Сообщения: 2089
- Зарегистрирован: Вс июн 19, 2016 09:32:03
[uquote="Аlex",url="/forum/viewtopic.php?p=3440458#p3440458"]Не менее странно, когда при макс. значении в 5000 и текущем 4800, при редактировании старшего разряда, устройство будет игнорировать кнопку "Up". Или вообще перескакивать на "0". Юзер может встать в ступор
[/uquote]
А чем старший разряд отличается от всех остальных? Юзер дойдет до 9 на младшем и впадет в ступор
А чем старший разряд отличается от всех остальных? Юзер дойдет до 9 на младшем и впадет в ступор
Фраза "Юзер может встать в ступор" предназначалась для первой половины поста, просто так нелогично всё склеилось
Представляю, если пользователь не будет знать максимального значения, какой нужно будет ему путь пройти
Представляю, если пользователь не будет знать максимального значения, какой нужно будет ему путь пройти
А зачем обязательно делать 1023? Не проще ли сделать 999 или 1999 ?
Вариант 2: если юзер пытается вылезти за предельное значение, подать звуковой сигнал ошибки, допустим, два коротких "пика" с коротким же интервалом между ними. Или взморгнуть дважды, опять же, быстро, всем числом, или соответствующим знакоместом.
А вообще, подобные ограничения иногда конкретно мешают - попробуйте, например, порулить шириной консольного окна винды. Ладно, перешел на закладку "Расположение" свойств консольного окна, текущая ширина выделена, набирай новую. Набираю, промазал в первую цифру. Естественная реакция - нажать забой и набрать правильную цифру. Ага, щаззз, как говорит молодёжь! Винда не дает забить эту цифру, ширина не может быть нулевой. С матюгами берешь мышь в правую руку...
Вариант 2: если юзер пытается вылезти за предельное значение, подать звуковой сигнал ошибки, допустим, два коротких "пика" с коротким же интервалом между ними. Или взморгнуть дважды, опять же, быстро, всем числом, или соответствующим знакоместом.
А вообще, подобные ограничения иногда конкретно мешают - попробуйте, например, порулить шириной консольного окна винды. Ладно, перешел на закладку "Расположение" свойств консольного окна, текущая ширина выделена, набирай новую. Набираю, промазал в первую цифру. Естественная реакция - нажать забой и набрать правильную цифру. Ага, щаззз, как говорит молодёжь! Винда не дает забить эту цифру, ширина не может быть нулевой. С матюгами берешь мышь в правую руку...
Последний раз редактировалось afz Вт авг 21, 2018 02:36:40, всего редактировалось 1 раз.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
- Реклама
Да, кстати. Бывают приложения под ББ, в которых нужно вводить числовое значение в текстбоксы. При этом, прога ограничивает его определённым диапазоном, пытаясь "помочь" юзеру, меняя значения при неправильном вводе. Очень хочется в глаза разрабу посмотреть в этот момент, выразив ему "благодарность". Думаешь, ну неужели нельзя было пропарсить строку после жмака на баттон "ОК" ? Что мешало ?
И тут также. Пользователя явно будет раздражать эта медвежья услуга . К гадалке не ходи.
Вот для ввода какого-нибудь секретного кода, или цифровой комбинации - самое то. Но не для параметров с ограничениями.
И тут также. Пользователя явно будет раздражать эта медвежья услуга . К гадалке не ходи.
Вот для ввода какого-нибудь секретного кода, или цифровой комбинации - самое то. Но не для параметров с ограничениями.
- Сообщения: 303
- Зарегистрирован: Ср май 03, 2017 03:22:26
Ост последняя фича. При удержании клавиши прибавлять\убавлять переменную пока не отпустят кнопку.
Раньше делал это путем проверки отпускания кнопки в цикле while(). Но тут так делать нельзя , т.к этим повешам динамичесскую индикацию. какие есть еще способы ?
Как делал обычно :
помещал в
case BTN_LONG_UP:
следующий код.
ласт код на данный момент.
Раньше делал это путем проверки отпускания кнопки в цикле while(). Но тут так делать нельзя , т.к этим повешам динамичесскую индикацию. какие есть еще способы ?
Как делал обычно :
помещал в
case BTN_LONG_UP:
следующий код.
Код: Выделить всё
while((!(PINA&BTN_LINE_UP))&(TimeToStartPW < 59999))
{
TimeToStartPW++;
_delay_ms(100);
}Спойлер
Код: Выделить всё
/*
* BESTV424V.cpp
* Created: 21.05.2018
* Author: Plotnikov Andrei.
*/
#define F_CPU 8000000UL //Частота CPU МК.
#include <avr/io.h> //Инклуд для работы с МК.
#include <util/delay.h> //Инклуд для использования задержек _delay_ms(x);
#include <avr/interrupt.h> //Инклуд для работы с прерываниями.
#include <avr/pgmspace.h> //Инклуд для работы с флэш памятью.
#include <avr/eeprom.h> //Инклуд для работы с ЭСППЗУ памятью.
/*_________________BEGIN_TARGET_DEFINE______*/
#define ENABLE_TIM1 TIMSK|= (1<<2)
#define DISABLE_TIM1 TIMSK&= ~(1<<2)
#define ENABLE_POWER PORTC|= (1<<0)
#define DISABLE_POWER PORTC&= ~(1<<0)
#define ENABLE_SM PORTC|= (1<<1)
#define DISABLE_SM PORTC&= ~(1<<1)
#define ENABLE_SB PORTC|= (1<<2)
#define DISABLE_SB PORTC&= ~(1<<2)
#define ENABLE_PW PORTC|= (1<<3)
#define DISABLE_PW PORTC&= ~(1<<3)
#define ENABLE_OW PORTC|= (1<<4)
#define DISABLE_OW PORTC&= ~(1<<4)
/******************Описание DEFINE SPI**********************/
#define SPI_PORT PORTB
#define SPI_DDR DDRB
#define SPI_MISO 6
#define SPI_MOSI 5
#define SPI_SCK 7
#define SPI_SS 4
/*********Кодировка семи сегментного индикатора.*************/
//________________________*/
#define SEG_PORT TwoOUT.Byte
//__________________Катоды____________________*/
#define SEGA 0
#define SEGB 1
#define SEGC 2
#define SEGD 3
#define SEGE 4
#define SEGF 5
#define SEGG 6
#define SEGH 7
//__________________Аноды_____________________*/
#define ANOD1 OneOUT.Bits.DO0
#define ANOD2 OneOUT.Bits.DO1
#define ANOD3 OneOUT.Bits.DO2
#define ANOD4 OneOUT.Bits.DO3
#define ANOD5 OneOUT.Bits.DO4
#define ANOD6 OneOUT.Bits.DO5
#define DISPLAY_MOD_TIM OneOUT.Bits.DO7
#define DISPLAY_MOD_JOB OneOUT.Bits.DO6
/*****************SETING_DEFINE_BTN_AND_GRC*****************/
#define BTN_LOCK_TIME 100 //время фиксации дребезга
#define BTN_LONG_TIME 2000 //время фиксации длинного нажатия
//**__________________порт чтения кнопок___________________*/
#define BTN_PORT1 PORTA
#define BTN_DDR1 DDRA
#define BTN_PIN1 PINA
#define BTN_PORT2 PORTD
#define BTN_DDR2 DDRD
#define BTN_PIN2 PIND
#define BTN_PORT3 PORTC
#define BTN_DDR3 DDRC
#define BTN_PIN3 PINC
//**________________пины чтения кнопок___________________*/
//________PORTA_____________*/
#define BTN_LINE_RA (1<<0) //Режим РУЧ/АВТ (PA)
#define BTN_LINE_ST (1<<1) //Режим СЧЕТЧИК/ТАЙМЕР
#define BTN_LINE_PR (1<<2) //MOD PROGRAMMING
#define BTN_LINE_EN (1<<3) //BTN_ENTER
#define BTN_LINE_UP (1<<4) //BTN_UP
#define BTN_LINE_DN (1<<5) //BTN_DOWN
#define BTN_LINE_SM (1<<6) //BTN_SW_СМЫКАНИЕ
#define BTN_LINE_SB (1<<7) //BTN_SW_ШТОК_БАРЫ
//________PORTD_____________*/
#define BTN_LINE_S1 (1<<0) //BTN_START_1 (PD)
#define BTN_LINE_S2 (1<<1) //BTN_START_2
#define GRK_LINE_SM (1<<2) //ГЕРКОН_СМЫКАНИЕ
#define BTN_LINE_PW (1<<3) //BTN_ПРЕД_ВЫДУВ
#define BTN_LINE_OW (1<<4) //BTN_ОСНОВНОЙ_ВЫДУВ
#define GRK_LINE_ZM_IP (1<<5) //ГЕРКОН_ЗАМОК_ИСХ.ПОЛОЖЕНИЕ
#define GRK_LINE_ZM_RP (1<<6) //ГЕРКОН_ЗАМОК_РАБ.ПОЛОЖЕНИЕ
#define BTN_LINE_ZM (1<<7) //BTN_SWITCH_ЗАМОК
//________PORTC_____________*/
#define DAT_LINE_PWR (1<<6) //ДАТЧИК_PWR (POWER)
#define BTN_LINE_MOD (1<<7) //BTN_MOD_ZM/NO_ZM
//_______Биты короткого нажатия -> BtnFlags_1_____________*/
#define BTN_SHRT_RA (1<<0) //Режим РУЧ/АВТ
#define BTN_SHRT_ST (1<<1) //Режим СЧЕТЧИК/ТАЙМЕР
#define BTN_SHRT_PR (1<<2) //MOD PROGRAMMING
#define BTN_SHRT_EN (1<<3) //BTN_ENTER
#define BTN_SHRT_UP (1<<4) //BTN_UP
#define BTN_SHRT_DN (1<<5) //BTN_DOWN
#define BTN_SHRT_SM (1<<6) //BTN_SW_СМЫКАНИЕ
#define BTN_SHRT_SB (1<<7) //BTN_SW_ШТОК_БАРЫ
//_______Биты короткого нажатия -> BtnFlags_2______________*/
#define BTN_SHRT_S1 (1<<0) //BTN_START_1
#define BTN_SHRT_S2 (1<<1) //BTN_START_2
#define GRK_SHRT_SM (1<<2) //ГЕРКОН_СМЫКАНИЕ
#define BTN_SHRT_PW (1<<3) //BTN_ПРЕД_ВЫДУВ
#define BTN_SHRT_OW (1<<4) //BTN_ОСНОВНОЙ_ВЫДУВ
#define GRK_SHRT_ZM_IP (1<<5) //ГЕРКОН_ЗАМОК_ИСХ.ПОЛОЖЕНИЕ
#define GRK_SHRT_ZM_RP (1<<6) //ГЕРКОН_ЗАМОК_РАБ.ПОЛОЖЕНИЕ
#define BTN_SHRT_ZM (1<<7) //BTN_SWITCH_ЗАМОК
//_______Биты короткого нажатия -> BtnFlags_3______________*/
//#define DAT_SHRT_PWR (1<<0) //ДАТЧИК_PWR
#define BTN_SHRT_MOD (1<<1) //BTN_MOD_ZM/NO_ZM
//_______Биты длинного нажатия */
#define BTN_LONG_PR (1<<10) //BTN_LONG_PR
#define BTN_LONG_UP (1<<12) //BTN_UP_LONG
#define BTN_LONG_DN (1<<13) //BTN_DOWN_LONG
/*_________________END_TARGET_DEFINE________*/
/***********************************************************/
//________________(глобальные переменные)___________________*/
///////////////////________EEPROM________/////////////////////
uint16_t eepTimeToStartPW EEMEM = 50; //Time*10 = T1 ms
uint16_t eepTimeToStopPW EEMEM = 50; //Time*10 = T2 ms
uint16_t eepTimeOW EEMEM = 50; //Time*10 = T3 ms
uint16_t eepTimeReturn EEMEM = 50; //Time*10 = T4 ms
//uint16_t eepCountProduct EEMEM = 0; //50 это дефолтное значения равное 0.5с.
volatile uint8_t TimeErrorStop=25;
volatile uint16_t TimeToStartPW=50; //Time*10 = T1 ms
volatile uint16_t TimeToStopPW=50; //Time*10 = T2 ms
volatile uint16_t TimeOW=50; //Time*10 = T3 ms
volatile uint16_t TimeReturn=50; //Time*10 = T4 ms
volatile uint16_t TimeSumm=0; //(Сумма Т1..Т4)*10 = Т5 ms
volatile uint16_t CountProduct=0; // Счетчик циклов(продукции)
volatile uint16_t SetProgProduct=0;
volatile uint8_t FlagOverflowProduct=0; //Флаг Отвечающий за переполннение - (CountProduct > SetProgProduct)
volatile uint16_t BtnFlags_1=0;
volatile uint16_t BtnFlags_2=0;
volatile uint16_t BtnFlags_3=0;
volatile uint8_t AnodCount=0; //Счетчик Анодов Сем.Сег.Идникатора.
volatile uint8_t ModTimer = 0x00; //Режим работы таймера. 0 -> Режим работы таймеров Т1..T4
// 1 -> Режим работы счетчика.
volatile uint16_t CountMS=0; //Переменная счетчик MS
volatile uint8_t FlagsEnDiplay=1; //Флаг для работы с Сем.Сег.Идникатором.
volatile uint8_t ModDebug=0xFF; //Ручной режим работы (отладка)(включен по дефолту)
volatile uint8_t ModAuto=0x00; //Автоматический режим работы (Отключен по дефолту)
volatile uint8_t ModProgramming=0x00; //Режим программирования таймеров.
void InitTimer0_OVF()
{
TCNT0=120; //Прерывания настроено на 1.25ms
TIMSK|=(1<<TOIE0);//Разрешить прерывание по переполнению таймера 0.
TCCR0|=(0<<CS02)|(1<<CS01)|(1<<CS00); //Настройка пред делителя. 100 .clk\256
}
void InitTimer1_OVF()
{
TCCR1B|=(1<<CS12)|(0<<CS11)|(0<<CS10); //Пред делитель
TIMSK|=(1<<TOIE1); //Разрешить прерывание по переполнению таймера 1
//TCNT1=65521;
TCNT1=65505 ; //Начальное значение таймера
}
void SPI_Init(void)
{
/*настройка портов ввода-вывода все выводы, кроме MISO выходы*/
SPI_DDR |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(0<<SPI_MISO);
SPI_PORT |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(1<<SPI_MISO);
SPCR = (1<<SPE)|(0<<DORD)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(0<<SPR1)|(1<<SPR0);
SPSR = (0<<SPI2X);
}
//--------------------------------------------------------------------------------------------------------------------
//Функции чтения данных о нажатии кнопок
uint16_t MaskGetOne (void)
{
cli();
uint16_t temp1 = BtnFlags_1;
BtnFlags_1 = 0;
sei();
return temp1;
}
uint16_t MaskGetTwo (void)
{
cli();
uint16_t temp2 = BtnFlags_2;
BtnFlags_2 = 0;
sei();
return temp2;
}
uint16_t MaskGetThree (void)
{
cli();
uint16_t temp3 = BtnFlags_3;
BtnFlags_3 = 0;
sei();
return temp3;
}
//-----------------------------------------------------------------------------------------------------------------------
//ФУНКЦИЯ ОБРАБОТКИ НАЖАТИЙ КЛАВИШ (вызывать в прерывании)
//короткое нажатие устанавливает бит BTN_SHRT_X глобальной переменной BtnFlags
//длинное нажатие устанавливает бит BTN_LONG_X глобальной переменной BtnFlags
volatile uint8_t BtPW=0;
volatile uint8_t BtOW=0;
volatile uint8_t BtS1=0;
volatile uint8_t BtS2=0;
volatile uint8_t GrKSM=0;
volatile uint8_t DatPWR=0;
void BtnExe (void)
{
static uint8_t BtnLockBit; //защелка (защита от дребезга)
static uint8_t BtnLockCoun; //счетчик защелки (защита от дребезга)
static uint8_t BtnLongCoun; //счетчик длинного нажатия
static uint8_t BtnLastState_1; //последнее состояние кнопок перед отпусканием
static uint8_t BtnLastState_2; //последнее состояние кнопок перед отпусканием
static uint8_t BtnLastState_3; //последнее состояние кнопок перед отпусканием
uint8_t mask_1 = 0;
uint8_t mask_2 = 0;
uint8_t mask_3 = 0;
if (!(BTN_PIN1 & BTN_LINE_RA)) mask_1 = BTN_SHRT_RA;
if (!(BTN_PIN1 & BTN_LINE_ST)) mask_1 = BTN_SHRT_ST;
if (!(BTN_PIN1 & BTN_LINE_PR)) mask_1 = BTN_SHRT_PR;
if (!(BTN_PIN1 & BTN_LINE_EN)) mask_1 = BTN_SHRT_EN;
if (!(BTN_PIN1 & BTN_LINE_UP)) mask_1 = BTN_SHRT_UP;
if (!(BTN_PIN1 & BTN_LINE_DN)) mask_1 = BTN_SHRT_DN;
if (!(BTN_PIN1 & BTN_LINE_SM)) mask_1 = BTN_SHRT_SM;
if (!(BTN_PIN1 & BTN_LINE_SB)) mask_1 = BTN_SHRT_SB;
if(!(BTN_PIN2 & BTN_LINE_S1)) mask_2 = BTN_SHRT_S1;
if(!(BTN_PIN2 & BTN_LINE_S2)) mask_2 = BTN_SHRT_S2;
if(!(BTN_PIN2 & GRK_LINE_SM)) mask_2 = GRK_SHRT_SM;
if(!(BTN_PIN2 & BTN_LINE_PW)) mask_2 = BTN_SHRT_PW;
if(!(BTN_PIN2 & BTN_LINE_OW)) mask_2 = BTN_SHRT_OW;
if(!(BTN_PIN2 & GRK_LINE_ZM_IP)) mask_2 = GRK_SHRT_ZM_IP;
if(!(BTN_PIN2 & GRK_LINE_ZM_RP)) mask_2 = GRK_SHRT_ZM_RP;
if(!(BTN_PIN2 & BTN_LINE_ZM)) mask_2 = BTN_SHRT_ZM;
//if(!(BTN_PIN3 & DAT_LINE_PWR)) mask_3 = DAT_SHRT_PWR;
if(!(BTN_PIN3 & BTN_LINE_MOD)) mask_3 = BTN_SHRT_MOD;
if((mask_1)||(mask_2)||(mask_3)) //опрос состояния кнопки
{
if (BtnLockCoun < (BTN_LOCK_TIME/10)) //клавиша нажата
{
BtnLockCoun++;
return; //защелка еще не досчитала - возврат
}
BtnLastState_1 = mask_1;
BtnLastState_2 = mask_2;
BtnLastState_3 = mask_3;
BtnLockBit =1;
if ((BtnLockBit)&&(!(BTN_PIN3 & DAT_LINE_PWR))) DatPWR=1;
if ((BtnLockBit)&&(!(BTN_PIN2 & BTN_LINE_PW))) BtPW=1;
if ((BtnLockBit)&&(!(BTN_PIN2 & BTN_LINE_OW))) BtOW=1;
if ((BtnLockBit)&&(!(BTN_PIN2 & BTN_LINE_S1))) BtS1=1;
if ((BtnLockBit)&&(!(BTN_PIN2 & BTN_LINE_S2))) BtS2=1;
if ((BtnLockBit)&&(!(BTN_PIN2 & GRK_LINE_SM))) GrKSM=1;
//нажатие зафиксировано
if (BtnLongCoun >= (BTN_LONG_TIME/10))
{
return; //возврат, т.к. счетчик длин.нажат. досчитал до максимума еще раньше
}
if (++BtnLongCoun >= (BTN_LONG_TIME/10))
{
if (mask_1)
{
BtnFlags_1|= (BtnLastState_1<<8); //счетчик досчитал до максимума - устанавливаем биты длинного нажатия
}
if (mask_2)
{
BtnFlags_2 |= (BtnLastState_2<<8);
}
if (mask_3)
{
BtnFlags_3 |= (BtnLastState_3<<8);
}
}
}
else //клавиша отжата
{
if (BTN_PIN2 & BTN_LINE_PW) BtPW=0;
if (BTN_PIN2 & BTN_LINE_OW) BtOW=0;
if (BTN_PIN2 & BTN_LINE_S1) BtS1=0;
if (BTN_PIN2 & BTN_LINE_S2) BtS2=0;
if (BTN_PIN2 & GRK_LINE_SM) GrKSM=0;
if (BtnLockCoun)
{
BtnLockCoun --;
return; //защелка еще не обнулилась - возврат
}
if (! BtnLockBit) return; //СТАТИЧЕСКИЙ ВОЗВРАТ
BtnLockBit =0; //отжатие зафиксировано
if (BtnLongCoun < (BTN_LONG_TIME/10))
{
if(!(mask_1))
{
BtnFlags_1 |= BtnLastState_1;
} //установка бита короткого нажатия
if (!(mask_2))
{
BtnFlags_2 |= BtnLastState_2;
}
if (!(mask_3))
{
BtnFlags_3 |= BtnLastState_3;
}
}
BtnLongCoun = 0; //сброс счетчика длительности нажатия
}
}
struct UnionBits
{
unsigned DO0: 1;
unsigned DO1: 1;
unsigned DO2: 1;
unsigned DO3: 1;
unsigned DO4: 1;
unsigned DO5: 1;
unsigned DO6: 1;
unsigned DO7: 1;
};
union Byte {
uint8_t Byte;
struct UnionBits Bits;
};
union Byte OneOUT; //аноды
union Byte TwoOUT; //Катоды
union Byte Flags; //Объеденнение битов(флагов) разрешающих мигающих разрядов.
uint8_t SPI_UpdataByte(uint8_t data)
{
uint8_t report;
SPDR = data;
while(!(SPSR & (1<<SPIF)));
report = SPDR;
return report;
}
void SpiUpdateRegister()
{
SPI_PORT &= ~(1<<SPI_SS);
SPI_UpdataByte(OneOUT.Byte);
SPI_UpdataByte(TwoOUT.Byte);
SPI_PORT |= (1<<SPI_SS);
}
void StartInitIO()
{
OneOUT.Byte=0xFF;
TwoOUT.Byte=0x00;
Flags.Byte=0x00;
DISPLAY_MOD_JOB=1;
DISPLAY_MOD_TIM=0;
}
//Функция вывода символов
static void PrintChar (uint8_t Number)
{
switch (Number)
{
case 0:
SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(1<<SEGG)|(1<<SEGH);break;
case 1:
SEG_PORT=(1<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG)|(1<<SEGH);break;
case 2:
SEG_PORT=(0<<SEGA)|(0<<SEGB)|(1<<SEGC)|(0<<SEGD)|(0<<SEGE)|(1<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
case 3:
SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(1<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
case 4:
SEG_PORT=(1<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
case 5:
SEG_PORT=(0<<SEGA)|(1<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
case 6:
SEG_PORT=(0<<SEGA)|(1<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
case 7:
SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG)|(1<<SEGH);break;
case 8:
SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
case 9:
SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
case 99: //OFF Все сегменты
SEG_PORT=(1<<SEGA)|(1<<SEGB)|(1<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG)|(1<<SEGH);break;
}
if ((ModTimer == 0)&&(AnodCount == 3))
{
SEG_PORT &=~(1<<SEGH);
}
}
volatile uint8_t data[6]={0};
//Функция вывода динамической индикации.
void PrintNumber(uint16_t NeberChar,uint8_t NumberTimers,union Byte FlagsBlink)
{
uint8_t TempResult =0;
for (int i = 0; i < 5; i++)
{
TempResult = NeberChar % 10;
NeberChar = NeberChar / 10;
data[i]=TempResult;
}
AnodCount++;
ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=1;
switch (AnodCount)
{
case 1:
if(FlagsBlink.Bits.DO0!=1) //Если флаг == 0, то выводим символ
{
ANOD1=0;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=1;
PrintChar(data[0]);
} else
{
if (FlagsBlink.Bits.DO6==1)
{
ANOD1=0;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=1;
PrintChar(data[0]);
} else PrintChar(99);
}
break;
case 2:
if (((data[1]+data[2]+data[3]+data[4])!=0)||(ModTimer == 0)||(ModProgramming&&ModTimer))
{
if(FlagsBlink.Bits.DO1!=1)
{
ANOD1=1;ANOD2=0;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=1;
PrintChar(data[1]);
}
else
{
if (FlagsBlink.Bits.DO6==1)
{
ANOD1=1;ANOD2=0;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=1;
PrintChar(data[1]);
} else PrintChar(99);
}
} else PrintChar(99);
break;
case 3:
if (((data[2]+data[3]+data[4])!=0)|| (ModTimer == 0)||(ModProgramming&&ModTimer))
{
if(FlagsBlink.Bits.DO2!=1)
{
ANOD1=1;ANOD2=1;ANOD3=0;ANOD4=1;ANOD5=1;ANOD6=1;
PrintChar(data[2]);
}
else
{
if (FlagsBlink.Bits.DO6==1)
{
ANOD1=1;ANOD2=1;ANOD3=0;ANOD4=1;ANOD5=1;ANOD6=1;
PrintChar(data[2]);
} else PrintChar(99);
}
} else PrintChar(99);
break;
case 4:
if (((data[3]+data[4])!=0)||(ModProgramming&&ModTimer))
{
if(FlagsBlink.Bits.DO3!=1)
{
ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=0;ANOD5=1;ANOD6=1;
PrintChar(data[3]);
}
else
{
if (FlagsBlink.Bits.DO6==1)
{
ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=0;ANOD5=1;ANOD6=1;
PrintChar(data[3]);
} else PrintChar(99);
}
} else PrintChar(99);
break;
case 5:
if ((data[4]!=0)||(ModProgramming&&ModTimer))
{
if(FlagsBlink.Bits.DO4!=1)
{
ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=0;ANOD6=1;
PrintChar(data[4]);
}
else
{
if (FlagsBlink.Bits.DO6==1)
{
ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=0;ANOD6=1;
PrintChar(data[4]);
} else PrintChar(99);
}
} else PrintChar(99);
break;
case 6:
if (NumberTimers)
{
if(FlagsBlink.Bits.DO5!=1)
{
ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=0;
PrintChar(NumberTimers);
}
else
{
if (FlagsBlink.Bits.DO6==1)
{
ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=0;
PrintChar(NumberTimers);
} else PrintChar(99);
}
} else PrintChar(99);
AnodCount=0;
break;
}
}
void InitIO_MC(void)
{
DDRA|=0x00; // Config InPut
PORTA|=0x00;
DDRB|=0xFF; // Config OutPut
PORTB=0x00;
DDRC|=(0<<PC7)|(0<<PC6)|(1<<PC5)|(1<<PC4)|(1<<PC3)|(1<<PC2)|(1<<PC1)|(1<<PC0);
PORTC|=0x00;
DDRD|=0x00; // Config IntPut
PORTD|=0x00;
}
volatile uint8_t CountDiv10=200;
volatile uint8_t tempx=3; /////////////////////////////////////////////////
ISR (TIMER0_OVF_vect)
{
TCNT0 =120;
SpiUpdateRegister();
if (tempx==0) {BtnExe();tempx=3;}
tempx--;
if (CountDiv10==0)
{
Flags.Bits.DO6=~Flags.Bits.DO6; //переменная отвечающая за частоту моргания.
CountDiv10=200;
}
CountDiv10--;
FlagsEnDiplay=1;
}
uint8_t FlagOnCountToNULL=0;
//ф() Производит обратный отсчет преременной.
uint8_t ClkCount=10; // переменная делитель отсчета ,при 1 clk=1,
uint16_t CountToNULL(uint16_t TimeVariable) // при 10 clk=10.
{
if (FlagOnCountToNULL)
{
ClkCount--;
if (TimeVariable&&(ClkCount==0))
{
TimeVariable=TimeVariable-1;
ClkCount=10;
}
FlagOnCountToNULL=0;
}
return TimeVariable;
}
ISR (TIMER1_OVF_vect)
{
TCNT1=65505;
FlagOnCountToNULL=1;
}
uint8_t FlagSM=0;
uint8_t FlagBtnSM=0;
uint8_t FlagSB=0;
uint8_t FlagBtnSB=0;
uint8_t FlagBtnPW=0;
uint8_t FlagBtnOW=0;
volatile uint8_t StepDebug = 0;
volatile uint8_t StepAuto = 0;
// Функция проверки РП на исходное(начальное) положение.
uint8_t CheckOriginalPosition()
{
static uint8_t State=0;
if ((BtOW||BtPW||FlagSB||FlagSM)||(BtS1||BtS2||GrKSM)) //Оптимизировать и внести правки.
{
State=0;
} else State=1;
return State;
}
volatile uint8_t FlangSetLongBtPR=0;
volatile uint8_t FlangSetShortBtPR=0;
volatile uint8_t LevelModProg=0;
volatile uint8_t TimerActive=1;
void UpdateEEPROM()
{
eeprom_update_word(&eepTimeToStartPW,TimeToStartPW);
eeprom_update_word(&eepTimeToStopPW,TimeToStopPW);
eeprom_update_word(&eepTimeOW,TimeOW);
eeprom_update_word(&eepTimeReturn,TimeReturn);
//eeprom_update_word(&eepCountProduct,CountProduct);
}
//Функция изменения заддоного разряда(NuberDidgit) в числе(OriginalValue) на +/-(1). MAX 59999
uint16_t ReplaceDigitValue(uint16_t OriginalValue,uint8_t NuberDidgit,uint8_t UpDown)
{
uint16_t LevelDig=1;
uint8_t ValueDidgit[5]={0};
uint8_t TempResult =0;
uint16_t ReturnValue=0;
for (uint8_t i = 0; i < 5; i++)
{
TempResult =OriginalValue % 10;
OriginalValue =OriginalValue / 10;
ValueDidgit[i] =TempResult;
}
if((UpDown==0)&&(ValueDidgit[NuberDidgit-1]>0)) {ValueDidgit[NuberDidgit-1]--;}
if((UpDown==1)&&(ValueDidgit[NuberDidgit-1]<9)&&(NuberDidgit<5))
{
ValueDidgit[NuberDidgit-1]++;
}
else if((UpDown==1)&&(ValueDidgit[NuberDidgit-1]<5)&&(NuberDidgit=5))
{
ValueDidgit[NuberDidgit-1]++;
}
for(uint8_t i = 0; i<5;i++)
{
ReturnValue=ReturnValue+ValueDidgit[i]*LevelDig;
if(i<4) LevelDig=LevelDig*10;
}
return ReturnValue;
}
volatile uint8_t CountDidgitNumber=1;
void InputMaskUpdate(uint16_t InputOne,uint16_t InputTwo,uint16_t InputThree)
{
switch(InputOne)
{
case BTN_SHRT_RA:
if(CheckOriginalPosition())
{
ModAuto=~ModAuto;
ModDebug=~ModDebug;
}
if (!(ModAuto)) DISPLAY_MOD_JOB=1; else DISPLAY_MOD_JOB=0;
break;
case BTN_SHRT_ST:
ModTimer=~ModTimer;
if (ModTimer==0)
{
DISPLAY_MOD_TIM=0;
}else DISPLAY_MOD_TIM=1;
break;
case BTN_SHRT_PR:
FlangSetShortBtPR=1;
if (ModProgramming)
{
FlangSetLongBtPR=0;
ModProgramming=0;
}
break;
case BTN_LONG_PR:
FlangSetLongBtPR=1;
break;
case BTN_SHRT_EN:
if (ModProgramming)
{
if(ModTimer!=0)
{
CountDidgitNumber++;
if (CountDidgitNumber > 5)
{
CountDidgitNumber=1;
}
}
}
if (ModProgramming)
{
if (LevelModProg==0)
{
LevelModProg=1;
break;
}
if (LevelModProg==1)
{
LevelModProg=0;
break;
}
}
break;
case BTN_SHRT_UP:
if ((ModProgramming)&&(ModTimer==0))
{
if (LevelModProg == 0)
{
TimerActive++;
if(TimerActive==5) TimerActive=1;
}
if (LevelModProg == 1)
{
switch(TimerActive)
{
case 1:TimeToStartPW++;break;
case 2:TimeToStopPW++;break;
case 3:TimeOW++;break;
case 4:TimeReturn++;break;
}
UpdateEEPROM();
}
}
if (ModProgramming&&(ModTimer!=0))
{
SetProgProduct=ReplaceDigitValue(SetProgProduct,CountDidgitNumber,1);break;
}
break;
case BTN_SHRT_DN:
if ((ModProgramming)&&(ModTimer==0))
{
if (LevelModProg==0)
{
TimerActive--;
if(TimerActive==0) TimerActive=4;
}
if (LevelModProg==1)
{
switch(TimerActive)
{
case 1:TimeToStartPW--;break;
case 2:TimeToStopPW--;break;
case 3:TimeOW--;break;
case 4:TimeReturn--;break;
}
UpdateEEPROM();
}
}
if (ModProgramming&&(ModTimer!=0))
{
SetProgProduct=ReplaceDigitValue(SetProgProduct,CountDidgitNumber,0);break;
}
break;
case BTN_LONG_UP:
if ((ModProgramming)&&(ModTimer==0))
{
if (LevelModProg == 1)
{
switch(TimerActive)
{
case 1:
while((!(PINA&BTN_LINE_UP))&(TimeToStartPW < 59999))
{
TimeToStartPW++;
_delay_ms(100);
}
break;
case 2:
TimeToStopPW++;
break;
case 3:
TimeOW++;
break;
case 4:
TimeReturn++;
break;
}
UpdateEEPROM();
}
}
break;
case BTN_LONG_DN:
if(ModTimer) CountProduct=0;
break;
case BTN_SHRT_SM:
if(ModDebug) FlagBtnSM=~FlagBtnSM;
break;
case BTN_SHRT_SB:
if(ModDebug) FlagBtnSB=~FlagBtnSB;
break;
default:break;
}
switch(InputTwo)
{
case BTN_SHRT_S1:
break;
case BTN_SHRT_S2:
break;
case GRK_SHRT_SM:
break;
case BTN_SHRT_PW:
if(ModDebug) FlagBtnPW=~FlagBtnPW;
break;
case BTN_SHRT_OW:
if(ModDebug) FlagBtnOW=~FlagBtnOW;
break;
case GRK_SHRT_ZM_IP:
break;
case GRK_SHRT_ZM_RP:
break;
case BTN_SHRT_ZM:
break;
default:break;
}
switch(InputThree)
{
/*
case DAT_SHRT_PWR: Датчик не работает в связи с
break; Запаздалой реакцией PC817
*/
case BTN_SHRT_MOD:
break;
default:break;
}
}
uint8_t StartCycleWork(uint8_t Bt1,uint8_t bt2)
{
uint8_t StartCycle=0;
if (Bt1&&bt2)
{
StartCycle = 1;
}
if ((BTN_PIN2 & BTN_LINE_S1)||(BTN_PIN2 & BTN_LINE_S2))
{
StartCycle=0;
}
return StartCycle;
}
uint8_t OneEnablePower=1;
void LoadEEPROM()
{
TimeToStartPW = eeprom_read_word(&eepTimeToStartPW);
TimeToStopPW = eeprom_read_word(&eepTimeToStopPW);
TimeOW = eeprom_read_word(&eepTimeOW);
TimeReturn = eeprom_read_word(&eepTimeReturn);
//if(OneEnablePower) CountProduct = eeprom_read_word(&eepCountProduct);
}
//Функция проверки исполнительных устройств на исходное положение.
int main(void)
{
InitIO_MC(); //Иницилизация портов.
LoadEEPROM();
StartInitIO();
SPI_Init();
SpiUpdateRegister();
_delay_ms(100);
InitTimer1_OVF();
InitTimer0_OVF();
ENABLE_POWER;
volatile uint8_t FlagOriginalPosition = 0;
if (OneEnablePower) OneEnablePower=0;
sei();
while(1)
{
InputMaskUpdate(MaskGetOne(),MaskGetTwo(),MaskGetThree());
if (FlagsEnDiplay) //Проверка флага разрешения вывода информации
{
if((CountProduct >= SetProgProduct)&&(SetProgProduct!=0))
{
FlagOverflowProduct=1;
} else {
FlagOverflowProduct=0;
}
if((!(ModTimer))&&(ModProgramming==0)) //Если режим таймера = 0 , то выводим Т1..Т4
{
TimeSumm=TimeToStartPW+TimeToStopPW+TimeOW+TimeReturn;
switch(StepAuto)
{
case 0: //Ожидания начала цикла(Ожидания старта от StartCycleWork() )
PrintNumber((TimeSumm),0,Flags); //Выводим Сумму Т1..Т4
break;
case 1: //Обработка Т1
PrintNumber((TimeToStartPW),StepAuto,Flags);
break;
case 2: //Обработка Т2
PrintNumber((TimeToStopPW),StepAuto,Flags);
break;
case 3: //Обработка Т3
PrintNumber((TimeOW),StepAuto,Flags);
break;
case 4: //Обработка Т4
PrintNumber((TimeReturn),StepAuto,Flags);
break;
}
}
if ((ModTimer)&&(ModProgramming==0)) //Если режим таймера = 1, то выводим счетчик.
{
if(FlagOverflowProduct==0){
Flags.Bits.DO0=0;
Flags.Bits.DO1=0;
Flags.Bits.DO2=0;
Flags.Bits.DO3=0;
Flags.Bits.DO4=0;
PrintNumber((CountProduct),0,Flags);
}
else{
Flags.Bits.DO0=1;
Flags.Bits.DO1=1;
Flags.Bits.DO2=1;
Flags.Bits.DO3=1;
Flags.Bits.DO4=1;
PrintNumber((CountProduct),0,Flags);
}
}
//Если выбран режим программирования.
if(ModProgramming)
{
if (ModTimer==0) //Отображение программирования режима таймера.
{
if (LevelModProg==0)
{
Flags.Bits.DO0=0;
Flags.Bits.DO1=0;
Flags.Bits.DO2=0;
Flags.Bits.DO3=0;
Flags.Bits.DO5=1;
}
if (LevelModProg==1)
{
Flags.Bits.DO0=1;
Flags.Bits.DO1=1;
Flags.Bits.DO2=1;
Flags.Bits.DO3=1;
Flags.Bits.DO5=0;
}
switch(TimerActive)
{
case 1:
PrintNumber((TimeToStartPW),TimerActive,Flags);
break;
case 2: // Т2
PrintNumber((TimeToStopPW),TimerActive,Flags);
break;
case 3: // Т3
PrintNumber((TimeOW),TimerActive,Flags);
break;
case 4: // Т4
PrintNumber((TimeReturn),TimerActive,Flags);
break;
default: break;
}
}
if (ModTimer!=0) //Отображение программирования режима счетчика.
{
switch(CountDidgitNumber)
{
case 1:
Flags.Bits.DO0=1;
Flags.Bits.DO1=0;
Flags.Bits.DO2=0;
Flags.Bits.DO3=0;
Flags.Bits.DO4=0;
PrintNumber(SetProgProduct,0,Flags);
break;
case 2:
Flags.Bits.DO0=0;
Flags.Bits.DO1=1;
Flags.Bits.DO2=0;
Flags.Bits.DO3=0;
Flags.Bits.DO4=0;
PrintNumber(SetProgProduct,0,Flags);
break;
case 3:
Flags.Bits.DO0=0;
Flags.Bits.DO1=0;
Flags.Bits.DO2=1;
Flags.Bits.DO3=0;
Flags.Bits.DO4=0;
PrintNumber(SetProgProduct,0,Flags);
break;
case 4:
Flags.Bits.DO0=0;
Flags.Bits.DO1=0;
Flags.Bits.DO2=0;
Flags.Bits.DO3=1;
Flags.Bits.DO4=0;
PrintNumber(SetProgProduct,0,Flags);
break;
case 5:
Flags.Bits.DO0=0;
Flags.Bits.DO1=0;
Flags.Bits.DO2=0;
Flags.Bits.DO3=0;
Flags.Bits.DO4=1;
PrintNumber(SetProgProduct,0,Flags);
break;
default:break;
}
}
} else if(SetProgProduct == 0)Flags.Byte=0;
FlagsEnDiplay=0; // Обнуляем Флаг разрешения. (Включается в прерывание таймера 0)
}
if(FlangSetLongBtPR)
{
ModProgramming=1;
}
//Алгоритм работы выходных MosFet ключей в ручном режиме(Режиме отладки).
if ((ModDebug!=0)&&(ModAuto == 0)&&(ModProgramming==0))
{
ENABLE_POWER;
if (BtPW)
{
ENABLE_PW;
} else DISABLE_PW;
if (BtOW)
{
ENABLE_OW;
} else DISABLE_OW;
if ((FlagBtnSM)&&(StepDebug!=2))
{
FlagSM=1;
StepDebug=1;
ENABLE_SM;
} else if (FlagSB==0)
{
DISABLE_SM;
FlagSM=0;
}
if (FlagBtnSB)
{
FlagSB=1;
StepDebug=2;
ENABLE_SB;
}
else {
DISABLE_SB;
FlagSB=0;
StepDebug=0;
}
}
//Алгоритм работы выходных MosFet ключей в режиме цикла.(Автоматический режим).
if ((ModAuto!=0)&&(ModDebug == 0)&&(ModProgramming==0))
{
if (FlagOverflowProduct==0)
{
Flags.Byte=0;
} else {
Flags.Bits.DO0=1;
Flags.Bits.DO1=1;
Flags.Bits.DO2=1;
Flags.Bits.DO3=1;
Flags.Bits.DO5=1;
}
switch(StepAuto)
{
case 0:
switch(FlagOriginalPosition)
{
case 0:
DISABLE_POWER;
FlagOriginalPosition=CheckOriginalPosition();
break;
case 1:
FlagOriginalPosition=2;
break;
case 2:
if (StartCycleWork(BtS1,BtS2))
{
ENABLE_POWER;
ENABLE_SM;
if (GrKSM) StepAuto=1;
}
else
{
DISABLE_SM;
DISABLE_POWER;
}
break;
}
break;
case 1:
FlagOriginalPosition=0;
ENABLE_SB;
TimeToStartPW=CountToNULL(TimeToStartPW);
if (!(GrKSM)) StepAuto=5;
if (TimeToStartPW==0) StepAuto=2;
break;
case 2:
ENABLE_PW;
TimeToStopPW=CountToNULL(TimeToStopPW);
if (!(GrKSM)) StepAuto=5;
if (TimeToStopPW==0)
{
DISABLE_PW;
StepAuto=3;
}
break;
case 3:
ENABLE_OW;
TimeOW=CountToNULL(TimeOW);
if (!(GrKSM)) StepAuto=5;
if (TimeOW==0)
{
DISABLE_OW;
StepAuto=4;
}
break;
case 4:
TimeReturn=CountToNULL(TimeReturn);
if (!(GrKSM)) StepAuto=5;
if (TimeReturn==0)
{
DISABLE_SB;
//Подумать о добавлении задержки 100-200ms.
DISABLE_SM;
if (CheckOriginalPosition())
{
LoadEEPROM();
CountProduct++;
StepAuto=0;
}
}
break;
case 5:
DISABLE_OW;
DISABLE_PW;
DISABLE_SB;
TimeErrorStop=CountToNULL(TimeErrorStop);
if (TimeErrorStop==0)
{
DISABLE_SM;
StepAuto=6;
}
break;
case 6:
TimeErrorStop=25;
if (CheckOriginalPosition())
{
LoadEEPROM();
StepAuto=0;
}
break;
}
}
}
return 0;
}
andrei23061996@gmail.com
.................................................................................................................
.................................................................................................................
а кто тебе мешает проверять кнопку регулярно после обновления экрана.
набралось некоторое число в служебном подсчетчике - добавил переменную, можно опрашивать и пореже, например, после зажигания только первого разряда
набралось некоторое число в служебном подсчетчике - добавил переменную, можно опрашивать и пореже, например, после зажигания только первого разряда
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- Сообщения: 303
- Зарегистрирован: Ср май 03, 2017 03:22:26
Все кнопки и проверяются регулярно. в функции BtnExe (void)
andrei23061996@gmail.com
.................................................................................................................
.................................................................................................................
про кнопки: с компа увидел... (а вопрос тогда в чем?)
_________________
по 0 и 1 таймерам: TCNT0 =120; и TCNT1=65505; это както... почитай про режим СТС (если это мега 8 - то вместо 0 таймера посмотри в сторону 2 таймера).
_________________
по 0 и 1 таймерам: TCNT0 =120; и TCNT1=65505; это както... почитай про режим СТС (если это мега 8 - то вместо 0 таймера посмотри в сторону 2 таймера).
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- Сообщения: 303
- Зарегистрирован: Ср май 03, 2017 03:22:26
с кнопками пока что не получается адекватно реализовать след.действие:
При длительном нажатии кнопки(удержании) должен производиться инкремент переменной с задержкойв 100-200 ms и это действие должно продолжаться до тех пор пока не отпустят кнопку.
Вот и получается не задача если я это действие делаю через цикл пока() то вешается вся программа. ((
то есть как щас происходит:
Обрабатываем кнопку
Получаем флаг длинного нажатия
Пока(Кнопка нажата и переменная не достигла макс значения)
{
Производим инкремент.
ждем(100ms)
}
и вот это пока() можно сказать вешает всю программу. т.к индикация выводится по spi через регистры.
Вот и не дам мысли какой тут еще можно алгоритм применить, в данный момент пытаюсь сделать через флаги(разрешения\запрета) в основном теле программы. Результаты пока не ок (.
При длительном нажатии кнопки(удержании) должен производиться инкремент переменной с задержкойв 100-200 ms и это действие должно продолжаться до тех пор пока не отпустят кнопку.
Вот и получается не задача если я это действие делаю через цикл пока() то вешается вся программа. ((
то есть как щас происходит:
Обрабатываем кнопку
Получаем флаг длинного нажатия
Пока(Кнопка нажата и переменная не достигла макс значения)
{
Производим инкремент.
ждем(100ms)
}
и вот это пока() можно сказать вешает всю программу. т.к индикация выводится по spi через регистры.
Вот и не дам мысли какой тут еще можно алгоритм применить, в данный момент пытаюсь сделать через флаги(разрешения\запрета) в основном теле программы. Результаты пока не ок (.
andrei23061996@gmail.com
.................................................................................................................
.................................................................................................................
алгоритм всегда должен быть один и тот же: если надо ждать, то не циклом, а флагом.
то есть в момент, когда вы обнаружили, что надо начать отсчет интервала времени, превышающего допустимую величину (незаметную), вам нужно запустить программный таймер, который установит флажок. при помощи простого if вы контролируете этот флажок и просто делаете в нужный момент то, что необходимо.
Добавлено after 7 minutes 27 seconds:
я всегда стараюсь автоповтор кнопок делать внутри функции, возвращающей код кнопки.
например, делаю функцию get_command(), которая возвращает код команды, т.е. что надо сделать. для редактирования чисел это может быть CMD_UP_1, CMD_UP_10, CMD_UP_100, CMD_DN_1 и т.д. разумеется, есть и CMD_NONE для ситуации "не делать ничего" (т.е. кнопка не нажата).
функция, естественно, в главном цикле вызывается периодически, так что для отсчета интервалов времени можно просто вести подсчет её вызовов. то есть внутри этой функции заводится static-счетчик входов, и мы получаем отличный способ возвращать код команды CMD_UP_1 при первом нажатии, CMD_UP_10 при удержании более 1 секунды и CMD_UP_100, если кнопку держат более 5 секунд.
естественно, возвращать эти команды надо не чаще 1 раза в 100-300 мс, поэтому заводим еще один счетчик и возвращаем CMD_NONE, если этот счетчик не истек, а если истек - см. ранее.
то есть в момент, когда вы обнаружили, что надо начать отсчет интервала времени, превышающего допустимую величину (незаметную), вам нужно запустить программный таймер, который установит флажок. при помощи простого if вы контролируете этот флажок и просто делаете в нужный момент то, что необходимо.
Добавлено after 7 minutes 27 seconds:
я всегда стараюсь автоповтор кнопок делать внутри функции, возвращающей код кнопки.
например, делаю функцию get_command(), которая возвращает код команды, т.е. что надо сделать. для редактирования чисел это может быть CMD_UP_1, CMD_UP_10, CMD_UP_100, CMD_DN_1 и т.д. разумеется, есть и CMD_NONE для ситуации "не делать ничего" (т.е. кнопка не нажата).
функция, естественно, в главном цикле вызывается периодически, так что для отсчета интервалов времени можно просто вести подсчет её вызовов. то есть внутри этой функции заводится static-счетчик входов, и мы получаем отличный способ возвращать код команды CMD_UP_1 при первом нажатии, CMD_UP_10 при удержании более 1 секунды и CMD_UP_100, если кнопку держат более 5 секунд.
естественно, возвращать эти команды надо не чаще 1 раза в 100-300 мс, поэтому заводим еще один счетчик и возвращаем CMD_NONE, если этот счетчик не истек, а если истек - см. ранее.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Чёт какие то сложности у вас, ребята.
Дин. индикация есть ? А значит есть периодические вызовы в прерывании. Что мешает засунуть туда обработку кнопок ? А там, хоть короткие нажатия, хоть длинные считай ...
PS: И ещё не понятно, как цикл while() в основном цикле может повесить индикацию, находящуюся в прерывании ? Какие то сказки ...
Дин. индикация есть ? А значит есть периодические вызовы в прерывании. Что мешает засунуть туда обработку кнопок ? А там, хоть короткие нажатия, хоть длинные считай ...
PS: И ещё не понятно, как цикл while() в основном цикле может повесить индикацию, находящуюся в прерывании ? Какие то сказки ...
- Сообщения: 303
- Зарегистрирован: Ср май 03, 2017 03:22:26
XD, чет я и вправду гдето загнался )))
Поместил
while((!(PINA&BTN_LINE_UP))&(TimeToStartPW < 59999))
{
if (BtLongTime == 0)
{
TimeToStartPW++;
BtLongTime=10;
}
BtLongTime=CountToNULL(BtLongTime);
}
в обработчик кнопок(InputMaskUpdate(uint16_t InputOne,uint16_t InputTwo,uint16_t InputThree))
и в case BTN_LONG_UP:
И все вроде заработало ))). Щас проведу некоторые тесты.
фулл код на данный момент:
Добавлено after 2 minutes 47 seconds:
Тут не большой косяк с временной задержкой ща ченить исправлю ))
Добавлено after 29 minutes 52 seconds:
Подход выше не работает все таки )
Сделал на флагах вродевсе робит. Правдо не знаю на сколько это коректно.
В основном теле программы:
FlagLongBT - активируется в обработчике. в case BTN_LONG_UP:
FlagEnableIncrement - активируется в прерывании
щас попробую превизять вторую кнопку минус и наверно сделать это функцией т.к есть 4 переменные с которыми может происходить данное действие.
Поместил
while((!(PINA&BTN_LINE_UP))&(TimeToStartPW < 59999))
{
if (BtLongTime == 0)
{
TimeToStartPW++;
BtLongTime=10;
}
BtLongTime=CountToNULL(BtLongTime);
}
в обработчик кнопок(InputMaskUpdate(uint16_t InputOne,uint16_t InputTwo,uint16_t InputThree))
и в case BTN_LONG_UP:
И все вроде заработало ))). Щас проведу некоторые тесты.
фулл код на данный момент:
Спойлер
Код: Выделить всё
/*
* BESTV424V.cpp
* Created: 21.05.2018
* Author: Plotnikov Andrei.
*/
#define F_CPU 8000000UL //Частота CPU МК.
#include <avr/io.h> //Инклуд для работы с МК.
#include <util/delay.h> //Инклуд для использования задержек _delay_ms(x);
#include <avr/interrupt.h> //Инклуд для работы с прерываниями.
#include <avr/pgmspace.h> //Инклуд для работы с флэш памятью.
#include <avr/eeprom.h> //Инклуд для работы с ЭСППЗУ памятью.
/*_________________BEGIN_TARGET_DEFINE______*/
#define ENABLE_TIM1 TIMSK|= (1<<2)
#define DISABLE_TIM1 TIMSK&= ~(1<<2)
#define ENABLE_POWER PORTC|= (1<<0)
#define DISABLE_POWER PORTC&= ~(1<<0)
#define ENABLE_SM PORTC|= (1<<1)
#define DISABLE_SM PORTC&= ~(1<<1)
#define ENABLE_SB PORTC|= (1<<2)
#define DISABLE_SB PORTC&= ~(1<<2)
#define ENABLE_PW PORTC|= (1<<3)
#define DISABLE_PW PORTC&= ~(1<<3)
#define ENABLE_OW PORTC|= (1<<4)
#define DISABLE_OW PORTC&= ~(1<<4)
/******************Описание DEFINE SPI**********************/
#define SPI_PORT PORTB
#define SPI_DDR DDRB
#define SPI_MISO 6
#define SPI_MOSI 5
#define SPI_SCK 7
#define SPI_SS 4
/*********Кодировка семи сегментного индикатора.*************/
//________________________*/
#define SEG_PORT TwoOUT.Byte
//__________________Катоды____________________*/
#define SEGA 0
#define SEGB 1
#define SEGC 2
#define SEGD 3
#define SEGE 4
#define SEGF 5
#define SEGG 6
#define SEGH 7
//__________________Аноды_____________________*/
#define ANOD1 OneOUT.Bits.DO0
#define ANOD2 OneOUT.Bits.DO1
#define ANOD3 OneOUT.Bits.DO2
#define ANOD4 OneOUT.Bits.DO3
#define ANOD5 OneOUT.Bits.DO4
#define ANOD6 OneOUT.Bits.DO5
#define DISPLAY_MOD_TIM OneOUT.Bits.DO7
#define DISPLAY_MOD_JOB OneOUT.Bits.DO6
/*****************SETING_DEFINE_BTN_AND_GRC*****************/
#define BTN_LOCK_TIME 100 //время фиксации дребезга
#define BTN_LONG_TIME 2000 //время фиксации длинного нажатия
//**__________________порт чтения кнопок___________________*/
#define BTN_PORT1 PORTA
#define BTN_DDR1 DDRA
#define BTN_PIN1 PINA
#define BTN_PORT2 PORTD
#define BTN_DDR2 DDRD
#define BTN_PIN2 PIND
#define BTN_PORT3 PORTC
#define BTN_DDR3 DDRC
#define BTN_PIN3 PINC
//**________________пины чтения кнопок___________________*/
//________PORTA_____________*/
#define BTN_LINE_RA (1<<0) //Режим РУЧ/АВТ (PA)
#define BTN_LINE_ST (1<<1) //Режим СЧЕТЧИК/ТАЙМЕР
#define BTN_LINE_PR (1<<2) //MOD PROGRAMMING
#define BTN_LINE_EN (1<<3) //BTN_ENTER
#define BTN_LINE_UP (1<<4) //BTN_UP
#define BTN_LINE_DN (1<<5) //BTN_DOWN
#define BTN_LINE_SM (1<<6) //BTN_SW_СМЫКАНИЕ
#define BTN_LINE_SB (1<<7) //BTN_SW_ШТОК_БАРЫ
//________PORTD_____________*/
#define BTN_LINE_S1 (1<<0) //BTN_START_1 (PD)
#define BTN_LINE_S2 (1<<1) //BTN_START_2
#define GRK_LINE_SM (1<<2) //ГЕРКОН_СМЫКАНИЕ
#define BTN_LINE_PW (1<<3) //BTN_ПРЕД_ВЫДУВ
#define BTN_LINE_OW (1<<4) //BTN_ОСНОВНОЙ_ВЫДУВ
#define GRK_LINE_ZM_IP (1<<5) //ГЕРКОН_ЗАМОК_ИСХ.ПОЛОЖЕНИЕ
#define GRK_LINE_ZM_RP (1<<6) //ГЕРКОН_ЗАМОК_РАБ.ПОЛОЖЕНИЕ
#define BTN_LINE_ZM (1<<7) //BTN_SWITCH_ЗАМОК
//________PORTC_____________*/
#define DAT_LINE_PWR (1<<6) //ДАТЧИК_PWR (POWER)
#define BTN_LINE_MOD (1<<7) //BTN_MOD_ZM/NO_ZM
//_______Биты короткого нажатия -> BtnFlags_1_____________*/
#define BTN_SHRT_RA (1<<0) //Режим РУЧ/АВТ
#define BTN_SHRT_ST (1<<1) //Режим СЧЕТЧИК/ТАЙМЕР
#define BTN_SHRT_PR (1<<2) //MOD PROGRAMMING
#define BTN_SHRT_EN (1<<3) //BTN_ENTER
#define BTN_SHRT_UP (1<<4) //BTN_UP
#define BTN_SHRT_DN (1<<5) //BTN_DOWN
#define BTN_SHRT_SM (1<<6) //BTN_SW_СМЫКАНИЕ
#define BTN_SHRT_SB (1<<7) //BTN_SW_ШТОК_БАРЫ
//_______Биты короткого нажатия -> BtnFlags_2______________*/
#define BTN_SHRT_S1 (1<<0) //BTN_START_1
#define BTN_SHRT_S2 (1<<1) //BTN_START_2
#define GRK_SHRT_SM (1<<2) //ГЕРКОН_СМЫКАНИЕ
#define BTN_SHRT_PW (1<<3) //BTN_ПРЕД_ВЫДУВ
#define BTN_SHRT_OW (1<<4) //BTN_ОСНОВНОЙ_ВЫДУВ
#define GRK_SHRT_ZM_IP (1<<5) //ГЕРКОН_ЗАМОК_ИСХ.ПОЛОЖЕНИЕ
#define GRK_SHRT_ZM_RP (1<<6) //ГЕРКОН_ЗАМОК_РАБ.ПОЛОЖЕНИЕ
#define BTN_SHRT_ZM (1<<7) //BTN_SWITCH_ЗАМОК
//_______Биты короткого нажатия -> BtnFlags_3______________*/
//#define DAT_SHRT_PWR (1<<0) //ДАТЧИК_PWR
#define BTN_SHRT_MOD (1<<1) //BTN_MOD_ZM/NO_ZM
//_______Биты длинного нажатия */
#define BTN_LONG_PR (1<<10) //BTN_LONG_PR
#define BTN_LONG_UP (1<<12) //BTN_UP_LONG
#define BTN_LONG_DN (1<<13) //BTN_DOWN_LONG
/*_________________END_TARGET_DEFINE________*/
/***********************************************************/
//________________(глобальные переменные)___________________*/
///////////////////________EEPROM________/////////////////////
uint16_t eepTimeToStartPW EEMEM = 50; //Time*10 = T1 ms
uint16_t eepTimeToStopPW EEMEM = 50; //Time*10 = T2 ms
uint16_t eepTimeOW EEMEM = 50; //Time*10 = T3 ms
uint16_t eepTimeReturn EEMEM = 50; //Time*10 = T4 ms
//uint16_t eepCountProduct EEMEM = 0; //50 это дефолтное значения равное 0.5с.
volatile uint8_t TimeErrorStop=25;
volatile uint16_t TimeToStartPW=50; //Time*10 = T1 ms
volatile uint16_t TimeToStopPW=50; //Time*10 = T2 ms
volatile uint16_t TimeOW=50; //Time*10 = T3 ms
volatile uint16_t TimeReturn=50; //Time*10 = T4 ms
volatile uint16_t TimeSumm=0; //(Сумма Т1..Т4)*10 = Т5 ms
volatile uint16_t CountProduct=0; // Счетчик циклов(продукции)
volatile uint16_t SetProgProduct=0;
volatile uint8_t FlagOverflowProduct=0; //Флаг Отвечающий за переполннение - (CountProduct > SetProgProduct)
volatile uint16_t BtnFlags_1=0;
volatile uint16_t BtnFlags_2=0;
volatile uint16_t BtnFlags_3=0;
volatile uint8_t AnodCount=0; //Счетчик Анодов Сем.Сег.Идникатора.
volatile uint8_t ModTimer = 0x00; //Режим работы таймера. 0 -> Режим работы таймеров Т1..T4
// 1 -> Режим работы счетчика.
volatile uint16_t CountMS=0; //Переменная счетчик MS
volatile uint8_t FlagsEnDiplay=1; //Флаг для работы с Сем.Сег.Идникатором.
volatile uint8_t ModDebug=0xFF; //Ручной режим работы (отладка)(включен по дефолту)
volatile uint8_t ModAuto=0x00; //Автоматический режим работы (Отключен по дефолту)
volatile uint8_t ModProgramming=0x00; //Режим программирования таймеров.
void InitTimer0_OVF()
{
TCNT0=120; //Прерывания настроено на 1.25ms
TIMSK|=(1<<TOIE0);//Разрешить прерывание по переполнению таймера 0.
TCCR0|=(0<<CS02)|(1<<CS01)|(1<<CS00); //Настройка пред делителя. 100 .clk\256
}
void InitTimer1_OVF()
{
TCCR1B|=(1<<CS12)|(0<<CS11)|(0<<CS10); //Пред делитель
TIMSK|=(1<<TOIE1); //Разрешить прерывание по переполнению таймера 1
//TCNT1=65521;
TCNT1=65505 ; //Начальное значение таймера
}
void SPI_Init(void)
{
/*настройка портов ввода-вывода все выводы, кроме MISO выходы*/
SPI_DDR |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(0<<SPI_MISO);
SPI_PORT |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(1<<SPI_MISO);
SPCR = (1<<SPE)|(0<<DORD)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(0<<SPR1)|(1<<SPR0);
SPSR = (0<<SPI2X);
}
//--------------------------------------------------------------------------------------------------------------------
//Функции чтения данных о нажатии кнопок
uint16_t MaskGetOne (void)
{
cli();
uint16_t temp1 = BtnFlags_1;
BtnFlags_1 = 0;
sei();
return temp1;
}
uint16_t MaskGetTwo (void)
{
cli();
uint16_t temp2 = BtnFlags_2;
BtnFlags_2 = 0;
sei();
return temp2;
}
uint16_t MaskGetThree (void)
{
cli();
uint16_t temp3 = BtnFlags_3;
BtnFlags_3 = 0;
sei();
return temp3;
}
//-----------------------------------------------------------------------------------------------------------------------
//ФУНКЦИЯ ОБРАБОТКИ НАЖАТИЙ КЛАВИШ (вызывать в прерывании)
//короткое нажатие устанавливает бит BTN_SHRT_X глобальной переменной BtnFlags
//длинное нажатие устанавливает бит BTN_LONG_X глобальной переменной BtnFlags
volatile uint8_t BtPW=0;
volatile uint8_t BtOW=0;
volatile uint8_t BtS1=0;
volatile uint8_t BtS2=0;
volatile uint8_t GrKSM=0;
volatile uint8_t DatPWR=0;
void BtnExe (void)
{
static uint8_t BtnLockBit; //защелка (защита от дребезга)
static uint8_t BtnLockCoun; //счетчик защелки (защита от дребезга)
static uint8_t BtnLongCoun; //счетчик длинного нажатия
static uint8_t BtnLastState_1; //последнее состояние кнопок перед отпусканием
static uint8_t BtnLastState_2; //последнее состояние кнопок перед отпусканием
static uint8_t BtnLastState_3; //последнее состояние кнопок перед отпусканием
uint8_t mask_1 = 0;
uint8_t mask_2 = 0;
uint8_t mask_3 = 0;
if (!(BTN_PIN1 & BTN_LINE_RA)) mask_1 = BTN_SHRT_RA;
if (!(BTN_PIN1 & BTN_LINE_ST)) mask_1 = BTN_SHRT_ST;
if (!(BTN_PIN1 & BTN_LINE_PR)) mask_1 = BTN_SHRT_PR;
if (!(BTN_PIN1 & BTN_LINE_EN)) mask_1 = BTN_SHRT_EN;
if (!(BTN_PIN1 & BTN_LINE_UP)) mask_1 = BTN_SHRT_UP;
if (!(BTN_PIN1 & BTN_LINE_DN)) mask_1 = BTN_SHRT_DN;
if (!(BTN_PIN1 & BTN_LINE_SM)) mask_1 = BTN_SHRT_SM;
if (!(BTN_PIN1 & BTN_LINE_SB)) mask_1 = BTN_SHRT_SB;
if(!(BTN_PIN2 & BTN_LINE_S1)) mask_2 = BTN_SHRT_S1;
if(!(BTN_PIN2 & BTN_LINE_S2)) mask_2 = BTN_SHRT_S2;
if(!(BTN_PIN2 & GRK_LINE_SM)) mask_2 = GRK_SHRT_SM;
if(!(BTN_PIN2 & BTN_LINE_PW)) mask_2 = BTN_SHRT_PW;
if(!(BTN_PIN2 & BTN_LINE_OW)) mask_2 = BTN_SHRT_OW;
if(!(BTN_PIN2 & GRK_LINE_ZM_IP)) mask_2 = GRK_SHRT_ZM_IP;
if(!(BTN_PIN2 & GRK_LINE_ZM_RP)) mask_2 = GRK_SHRT_ZM_RP;
if(!(BTN_PIN2 & BTN_LINE_ZM)) mask_2 = BTN_SHRT_ZM;
//if(!(BTN_PIN3 & DAT_LINE_PWR)) mask_3 = DAT_SHRT_PWR;
if(!(BTN_PIN3 & BTN_LINE_MOD)) mask_3 = BTN_SHRT_MOD;
if((mask_1)||(mask_2)||(mask_3)) //опрос состояния кнопки
{
if (BtnLockCoun < (BTN_LOCK_TIME/10)) //клавиша нажата
{
BtnLockCoun++;
return; //защелка еще не досчитала - возврат
}
BtnLastState_1 = mask_1;
BtnLastState_2 = mask_2;
BtnLastState_3 = mask_3;
BtnLockBit =1;
if ((BtnLockBit)&&(!(BTN_PIN3 & DAT_LINE_PWR))) DatPWR=1;
if ((BtnLockBit)&&(!(BTN_PIN2 & BTN_LINE_PW))) BtPW=1;
if ((BtnLockBit)&&(!(BTN_PIN2 & BTN_LINE_OW))) BtOW=1;
if ((BtnLockBit)&&(!(BTN_PIN2 & BTN_LINE_S1))) BtS1=1;
if ((BtnLockBit)&&(!(BTN_PIN2 & BTN_LINE_S2))) BtS2=1;
if ((BtnLockBit)&&(!(BTN_PIN2 & GRK_LINE_SM))) GrKSM=1;
//нажатие зафиксировано
if (BtnLongCoun >= (BTN_LONG_TIME/10))
{
return; //возврат, т.к. счетчик длин.нажат. досчитал до максимума еще раньше
}
if (++BtnLongCoun >= (BTN_LONG_TIME/10))
{
if (mask_1)
{
BtnFlags_1|= (BtnLastState_1<<8); //счетчик досчитал до максимума - устанавливаем биты длинного нажатия
}
if (mask_2)
{
BtnFlags_2 |= (BtnLastState_2<<8);
}
if (mask_3)
{
BtnFlags_3 |= (BtnLastState_3<<8);
}
}
}
else //клавиша отжата
{
if (BTN_PIN2 & BTN_LINE_PW) BtPW=0;
if (BTN_PIN2 & BTN_LINE_OW) BtOW=0;
if (BTN_PIN2 & BTN_LINE_S1) BtS1=0;
if (BTN_PIN2 & BTN_LINE_S2) BtS2=0;
if (BTN_PIN2 & GRK_LINE_SM) GrKSM=0;
if (BtnLockCoun)
{
BtnLockCoun --;
return; //защелка еще не обнулилась - возврат
}
if (! BtnLockBit) return; //СТАТИЧЕСКИЙ ВОЗВРАТ
BtnLockBit =0; //отжатие зафиксировано
if (BtnLongCoun < (BTN_LONG_TIME/10))
{
if(!(mask_1))
{
BtnFlags_1 |= BtnLastState_1;
} //установка бита короткого нажатия
if (!(mask_2))
{
BtnFlags_2 |= BtnLastState_2;
}
if (!(mask_3))
{
BtnFlags_3 |= BtnLastState_3;
}
}
BtnLongCoun = 0; //сброс счетчика длительности нажатия
}
}
struct UnionBits
{
unsigned DO0: 1;
unsigned DO1: 1;
unsigned DO2: 1;
unsigned DO3: 1;
unsigned DO4: 1;
unsigned DO5: 1;
unsigned DO6: 1;
unsigned DO7: 1;
};
union Byte {
uint8_t Byte;
struct UnionBits Bits;
};
union Byte OneOUT; //аноды
union Byte TwoOUT; //Катоды
union Byte Flags; //Объеденнение битов(флагов) разрешающих мигающих разрядов.
uint8_t SPI_UpdataByte(uint8_t data)
{
uint8_t report;
SPDR = data;
while(!(SPSR & (1<<SPIF)));
report = SPDR;
return report;
}
void SpiUpdateRegister()
{
SPI_PORT &= ~(1<<SPI_SS);
SPI_UpdataByte(OneOUT.Byte);
SPI_UpdataByte(TwoOUT.Byte);
SPI_PORT |= (1<<SPI_SS);
}
void StartInitIO()
{
OneOUT.Byte=0xFF;
TwoOUT.Byte=0x00;
Flags.Byte=0x00;
DISPLAY_MOD_JOB=1;
DISPLAY_MOD_TIM=0;
}
//Функция вывода символов
static void PrintChar (uint8_t Number)
{
switch (Number)
{
case 0:
SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(1<<SEGG)|(1<<SEGH);break;
case 1:
SEG_PORT=(1<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG)|(1<<SEGH);break;
case 2:
SEG_PORT=(0<<SEGA)|(0<<SEGB)|(1<<SEGC)|(0<<SEGD)|(0<<SEGE)|(1<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
case 3:
SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(1<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
case 4:
SEG_PORT=(1<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
case 5:
SEG_PORT=(0<<SEGA)|(1<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
case 6:
SEG_PORT=(0<<SEGA)|(1<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
case 7:
SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG)|(1<<SEGH);break;
case 8:
SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
case 9:
SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
case 99: //OFF Все сегменты
SEG_PORT=(1<<SEGA)|(1<<SEGB)|(1<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG)|(1<<SEGH);break;
}
if ((ModTimer == 0)&&(AnodCount == 3))
{
SEG_PORT &=~(1<<SEGH);
}
}
volatile uint8_t data[6]={0};
//Функция вывода динамической индикации.
void PrintNumber(uint16_t NeberChar,uint8_t NumberTimers,union Byte FlagsBlink)
{
uint8_t TempResult =0;
for (int i = 0; i < 5; i++)
{
TempResult = NeberChar % 10;
NeberChar = NeberChar / 10;
data[i]=TempResult;
}
AnodCount++;
ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=1;
switch (AnodCount)
{
case 1:
if(FlagsBlink.Bits.DO0!=1) //Если флаг == 0, то выводим символ
{
ANOD1=0;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=1;
PrintChar(data[0]);
} else
{
if (FlagsBlink.Bits.DO6==1)
{
ANOD1=0;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=1;
PrintChar(data[0]);
} else PrintChar(99);
}
break;
case 2:
if (((data[1]+data[2]+data[3]+data[4])!=0)||(ModTimer == 0)||(ModProgramming&&ModTimer))
{
if(FlagsBlink.Bits.DO1!=1)
{
ANOD1=1;ANOD2=0;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=1;
PrintChar(data[1]);
}
else
{
if (FlagsBlink.Bits.DO6==1)
{
ANOD1=1;ANOD2=0;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=1;
PrintChar(data[1]);
} else PrintChar(99);
}
} else PrintChar(99);
break;
case 3:
if (((data[2]+data[3]+data[4])!=0)|| (ModTimer == 0)||(ModProgramming&&ModTimer))
{
if(FlagsBlink.Bits.DO2!=1)
{
ANOD1=1;ANOD2=1;ANOD3=0;ANOD4=1;ANOD5=1;ANOD6=1;
PrintChar(data[2]);
}
else
{
if (FlagsBlink.Bits.DO6==1)
{
ANOD1=1;ANOD2=1;ANOD3=0;ANOD4=1;ANOD5=1;ANOD6=1;
PrintChar(data[2]);
} else PrintChar(99);
}
} else PrintChar(99);
break;
case 4:
if (((data[3]+data[4])!=0)||(ModProgramming&&ModTimer))
{
if(FlagsBlink.Bits.DO3!=1)
{
ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=0;ANOD5=1;ANOD6=1;
PrintChar(data[3]);
}
else
{
if (FlagsBlink.Bits.DO6==1)
{
ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=0;ANOD5=1;ANOD6=1;
PrintChar(data[3]);
} else PrintChar(99);
}
} else PrintChar(99);
break;
case 5:
if ((data[4]!=0)||(ModProgramming&&ModTimer))
{
if(FlagsBlink.Bits.DO4!=1)
{
ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=0;ANOD6=1;
PrintChar(data[4]);
}
else
{
if (FlagsBlink.Bits.DO6==1)
{
ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=0;ANOD6=1;
PrintChar(data[4]);
} else PrintChar(99);
}
} else PrintChar(99);
break;
case 6:
if (NumberTimers)
{
if(FlagsBlink.Bits.DO5!=1)
{
ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=0;
PrintChar(NumberTimers);
}
else
{
if (FlagsBlink.Bits.DO6==1)
{
ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=0;
PrintChar(NumberTimers);
} else PrintChar(99);
}
} else PrintChar(99);
AnodCount=0;
break;
}
}
void InitIO_MC(void)
{
DDRA|=0x00; // Config InPut
PORTA|=0x00;
DDRB|=0xFF; // Config OutPut
PORTB=0x00;
DDRC|=(0<<PC7)|(0<<PC6)|(1<<PC5)|(1<<PC4)|(1<<PC3)|(1<<PC2)|(1<<PC1)|(1<<PC0);
PORTC|=0x00;
DDRD|=0x00; // Config IntPut
PORTD|=0x00;
}
volatile uint8_t CountDiv10=200;
volatile uint8_t tempx=3; /////////////////////////////////////////////////
ISR (TIMER0_OVF_vect)
{
TCNT0 =120;
SpiUpdateRegister();
if (tempx==0) {BtnExe();tempx=3;}
tempx--;
if (CountDiv10==0)
{
Flags.Bits.DO6=~Flags.Bits.DO6; //переменная отвечающая за частоту моргания.
CountDiv10=200;
}
CountDiv10--;
FlagsEnDiplay=1;
}
uint8_t FlagOnCountToNULL=0;
//ф() Производит обратный отсчет преременной.
uint8_t ClkCount=10; // переменная делитель отсчета ,при 1 clk=1,
uint16_t CountToNULL(uint16_t TimeVariable) // при 10 clk=10.
{
if (FlagOnCountToNULL)
{
ClkCount--;
if (TimeVariable&&(ClkCount==0))
{
TimeVariable=TimeVariable-1;
ClkCount=10;
}
FlagOnCountToNULL=0;
}
return TimeVariable;
}
ISR (TIMER1_OVF_vect)
{
TCNT1=65505;
FlagOnCountToNULL=1;
}
uint8_t FlagSM=0;
uint8_t FlagBtnSM=0;
uint8_t FlagSB=0;
uint8_t FlagBtnSB=0;
uint8_t FlagBtnPW=0;
uint8_t FlagBtnOW=0;
volatile uint8_t StepDebug = 0;
volatile uint8_t StepAuto = 0;
// Функция проверки РП на исходное(начальное) положение.
uint8_t CheckOriginalPosition()
{
static uint8_t State=0;
if ((BtOW||BtPW||FlagSB||FlagSM)||(BtS1||BtS2||GrKSM)) //Оптимизировать и внести правки.
{
State=0;
} else State=1;
return State;
}
volatile uint8_t FlangSetLongBtPR=0;
volatile uint8_t FlangSetShortBtPR=0;
volatile uint8_t LevelModProg=0;
volatile uint8_t TimerActive=1;
void UpdateEEPROM()
{
eeprom_update_word(&eepTimeToStartPW,TimeToStartPW);
eeprom_update_word(&eepTimeToStopPW,TimeToStopPW);
eeprom_update_word(&eepTimeOW,TimeOW);
eeprom_update_word(&eepTimeReturn,TimeReturn);
//eeprom_update_word(&eepCountProduct,CountProduct);
}
//Функция изменения заддоного разряда(NuberDidgit) в числе(OriginalValue) на +/-(1). MAX 59999
uint16_t ReplaceDigitValue(uint16_t OriginalValue,uint8_t NuberDidgit,uint8_t UpDown)
{
uint16_t LevelDig=1;
uint8_t ValueDidgit[5]={0};
uint8_t TempResult =0;
uint16_t ReturnValue=0;
for (uint8_t i = 0; i < 5; i++)
{
TempResult =OriginalValue % 10;
OriginalValue =OriginalValue / 10;
ValueDidgit[i] =TempResult;
}
if((UpDown==0)&&(ValueDidgit[NuberDidgit-1]>0)) {ValueDidgit[NuberDidgit-1]--;}
if((UpDown==1)&&(ValueDidgit[NuberDidgit-1]<9)&&(NuberDidgit<5))
{
ValueDidgit[NuberDidgit-1]++;
}
else if((UpDown==1)&&(ValueDidgit[NuberDidgit-1]<5)&&(NuberDidgit=5))
{
ValueDidgit[NuberDidgit-1]++;
}
for(uint8_t i = 0; i<5;i++)
{
ReturnValue=ReturnValue+ValueDidgit[i]*LevelDig;
if(i<4) LevelDig=LevelDig*10;
}
return ReturnValue;
}
volatile uint8_t CountDidgitNumber=1;
uint8_t BtLongTime=10;
uint8_t FlagLongBT=0;
void InputMaskUpdate(uint16_t InputOne,uint16_t InputTwo,uint16_t InputThree)
{
switch(InputOne)
{
case BTN_SHRT_RA:
if(CheckOriginalPosition())
{
ModAuto=~ModAuto;
ModDebug=~ModDebug;
}
if (!(ModAuto)) DISPLAY_MOD_JOB=1; else DISPLAY_MOD_JOB=0;
break;
case BTN_SHRT_ST:
ModTimer=~ModTimer;
if (ModTimer==0)
{
DISPLAY_MOD_TIM=0;
}else DISPLAY_MOD_TIM=1;
break;
case BTN_SHRT_PR:
FlangSetShortBtPR=1;
if (ModProgramming)
{
FlangSetLongBtPR=0;
ModProgramming=0;
}
break;
case BTN_LONG_PR:
FlangSetLongBtPR=1;
break;
case BTN_SHRT_EN:
if (ModProgramming)
{
if(ModTimer!=0)
{
CountDidgitNumber++;
if (CountDidgitNumber > 5)
{
CountDidgitNumber=1;
}
}
}
if (ModProgramming)
{
if (LevelModProg==0)
{
LevelModProg=1;
break;
}
if (LevelModProg==1)
{
LevelModProg=0;
break;
}
}
break;
case BTN_SHRT_UP:
if ((ModProgramming)&&(ModTimer==0))
{
if (LevelModProg == 0)
{
TimerActive++;
if(TimerActive==5) TimerActive=1;
}
if (LevelModProg == 1)
{
switch(TimerActive)
{
case 1:TimeToStartPW++;break;
case 2:TimeToStopPW++;break;
case 3:TimeOW++;break;
case 4:TimeReturn++;break;
}
UpdateEEPROM();
}
}
if (ModProgramming&&(ModTimer!=0))
{
SetProgProduct=ReplaceDigitValue(SetProgProduct,CountDidgitNumber,1);break;
}
break;
case BTN_SHRT_DN:
if ((ModProgramming)&&(ModTimer==0))
{
if (LevelModProg==0)
{
TimerActive--;
if(TimerActive==0) TimerActive=4;
}
if (LevelModProg==1)
{
switch(TimerActive)
{
case 1:TimeToStartPW--;break;
case 2:TimeToStopPW--;break;
case 3:TimeOW--;break;
case 4:TimeReturn--;break;
}
UpdateEEPROM();
}
}
if (ModProgramming&&(ModTimer!=0))
{
SetProgProduct=ReplaceDigitValue(SetProgProduct,CountDidgitNumber,0);break;
}
break;
case BTN_LONG_UP:
if ((ModProgramming)&&(ModTimer==0))
{
if (LevelModProg == 1)
{
switch(TimerActive)
{
case 1:
while((!(PINA&BTN_LINE_UP))&(TimeToStartPW < 59999))
{
if (BtLongTime == 0)
{
TimeToStartPW++;
BtLongTime=10;
}
BtLongTime=CountToNULL(BtLongTime);
}
break;
case 2:
TimeToStopPW++;
break;
case 3:
TimeOW++;
break;
case 4:
TimeReturn++;
break;
}
UpdateEEPROM();
}
}
break;
case BTN_LONG_DN:
if(ModTimer) CountProduct=0;
break;
case BTN_SHRT_SM:
if(ModDebug) FlagBtnSM=~FlagBtnSM;
break;
case BTN_SHRT_SB:
if(ModDebug) FlagBtnSB=~FlagBtnSB;
break;
default:break;
}
switch(InputTwo)
{
case BTN_SHRT_S1:
break;
case BTN_SHRT_S2:
break;
case GRK_SHRT_SM:
break;
case BTN_SHRT_PW:
if(ModDebug) FlagBtnPW=~FlagBtnPW;
break;
case BTN_SHRT_OW:
if(ModDebug) FlagBtnOW=~FlagBtnOW;
break;
case GRK_SHRT_ZM_IP:
break;
case GRK_SHRT_ZM_RP:
break;
case BTN_SHRT_ZM:
break;
default:break;
}
switch(InputThree)
{
/*
case DAT_SHRT_PWR: Датчик не работает в связи с
break; Запаздалой реакцией PC817
*/
case BTN_SHRT_MOD:
break;
default:break;
}
}
uint8_t StartCycleWork(uint8_t Bt1,uint8_t bt2)
{
uint8_t StartCycle=0;
if (Bt1&&bt2)
{
StartCycle = 1;
}
if ((BTN_PIN2 & BTN_LINE_S1)||(BTN_PIN2 & BTN_LINE_S2))
{
StartCycle=0;
}
return StartCycle;
}
uint8_t OneEnablePower=1;
void LoadEEPROM()
{
TimeToStartPW = eeprom_read_word(&eepTimeToStartPW);
TimeToStopPW = eeprom_read_word(&eepTimeToStopPW);
TimeOW = eeprom_read_word(&eepTimeOW);
TimeReturn = eeprom_read_word(&eepTimeReturn);
//if(OneEnablePower) CountProduct = eeprom_read_word(&eepCountProduct);
}
//Функция проверки исполнительных устройств на исходное положение.
int main(void)
{
InitIO_MC(); //Иницилизация портов.
LoadEEPROM();
StartInitIO();
SPI_Init();
SpiUpdateRegister();
_delay_ms(100);
InitTimer1_OVF();
InitTimer0_OVF();
ENABLE_POWER;
volatile uint8_t FlagOriginalPosition = 0;
if (OneEnablePower) OneEnablePower=0;
sei();
while(1)
{
InputMaskUpdate(MaskGetOne(),MaskGetTwo(),MaskGetThree());
if (FlagsEnDiplay) //Проверка флага разрешения вывода информации
{
if((CountProduct >= SetProgProduct)&&(SetProgProduct!=0))
{
FlagOverflowProduct=1;
} else {
FlagOverflowProduct=0;
}
if((!(ModTimer))&&(ModProgramming==0)) //Если режим таймера = 0 , то выводим Т1..Т4
{
TimeSumm=TimeToStartPW+TimeToStopPW+TimeOW+TimeReturn;
switch(StepAuto)
{
case 0: //Ожидания начала цикла(Ожидания старта от StartCycleWork() )
PrintNumber((TimeSumm),0,Flags); //Выводим Сумму Т1..Т4
break;
case 1: //Обработка Т1
PrintNumber((TimeToStartPW),StepAuto,Flags);
break;
case 2: //Обработка Т2
PrintNumber((TimeToStopPW),StepAuto,Flags);
break;
case 3: //Обработка Т3
PrintNumber((TimeOW),StepAuto,Flags);
break;
case 4: //Обработка Т4
PrintNumber((TimeReturn),StepAuto,Flags);
break;
}
}
if ((ModTimer)&&(ModProgramming==0)) //Если режим таймера = 1, то выводим счетчик.
{
if(FlagOverflowProduct==0){
Flags.Bits.DO0=0;
Flags.Bits.DO1=0;
Flags.Bits.DO2=0;
Flags.Bits.DO3=0;
Flags.Bits.DO4=0;
PrintNumber((CountProduct),0,Flags);
}
else{
Flags.Bits.DO0=1;
Flags.Bits.DO1=1;
Flags.Bits.DO2=1;
Flags.Bits.DO3=1;
Flags.Bits.DO4=1;
PrintNumber((CountProduct),0,Flags);
}
}
//Если выбран режим программирования.
if(ModProgramming)
{
if (ModTimer==0) //Отображение программирования режима таймера.
{
if (LevelModProg==0)
{
Flags.Bits.DO0=0;
Flags.Bits.DO1=0;
Flags.Bits.DO2=0;
Flags.Bits.DO3=0;
Flags.Bits.DO5=1;
}
if (LevelModProg==1)
{
Flags.Bits.DO0=1;
Flags.Bits.DO1=1;
Flags.Bits.DO2=1;
Flags.Bits.DO3=1;
Flags.Bits.DO5=0;
}
switch(TimerActive)
{
case 1:
PrintNumber((TimeToStartPW),TimerActive,Flags);
break;
case 2: // Т2
PrintNumber((TimeToStopPW),TimerActive,Flags);
break;
case 3: // Т3
PrintNumber((TimeOW),TimerActive,Flags);
break;
case 4: // Т4
PrintNumber((TimeReturn),TimerActive,Flags);
break;
default: break;
}
}
if (ModTimer!=0) //Отображение программирования режима счетчика.
{
switch(CountDidgitNumber)
{
case 1:
Flags.Bits.DO0=1;
Flags.Bits.DO1=0;
Flags.Bits.DO2=0;
Flags.Bits.DO3=0;
Flags.Bits.DO4=0;
PrintNumber(SetProgProduct,0,Flags);
break;
case 2:
Flags.Bits.DO0=0;
Flags.Bits.DO1=1;
Flags.Bits.DO2=0;
Flags.Bits.DO3=0;
Flags.Bits.DO4=0;
PrintNumber(SetProgProduct,0,Flags);
break;
case 3:
Flags.Bits.DO0=0;
Flags.Bits.DO1=0;
Flags.Bits.DO2=1;
Flags.Bits.DO3=0;
Flags.Bits.DO4=0;
PrintNumber(SetProgProduct,0,Flags);
break;
case 4:
Flags.Bits.DO0=0;
Flags.Bits.DO1=0;
Flags.Bits.DO2=0;
Flags.Bits.DO3=1;
Flags.Bits.DO4=0;
PrintNumber(SetProgProduct,0,Flags);
break;
case 5:
Flags.Bits.DO0=0;
Flags.Bits.DO1=0;
Flags.Bits.DO2=0;
Flags.Bits.DO3=0;
Flags.Bits.DO4=1;
PrintNumber(SetProgProduct,0,Flags);
break;
default:break;
}
}
} else if(SetProgProduct == 0)Flags.Byte=0;
FlagsEnDiplay=0; // Обнуляем Флаг разрешения. (Включается в прерывание таймера 0)
}
if(FlangSetLongBtPR)
{
ModProgramming=1;
}
//Алгоритм работы выходных MosFet ключей в ручном режиме(Режиме отладки).
if ((ModDebug!=0)&&(ModAuto == 0)&&(ModProgramming==0))
{
ENABLE_POWER;
if (BtPW)
{
ENABLE_PW;
} else DISABLE_PW;
if (BtOW)
{
ENABLE_OW;
} else DISABLE_OW;
if ((FlagBtnSM)&&(StepDebug!=2))
{
FlagSM=1;
StepDebug=1;
ENABLE_SM;
} else if (FlagSB==0)
{
DISABLE_SM;
FlagSM=0;
}
if (FlagBtnSB)
{
FlagSB=1;
StepDebug=2;
ENABLE_SB;
}
else {
DISABLE_SB;
FlagSB=0;
StepDebug=0;
}
}
//Алгоритм работы выходных MosFet ключей в режиме цикла.(Автоматический режим).
if ((ModAuto!=0)&&(ModDebug == 0)&&(ModProgramming==0))
{
if (FlagOverflowProduct==0)
{
Flags.Byte=0;
} else {
Flags.Bits.DO0=1;
Flags.Bits.DO1=1;
Flags.Bits.DO2=1;
Flags.Bits.DO3=1;
Flags.Bits.DO5=1;
}
switch(StepAuto)
{
case 0:
switch(FlagOriginalPosition)
{
case 0:
DISABLE_POWER;
FlagOriginalPosition=CheckOriginalPosition();
break;
case 1:
FlagOriginalPosition=2;
break;
case 2:
if (StartCycleWork(BtS1,BtS2))
{
ENABLE_POWER;
ENABLE_SM;
if (GrKSM) StepAuto=1;
}
else
{
DISABLE_SM;
DISABLE_POWER;
}
break;
}
break;
case 1:
FlagOriginalPosition=0;
ENABLE_SB;
TimeToStartPW=CountToNULL(TimeToStartPW);
if (!(GrKSM)) StepAuto=5;
if (TimeToStartPW==0) StepAuto=2;
break;
case 2:
ENABLE_PW;
TimeToStopPW=CountToNULL(TimeToStopPW);
if (!(GrKSM)) StepAuto=5;
if (TimeToStopPW==0)
{
DISABLE_PW;
StepAuto=3;
}
break;
case 3:
ENABLE_OW;
TimeOW=CountToNULL(TimeOW);
if (!(GrKSM)) StepAuto=5;
if (TimeOW==0)
{
DISABLE_OW;
StepAuto=4;
}
break;
case 4:
TimeReturn=CountToNULL(TimeReturn);
if (!(GrKSM)) StepAuto=5;
if (TimeReturn==0)
{
DISABLE_SB;
//Подумать о добавлении задержки 100-200ms.
DISABLE_SM;
if (CheckOriginalPosition())
{
LoadEEPROM();
CountProduct++;
StepAuto=0;
}
}
break;
case 5:
DISABLE_OW;
DISABLE_PW;
DISABLE_SB;
TimeErrorStop=CountToNULL(TimeErrorStop);
if (TimeErrorStop==0)
{
DISABLE_SM;
StepAuto=6;
}
break;
case 6:
TimeErrorStop=25;
if (CheckOriginalPosition())
{
LoadEEPROM();
StepAuto=0;
}
break;
}
}
}
return 0;
}
Тут не большой косяк с временной задержкой ща ченить исправлю ))
Добавлено after 29 minutes 52 seconds:
Подход выше не работает все таки )
Сделал на флагах вродевсе робит. Правдо не знаю на сколько это коректно.
В основном теле программы:
Код: Выделить всё
if((!(PINA&BTN_LINE_UP))&&(TimeToStartPW < 59999)&&FlagLongBT)
{
if(FlagEnableIncrement)
{
TimeToStartPW++;
FlagEnableIncrement=0;
}
} else FlagLongBT=0;
FlagEnableIncrement - активируется в прерывании
щас попробую превизять вторую кнопку минус и наверно сделать это функцией т.к есть 4 переменные с которыми может происходить данное действие.
andrei23061996@gmail.com
.................................................................................................................
.................................................................................................................
странно... (не вижу никаких сложностей)
просто в своей функции, если кнопка нажата и счетчик досчитал - делай дело и сбрасывай счетчик (он потом опять досчитает - так и будет цикличность)
просто в своей функции, если кнопка нажата и счетчик досчитал - делай дело и сбрасывай счетчик (он потом опять досчитает - так и будет цикличность)
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- Сообщения: 303
- Зарегистрирован: Ср май 03, 2017 03:22:26
Всем спасибо за советы ) к чему то прислушался чего то не понял , но главное сделал.
Теперь настало время причесать фул код ))
Код: Выделить всё
void UpdlngBt()
{
if (FlagLongBT)
{
if((!(PINA&BTN_LINE_UP))||(!(PINA&BTN_LINE_DN)))
{
if(!(PINA&BTN_LINE_UP))
{
if (FlagEnableIncrement)
{
switch(TimerActive)
{
case 1:TimeToStartPW++;break;
case 2:TimeToStopPW++;break;
case 3:TimeOW++;break;
case 4:TimeReturn++;break;
}
FlagEnableIncrement=0;
}
}
if(!(PINA&BTN_LINE_DN))
{
if (FlagEnableIncrement)
{
switch(TimerActive)
{
case 1:TimeToStartPW--;break;
case 2:TimeToStopPW--;break;
case 3:TimeOW--;break;
case 4:TimeReturn--;break;
}
FlagEnableIncrement=0;
}
}
}else FlagLongBT=0;
}
}
andrei23061996@gmail.com
.................................................................................................................
.................................................................................................................


