Эффективность функции?Работа с 16 бит числом.Atmega16.

Обсуждаем контроллеры компании Atmel.
Ответить
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 303
Зарегистрирован: Ср май 03, 2017 03:22:26

Сообщение 7seg »

Уважаемые коты хотелось бы с вами посоветоваться, не слишком ли жирная следующая функция для ее задач ?) все-таки работа на 8-битном мк с 16-битным числом.

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

//Функция  изменения выбранного разряда(NuberDidgit), в числе(OriginalValue) на +/-(1).
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;
}
andrei23061996@gmail.com
.................................................................................................................
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

а что вас смущает? функция, как функция... ничего крамольного.
на 8-битном Мк спокойно float-ы обрабатываются, 32-битные и даже иногда 64-битные тоже. и ни один МК еще не взорвался от перегрузки :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 303
Зарегистрирован: Ср май 03, 2017 03:22:26

Сообщение 7seg »

Просто такое ощущение что она прерывается при выполнении. Щас пытаюсь разобраться где въехал в пень. некоторые др функции не работают.
Осторожно индуссо-код XD
Спойлер

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

/*
 * 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 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).
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: 
			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:
			break;
		case BTN_LONG_DN:
			if(ModTimer) CountProduct=0;
			break;
		case BTN_SHRT_SM:
			FlagBtnSM=~FlagBtnSM;
			break;
		case BTN_SHRT_SB:
			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:
			FlagBtnPW=~FlagBtnPW;
			break;
		case BTN_SHRT_OW:
			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){
					PrintNumber((CountProduct),0,Flags);
				}
				else{
					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 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))
		{
			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 (TimeToStartPW==0) StepAuto=2;
					break;
				case 2:
					ENABLE_PW;
					TimeToStopPW=CountToNULL(TimeToStopPW);
					if (TimeToStopPW==0)
					{
						DISABLE_PW;
						StepAuto=3;
					}
					break;
				case 3:
					ENABLE_OW;
					TimeOW=CountToNULL(TimeOW);
					if (TimeOW==0)
					{
						DISABLE_OW;
						StepAuto=4;
					}
					break;
				case 4:
				TimeReturn=CountToNULL(TimeReturn);
				if (TimeReturn==0)
				{
					;
					DISABLE_SB;
					//Подумать о добавлении задержки 100-200ms.
					DISABLE_SM;
					if (CheckOriginalPosition())
					{
						LoadEEPROM();
						CountProduct++;
						StepAuto=0;
					}
				}
					break;
			}
			
		}
    }
	return 0;
}

Пока что попробую сам разобраться )
andrei23061996@gmail.com
.................................................................................................................
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

что-то многовато у вас volatile переменных. да и огромное количество локальных static-переменных в функциях тоже как-то настораживает.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 303
Зарегистрирован: Ср май 03, 2017 03:22:26

Сообщение 7seg »

Тоже так думаю щас в железе еще пару фич реализую и начну код чистить от шлака. главное сейчас от текущих багов избавиться ))
andrei23061996@gmail.com
.................................................................................................................
Реклама
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

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

uint16_t ReplaceDigitValue(uint16_t OriginalValue, uint8_t NuberDidgit, uint8_t UpDown)
{
	const uint16_t tbl[] = { 1, 10, 100, 1000, 10000 };
	uint16_t val = tbl[NuberDidgit - 1];
	uint8_t digit = OriginalValue / val % 10;
	if (UpDown == 0 && digit > 0)  OriginalValue -= val;
	if (UpDown == 1 && digit < 9)  OriginalValue += val;
	return OriginalValue;
}
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

при поразрядном редактировании числа не все так просто: как правило, всегда требуется ограничение сверху/снизу, то есть правила ввода цифр для старшего разряда и для младших явно не одинаковы. Более того, если число ограничено значением, предположим, 1024, то не так-то и просто формализовать правила редактирования любой отдельной цифры. я это многократно проходил, как ни крути - получаются "простыни" кода или множество занятных функций...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="ARV",url="/forum/viewtopic.php?p=3440282#p3440282"]при поразрядном редактировании числа не все так просто: как правило, всегда требуется ограничение сверху/снизу, то есть правила ввода цифр для старшего разряда и для младших явно не одинаковы. Более того, если число ограничено значением, предположим, 1024, то не так-то и просто формализовать правила редактирования любой отдельной цифры.[/uquote]

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

if (UpDown == 1 && ((NuberDidgit < 5 && digit < 9) || digit < 6))
{
    if(OriginalValue + val < 1024)
        OriginalValue += val;
}
Это в общем виде, вверху условие для uint16_t, для 1024 его нужно немного изменить, но в целом т.к. работа идет непосредственно с числами, а не массивами, то проверки получаются очень простыми.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

ну да, проверки простые, но их много. а если редактируемых параметров несколько, и у каждого свои ограничения, то приходим к... тому, от чего пытались уйти :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 303
Зарегистрирован: Ср май 03, 2017 03:22:26

Сообщение 7seg »

Все верно , число OriginalValue ограниченно 0..59999
andrei23061996@gmail.com
.................................................................................................................
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="7seg",url="/forum/viewtopic.php?p=3440304#p3440304"]Все верно , число OriginalValue ограниченно 0..59999[/uquote]
Вроде так:

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

uint16_t ReplaceDigitValue(uint16_t OriginalValue, uint8_t NuberDidgit, uint8_t UpDown)
{
    const uint16_t tbl[] = { 1, 10, 100, 1000, 10000 };
    uint16_t val = tbl[NuberDidgit - 1];
    if (OriginalValue < val - 1) return OriginalValue;
    uint8_t digit = OriginalValue / val % 10;
    if (UpDown == 0 && digit > 0)  OriginalValue -= val;
    if (UpDown == 1 && digit < 9 && OriginalValue + val < 60000)
        OriginalValue += val;
    return OriginalValue;
}
Не, погоди, еще не все... :)
Добавил еще одну проверку, чтобы не инкрементировались старшие разряды, которые у конкретного числа могут отсутствовать.
Последний раз редактировалось Reflector Пн авг 20, 2018 10:52:31, всего редактировалось 2 раза.
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 303
Зарегистрирован: Ср май 03, 2017 03:22:26

Сообщение 7seg »

У вас хороший стиль Reflector .
Мне самоучке еще не один год наверно до такого еще совершенствоваться )

Добавлено after 34 minutes 45 seconds:
Только ваш код не работает )
andrei23061996@gmail.com
.................................................................................................................
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="7seg",url="/forum/viewtopic.php?p=3440322#p3440322"]Только ваш код не работает )[/uquote]
А на AVR int же вроде 16 бит? Тогда OriginalValue + val нужно явно привести к 32-м, у меня на ПК и ARM это и так происходит...
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Проще, наверное, разбить на массив значений и одно из них редактировать.
Контактная информация:
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 303
Зарегистрирован: Ср май 03, 2017 03:22:26

Сообщение 7seg »

Для данного устройства эта прошивка )
Изображение
Изображение
andrei23061996@gmail.com
.................................................................................................................
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="Аlex",url="/forum/viewtopic.php?p=3440351#p3440351"]Проще, наверное, разбить на массив значений и одно из них редактировать.[/uquote]
Изначально же так и было, чем тот подход проще? Еще и медленнее раз в 10.
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Ну, то что медленнее - да. Но проще :))
Кстати, по поводу ограничения по макс. значению. Я бы не парился запихнуть весь функционал в одну функцию и сделал бы проверку при подтверждении. Т.е. , дал бы корректировать все цифры без препятствий (хоть до 99999), а после подтверждения - условие на переполнение. И если >60000, то корректируется на это значение. Всё просто и никакого гемора с кучей проверок.
Функция, в которую передаётся текущее и макс. значения. В ней всё крутится - выбор индикатора, его мигание, кнопки, .... Возврат - скорректированное значение.
Тем более, такое пишется всяко не для одного значения, а для множества параметров. А у разных параметров, как правило, разные диапазоны.
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="Аlex",url="/forum/viewtopic.php?p=3440377#p3440377"]Ну, то что медленнее - да. Но проще :))[/uquote]
Да не проще он. Допустим у нас число 1234 и нужно проинкрементить третий разряд, тогда берем из массива число 100 и просто его прибавляем, получая 1334. Все,
при этом если бы было ограничение на числа до 1300, то результат сложения просто отменяется как больший этих 1300.
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Возможно, возможно...
Я, например, редактирование больших значений делаю с обработкой длительного нажатия. Чем дольше держишь, тем больше прибавляется/уменьшается за единицу времени. Вот это гораздо проще, быстрее в плане выполнения кода и удобнее для пользователя.
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

я делал вообще не совсем так. при поразрядном редактировании было бы странно, если бы при числе 1023 при попытке изменить третий разряд мы получали 1024. я делал так, что разряд менялся только в том случае, если полученное число не выходит за пределы допустимого. соответственно, проверок чуть больше, но в целом более интуитивно получается.
вариант Alex-а тоже неоднократно применял, но он менее удобный, имхо: при увеличении скорости изменения числа легко можно проскочить нужное значение, а затем придется откатывать назад...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Ответить

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