EEPROM запись в цикле.

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

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

Столкнулся с проблемкой по работе с ЕЕПРОМом , (провожу симуляцию в протеусе)ж

в еепром должны записаться 1,2. А суда по симуляции в протеусе там хреновина какая та пишется.

Проблема в протеусе или в коде ? может кто подсказать.
Вместо eeprom_write_byte(); , буду использывать eeprom_update_byte();
фулл код:
Спойлер

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

#define F_CPU 8000000UL

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
//-------------------------------------------///init_pwm///-----------------------------------------------------------------//
void init_pwm()
{
	TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (1<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00);
	TCCR0B=(0<<WGM02) | (0<<CS02) | (1<<CS01) | (0<<CS00);
	OCR0A=0x00;
	OCR0B=0x00;

	TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (1<<WGM10);
	TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (1<<CS11) | (0<<CS10);
	OCR1AL=0x00;
	OCR1BL=0x00;

	TCCR2A=(1<<COM2A1) | (0<<COM2A0) | (1<<COM2B1) | (0<<COM2B0) | (1<<WGM21) | (1<<WGM20);
	TCCR2B=(0<<WGM22) | (0<<CS22) | (1<<CS21) | (0<<CS20);
	OCR2A=0x00;
	OCR2B=0x00;
}
//--------------------------------------------------------------------------------------------------------------------------//
void init_int0()
{
	//настраиваем на срабатывание INT0 по переднему фронту
	EICRA |= (1<<ISC01)|(0<<ISC00);
	//разрешаем внешнее прерывание INT0
	EIMSK |= (1<<INT0);
}
//--------------------------------------------------------------------------------------------------------------------------//
void init_io()
{
	DDRB=(0<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(0<<PB5)|(0<<PB6)|(0<<PB7);
	PORTB=0x00;
	DDRC=(1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4)|(1<<PC5)|(1<<PC6);
	PORTC=0x00;
	DDRD=(1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3)|(1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7);
	PORTD=0x00;
}
//--------------------------------------------------------------------------------------------------------------------------//
//настройка параметров работы функций
#define BTN_LOCK_TIME		30					/*время обработки дребезга в милисекундах (10-100)*/
#define BTN_LONG_TIME		1000				/*время фиксации длинного нажатия в милисекундах (1000 - 2500)*/
//настройки портов
/*порт чтения кнопок*/
#define BTN_PORT			PORTB
#define BTN_DDR				DDRB
#define BTN_PIN				PINB
/*пины чтения кнопок*/
#define BTN_LINE_UP		(1<<7)
#define BTN_LINE_DN		(1<<6)
#define BTN_LINE_POWER	(1<<5)
#define BTN_LINE_SW		(1<<0)
//глобальные переменные
volatile uint8_t BtnFlags;					//байт флагов нажатия кнопки
#define BTN_SHRT_UP			(1<<0)			/*бит короткого нажатия кнопки up*/
#define BTN_SHRT_DN			(1<<1)			/*бит короткого нажатия кнопки dn*/
#define BTN_SHRT_POWER		(1<<2)			/*бит короткого нажатия кнопки POWER */
#define BTN_SHRT_SW			(1<<3)			/*бит короткого нажатия кнопки SW*/
#define BTN_LONG_UP			(1<<4)			/*бит длинного нажатия кнопки up*/
#define BTN_LONG_DN			(1<<5)			/*бит длинного нажатия кнопки dn*/
#define BTN_LONG_SW			(1<<6)			/*бит короткого нажатия кнопки SW*/
//-------------------------------------------------------------------------------------------------------------------
//Функция настройки библиотеки работы с кнопками
void BtnInit (void)
{
	BTN_DDR &= ~(BTN_LINE_UP| BTN_LINE_DN| BTN_LINE_POWER|BTN_LINE_SW);//на ввод
	BTN_PORT |= (BTN_LINE_UP| BTN_LINE_DN| BTN_LINE_POWER|BTN_LINE_SW);//подтяжка вкл
}
//--------------------------------------------------------------------------------------------------------------------
//Функция чтения данных о нажатии кнопок
char BtnGet (void)
{
	cli();
	char temp = BtnFlags;
	BtnFlags = 0;
	sei();
	return temp;
}
//-----------------------------------------------------------------------------------------------------------------------
//ФУНКЦИЯ ОБРАБОТКИ НАЖАТИЙ КЛАВИШ (вызывать в прерывании с частотой 100 Гц)
//короткое нажатие устанавливает бит BTN_SHRT_X глобальной переменной BtnFlags
//длинное нажатие устанавливает бит BTN_LONG_X глобальной переменной BtnFlags
void BtnExe (void)
{
	static unsigned char BtnLockBit;				//защелка (защита от дребезга)
	static unsigned char BtnLockCoun;			//счетчик защелки (защита от дребезга)
	static unsigned char BtnLongCoun;			//счетчик длинного нажатия
	static unsigned char BtnLastState;			//последнее состояние кнопок перед отпусканием

	char mask = 0;
	if (! (BTN_PIN & BTN_LINE_UP))		mask = BTN_SHRT_UP;
	if (! (BTN_PIN & BTN_LINE_DN))		mask = BTN_SHRT_DN;
	if (! (BTN_PIN & BTN_LINE_POWER))	mask = BTN_SHRT_POWER;
	if (! (BTN_PIN & BTN_LINE_SW))		mask = BTN_SHRT_SW;

	if (mask){									//опрос состояния кнопки
		if (BtnLockCoun < (BTN_LOCK_TIME/10)){	//клавиша нажата
			BtnLockCoun++;
			return;								//защелка еще не дощитала - возврат
		}
		BtnLastState = mask;
		BtnLockBit =1;							//нажатие зафиксировано
		if (BtnLongCoun >= (BTN_LONG_TIME/10))
		return;								//возврат, т.к. счетчик длинн нажат досчитал до максимума еще раньше
		if (++BtnLongCoun >= (BTN_LONG_TIME/10))
		BtnFlags |= (BtnLastState<<4);			//счетчик досчитал до максимума - устанавливаем биты длинного нажатия
	}
	else{										//клавиша отжата
		if (BtnLockCoun){
			BtnLockCoun --;
			return;								//защелка еще не обнулилась - возврат
		}
		if (! BtnLockBit)						//СТАТИЧЕСКИЙ ВОЗВРАТ
		return;
		BtnLockBit =0;							//отжатие зафиксировано
		if (BtnLongCoun < (BTN_LONG_TIME/10))
		BtnFlags |= BtnLastState;			//установка бита короткого нажатия
		BtnLongCoun = 0;					//сброс счетчика длительности нажатия
	}
}
//------------------------------------------------------****7SEG****----------------------------------------------------------
#define SEGA 6
#define SEGB 5
#define SEGC 1
#define SEGD 2
#define SEGE 3
#define SEGF 4
#define SEGG 0

#define ANOD1 4
#define ANOD2 7
#define ANOD3 4
//-------------------------------------------------------------------------------------------------------------------------
void segchar (unsigned char seg)
{
	switch (seg)
	{
		case 0:
		PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(1<<SEGG);break;
		case 1:
		PORTC=(1<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG);break;
		case 2:
		PORTC=(0<<SEGA)|(0<<SEGB)|(1<<SEGC)|(0<<SEGD)|(0<<SEGE)|(1<<SEGF)|(0<<SEGG);break;
		case 3:
		PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(1<<SEGF)|(0<<SEGG);break;
		case 4:
		PORTC=(1<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
		case 5:
		PORTC=(0<<SEGA)|(1<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
		case 6:
		PORTC=(0<<SEGA)|(1<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
		case 7:
		PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG);break;
		case 8:
		PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
		case 9:
		PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
		case 99: //OFF Все сегменты
		PORTC=(1<<SEGA)|(1<<SEGB)|(1<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG);break;
	}
}
unsigned char ValuePWM[]={0,0,0,0,0,0};
unsigned char FlagPower[]={0,0,0,0,0,0};
void UpdateFlagPower(unsigned char ZoneNumber,unsigned char Flag)
{
	FlagPower[ZoneNumber]=Flag;
}

void UpdateValue(void)
{
	for (unsigned char ValueCount = 0; ValueCount < 5; ValueCount++)
	{
		switch (ValueCount)
		{
			case 0:
			OCR0A=ValuePWM[ValueCount]*2.56;break;
			case 1:
			OCR0B=ValuePWM[ValueCount]*2.56;break;
			case 2:
			OCR1AL=ValuePWM[ValueCount]*2.56;break;
			case 3:
			OCR1BL=ValuePWM[ValueCount]*2.56;break;
			case 4:
			OCR2A=ValuePWM[ValueCount]*2.56;break;
			case 5:
			OCR2B=ValuePWM[ValueCount]*2.56;break;
		}
	}
}
unsigned char data1 = 0;
unsigned char data2 = 0;
unsigned char count = 0;
unsigned char ZoneNumber=0;
void WriteSeg(unsigned char Number)
{
	data1=ValuePWM[Number]%10;
	data2=ValuePWM[Number]/10;
	PORTB |=(1<<ANOD1);
	PORTD |=(1<<ANOD2);
	PORTD |=(1<<ANOD3);
	segchar(99);
	count++;
	if (count==1){
		PORTB &= ~(1<<ANOD1);
		segchar(data1);
		PORTD |=(1<<ANOD2);
		PORTD |=(1<<ANOD3);
	}
	if (count==2){
		PORTD &= ~(1<<ANOD2);
		segchar(data2);
		PORTB |=(1<<ANOD1);
		PORTD |=(1<<ANOD3);
	}
	if (count==3){
		PORTD &= ~(1<<ANOD3);
		segchar(Number+1);
		PORTB |=(1<<ANOD1);
		PORTD|=(1<<ANOD2);
	}
	if (count==3){count=0;}
}
ISR(INT0_vect)
{
	WriteSeg(ZoneNumber);
	UpdateValue();
	BtnExe();
}
unsigned char fBtnPower=0;
void BtnUpdate(void)
{
	char BtnMask = BtnGet ();
	if (BtnMask == BTN_SHRT_POWER)
	{
	}
	if ((BtnMask == BTN_SHRT_SW))
	{
		ZoneNumber++;
		if (ZoneNumber==6)
		{
			ZoneNumber=0;
		}
	}
	//одиночное нажатие +
	if ((BtnMask == BTN_SHRT_UP)& (ValuePWM[ZoneNumber] < 99))
	{
		ValuePWM[ZoneNumber]++;
	}
	//одиночное нажатие -
	if ((BtnMask == BTN_SHRT_DN)& (ValuePWM[ZoneNumber] > 0))
	{
		ValuePWM[ZoneNumber]--;
	}
	//Удержание +
	if ((BtnMask == BTN_LONG_UP) & (ValuePWM[ZoneNumber] < 99))
	{
		while ((!(PINB&0b10000000))& (ValuePWM[ZoneNumber] < 99))
		{
			ValuePWM[ZoneNumber]++;
			_delay_ms(50);
		}
	}
	//Удержание -
	if ((BtnMask == BTN_LONG_DN) & (ValuePWM[ZoneNumber] > 0))
	{
		while ((!(PINB&0b01000000))& (ValuePWM[ZoneNumber] > 0))
		{
			ValuePWM[ZoneNumber]--;
			_delay_ms(50);
		}
	}
}
//-----------------------------------------------------------------------------------------------------

uint8_t EEMEM FlagPower1_EEPROM=0;
uint8_t EEMEM FlagPower2_EEPROM=0;
uint8_t EEMEM FlagPower3_EEPROM=0;
uint8_t EEMEM FlagPower4_EEPROM=0;
uint8_t EEMEM FlagPower5_EEPROM=0;
uint8_t EEMEM FlagPower6_EEPROM=0;

uint8_t EEMEM Value1_EEPROM=0;
uint8_t EEMEM Value2_EEPROM=0;
uint8_t EEMEM Value3_EEPROM=0;
uint8_t EEMEM Value4_EEPROM=0;
uint8_t EEMEM Value5_EEPROM=0;
uint8_t EEMEM Value6_EEPROM=0;

unsigned char LoadingFlagEEPROM(uint8_t NumberZone)
{
	unsigned char PowerFlag=0;
	switch(NumberZone)
	{
		case 1:
		PowerFlag = eeprom_read_byte(&Value1_EEPROM);
		break;
		case 2:
		PowerFlag = eeprom_read_byte(&Value2_EEPROM);
		break;
		case 3:
		PowerFlag = eeprom_read_byte(&Value3_EEPROM);
		break;
		case 4:
		PowerFlag = eeprom_read_byte(&Value4_EEPROM);
		break;
		case 5:
		PowerFlag = eeprom_read_byte(&Value5_EEPROM);
		break;
		case 6:
		PowerFlag = eeprom_read_byte(&Value6_EEPROM);
		break;
	}
	_delay_ms(10);
	return(PowerFlag);
}
uint8_t LoadingValueEEPROM(uint8_t NumberZone)
{
	uint8_t ValueFlag=0;
	switch(NumberZone)
	{
		case 1:
		ValueFlag = eeprom_read_byte(&FlagPower1_EEPROM);
		break;
		case 2:
		ValueFlag = eeprom_read_byte(&FlagPower2_EEPROM);
		break;
		case 3:
		ValueFlag = eeprom_read_byte(&FlagPower3_EEPROM);
		break;
		case 4:
		ValueFlag = eeprom_read_byte(&FlagPower4_EEPROM);
		break;
		case 5:
		ValueFlag = eeprom_read_byte(&FlagPower5_EEPROM);
		break;
		case 6:
		ValueFlag = eeprom_read_byte(&FlagPower6_EEPROM);
		break;
	}
	_delay_ms(10);
	return(ValueFlag);
}

void SaveEEPROM(uint8_t SaveValue,uint8_t SaveFlagPower,uint8_t NumberZone)
{
	switch(NumberZone)
	{
		case 1:
		eeprom_write_byte (&Value1_EEPROM, SaveValue);
		eeprom_write_byte (&FlagPower1_EEPROM, SaveFlagPower);
		break;
		case 2:
		eeprom_write_byte (&Value2_EEPROM, SaveValue);
		eeprom_write_byte (&FlagPower2_EEPROM, SaveFlagPower);
		break;
		case 3:
		eeprom_write_byte (&Value3_EEPROM, SaveValue);
		eeprom_write_byte (&FlagPower3_EEPROM, SaveFlagPower);
		break;
		case 4:
		eeprom_write_byte (&Value4_EEPROM, SaveValue);
		eeprom_write_byte (&FlagPower4_EEPROM, SaveFlagPower);
		break;
		case 5:
		eeprom_write_byte (&Value5_EEPROM, SaveValue);
		eeprom_write_byte (&FlagPower5_EEPROM, SaveFlagPower);
		break;
		case 6:
		eeprom_write_byte (&Value6_EEPROM, SaveValue);
		eeprom_write_byte (&FlagPower6_EEPROM, SaveFlagPower);
		break;
	}
}

//-----------------------------------------------------------------------------------------------------
int main(void)
{
	for (unsigned char Count = 0; Count < 5; Count++)
	{
		SaveEEPROM(1,2,Count+1);
		_delay_ms(15);
	}
	
	for (unsigned char Count = 0; Count < 5; Count++)
	{
		FlagPower[Count]=LoadingFlagEEPROM(Count+1);
	}
	
	for (unsigned char Count = 0; Count < 5; Count++)
	{
		ValuePWM[Count]=LoadingValueEEPROM(Count+1);
	}
	init_io();
	init_int0();
	BtnInit();
	init_pwm();
	_delay_ms(10);
	sei();
    while(1)
    {
		BtnUpdate();
	}
	return 0;
}
Последний раз редактировалось 7seg Пт окт 20, 2017 07:45:14, всего редактировалось 1 раз.
andrei23061996@gmail.com
.................................................................................................................
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Вот вы эту простыню зачем тут запостили? Вместо неё лучше бы расшифровали, что за фигня у вас пишется вместо 1, 2 - больше толку было бы.
Но скажу вам следующее, возможно, что-то окажется полезным:
1. функций для записи есть несколько: для байта, слова (2 байта), для двойного слова (4 байта) и для блока произвольной длины. выбирайте ту, которая вам больше подходит для данных, и не ломайте голову напрасно
2. функции, содержащие вместо write слово update в своем названии предназначены для продления ресурса записи в EEPROM: прежде чем записать ячейку, эти функции считывают ее и сравнивают с новыми данными - если новые данные не отличаются от уже имеющихся в ячейке, запись не выполняется. так что эти функции работают медленнее, но менее изнашивают EEPROM. повлиять на ваши "чудеса" они не смогут никак.
3. протеус корректно отрабатывает длительность записи в EEPROM (около 4 мс), поэтому при прогоне по шагам программы сразу после выполнения функции записи вы не увидите в дампе EEPROM никакого обновления одного байта, а если писали несколько, то самого последнего записанного. зато спустя 4 мс (по часам симуляции протеуса) увидите
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

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

Есть 3 функции по работе с епромом:
SaveEEPROM(uint8_t SaveValue,uint8_t SaveFlagPower,uint8_t NumberZone)
LoadingValueEEPROM(uint8_t NumberZone)
LoadingFlagEEPROM(uint8_t NumberZone)
Эти функции работают с массивами
unsigned char ValuePWM[]={0,0,0,0,0,0};
unsigned char FlagPower[]={0,0,0,0,0,0};

Массивы в свою очередь содержат данные для 6ти каналов ШИМ и флаг о состоянии канала.

Добавлено after 6 minutes 23 seconds:
причем с 1го по 5тый канал ШИМа значения "2"(SaveEEPROM(1,2,Count+1); Пишется а в 6том канале нет.
andrei23061996@gmail.com
.................................................................................................................
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Ужас.
Посмотрел на ваш код - ужас.
У вас switch-ем выбирается, какая переменная пишется/читается - это ж кошмар! Ну поместите все в массив, и пишите элемент массива или сразу весь массив! структуры для этого служат, например... и тогда у вас вся запись превратится в единственный eeprom_update_block, чтение соответственно тоже...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

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

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

Сообщение ARV »

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

пусть у нас 6 вариантов конфигурации. каждая конфигурация содержит значения трех параметров. делаем так

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

// определяем константу-количество конфигураций
#define CONFIG_CNT 6

// описываем структуру конфигурации
typedef struct{
   int param1; 
   char param2;
   long param3;
} configuration;

//определяем массив конфигураций в EEPROM
EEMEM configuration e_config[CONFIG_CNT];

// для удобства такой же массив в ОЗУ
configuration config[CONFIG_CNT];

// вот так конфигурация из ОЗУ сохраняется в EEPROM
eeprom_update_block((void*)config, (void*)e_config, sizeof(config));

// вот так конфигурация считывается в ОЗУ из EEPROM
eeprom_read_block((void*)e_config, (void*)config, sizeof(config)); // я тут ранее опечатался - теперь корректно!!!

// вот так вы получаете параметр из 2-й конфигурации для работы
int var = config[1].param1;
и всё, никаких switch, никакой мороки, никакого гемора... всё будет работать, как часы. код сократится в 10 раз...

Добавлено after 4 minutes 50 seconds:
если вам все-таки приспичит считывать/записывать не весь массив конфигураций, а отдельно взятую конфигурацию из массива, то параметры функций блочной записи/чтения надо всего-навсего сделать такими: ((void*)&config, (void*)&e_config, sizeof(configuration)), то есть передавать в функцию не адреса и размер массивов целиком, а только адреса нужного элемента и размер структуры этого элемента.

хотя причин так делать я не вижу, разве что экономия нескольких десятков миллисекунд...

Добавлено after 17 minutes 3 seconds:
еще в догонку...
параметры блочных функций такие (по порядку):
-адрес "откуда"
-адрес "куда"
-количество байт
Последний раз редактировалось ARV Пт окт 20, 2017 08:37:20, всего редактировалось 1 раз.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

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

То есть как я понял ,создаем массив структур e_config[] с типом configuration , который в себя включает нужное количество мне параметров.
Также дублируем этот маcсив в ОЗУ под именем config[](С этими значениями я уже могу работать непосредственно в теле программы).

eeprom_update_block((void*)config, (void*)e_config, sizeof(config));
eeprom_read_block((void*)config, (void*)e_config, sizeof(config));

для чего используется указатель пустого типа ? void* .

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

Сообщение ARV »

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

если вас варнинги не нервируют, можете не приводить.

Добавлено after 3 minutes 2 seconds:
7seg писал(а):eeprom_update_block((void*)config, (void*)e_config, sizeof(config));
eeprom_read_block((void*)config, (void*)e_config, sizeof(config));
обратите внимание на приписку о параметрах функций, которую я сделал позже - порядок адресов для чтения и записи - разный! на первом месте адрес массива, откуда берутся данные, на втором - куда помещаются. если вы сделаете так, как процитировано - функция чтения работать не будет
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

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

Еще раз спасибо , сейчас пробую реализовать структуру под мои нужды.

Добавлено after 3 minutes 1 second:
Яж правильно понимаю т.к номера элемента массивов начинаются с 0 , то для 6ти конфигураций мне нужно указать. #define CONFIG_CNT 5.

Добавлено after 6 minutes 49 seconds:
Хотя походу нет при компиляции:
EEPROM Memory Usage : 10 bytes 2,0 % Full

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

#define CONFIG_CNT 5
typedef struct
{
	char FlagPower;
	char ValuePWM;
}ConfigurationLamp;

EEMEM ConfigurationLamp E_ConfigLamp[CONFIG_CNT];
ConfigurationLamp ConfigLamp[CONFIG_CNT];
Походу создано на самом деле 5 копий а не 6 судя по тому что в епроме 10 bytes только занято а не 12.

Добавлено after 7 minutes 31 second:
и для инициализации ConfigLamp и E_ConfigLamp (стартовыми значениями )
Как я понял придется прогнать вот такой цикл ?
for (int i = 0; i< 5; i++)
{
ConfigLamp.FlagPower=0;
ConfigLamp.ValuePWM=0;
}
andrei23061996@gmail.com
.................................................................................................................
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

количество человек считает с 1, поэтому если у вас 6 конфигураций, и в программе надо 6 указывать. а вот НОМЕР конфигурации будет на 1 меньше :)
первый будет 0, а последний - 5.

что касается инициализации, то есть несколько способов.
1. если все нулями - есть 2 способа:
1.1 прямо в описании массива в EEPROM выполнить его инициализацию = {0}; а потом прошить в МК полученный .eep файл
1.2 глобальный массив в ОЗУ будет автоматически заполнен нулями, и поэтому достаточно его записать в EEPROM
2. если не все нулями, то можно поступить почти как в п.1: или инициализировать вручную и прошить, или аналогично заполнить в ОЗУ и сохранить.

для заполнения области памяти одинаковыми байтами рекомендую применять функцию memset из модуля string.h
для копирования одной области памяти в другую (например, заполнение массива структур одинаковыми, но ненулевыми, структурами) рекомендую применять функцию memcpy или memmove оттуда же.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

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

Заполняю структуру для теста вот таки кодом:

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

#define CONFIG_CNT 6
typedef struct
{
	char FlagPower;
	char ValuePWM;
}ConfigurationLamp;

EEMEM ConfigurationLamp E_ConfigLamp[CONFIG_CNT];
ConfigurationLamp ConfigLamp[CONFIG_CNT];

for (unsigned char ValueCount = 0; ValueCount < 5; ValueCount++)
{
	ConfigLamp[ValueCount].FlagPower=(ValueCount+1);
	ConfigLamp[ValueCount].ValuePWM=(6-ValueCount);
}
eeprom_update_block((void*)ConfigLamp, (void*)E_ConfigLamp, sizeof(ConfigLamp));

Смотрю заполнение в протеусе:
Изображение


оно же явно не правильное в конце:
000a должно быть = 06
000bдолжно быть = 05

Добавлено after 5 minutes 39 seconds:
Тфу сам тупил )))
Надо же for (unsigned char ValueCount = 0; ValueCount <= 5; ValueCount++).. Чет запарился походу я с этим епромом.
andrei23061996@gmail.com
.................................................................................................................
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

в чем ваша беда? в том, что вы думаете, будто ValueCount у вас пробегает по ВСЕМ элементам массива... а он, зараза, не пробегает.

вот так ПРАВИЛЬНО делать цикл по ВСЕМ элементам массива:

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

for (unsigned char ValueCount = 0; ValueCount < CONFIG_CNT; ValueCount++)
и, разумеется, если вы где-то еще по коду используете КОЛИЧЕСТВО КОНФИГУРАЦИЙ, вместо числа 6 вы ОБЯЗАНЫ использовать константу CONFIG_CNT, иначе зачем вы вообще её вводили?!

Добавлено after 2 minutes 43 seconds:
кстати, пользуйтесь типами строгой размерности. вместо длинного unsigned char применяйте короткий (и однозначный) uint8_t. ну и соответственно для других случаев аналогично in8_t, uint16_t, int16_t и т.д. (где u в начале означает "без знака", а число перед _t - количество бит в переменной).
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

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

Сделал пару функций для теста вроде работают(в протеусе значения меняются) но при перезапуске протеуса все значение в еппром = 00. Грешу на file.BIN созданный мной для еппрома.

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

#define CONFIG_AMOUNT 6
typedef struct
{
	char FlagPower;
	char ValuePWM;
}ConfigurationLamp;

EEMEM ConfigurationLamp E_ConfigLamp[CONFIG_AMOUNT];
ConfigurationLamp ConfigLamp[CONFIG_AMOUNT];

unsigned char ValuePWM[CONFIG_AMOUNT];
unsigned char FlagPower[CONFIG_AMOUNT];
void LoadingEEPROM()
{
	eeprom_read_block((void*)E_ConfigLamp, (void*)ConfigLamp, sizeof(ConfigLamp));
	for (unsigned char ValueCount = 0; ValueCount < CONFIG_AMOUNT; ValueCount++)
	{
		FlagPower[ValueCount]=ConfigLamp[ValueCount].FlagPower;
		ValuePWM[ValueCount]=ConfigLamp[ValueCount].ValuePWM;
	}
}

void SaveEEPROM()
{
	for (unsigned char ValueCount = 0; ValueCount < CONFIG_AMOUNT; ValueCount++)
	{
		ConfigLamp[ValueCount].FlagPower=(FlagPower[ValueCount]);
		ConfigLamp[ValueCount].ValuePWM=(ValuePWM[ValueCount]);
	}
	eeprom_update_block((void*)ConfigLamp, (void*)E_ConfigLamp, sizeof(ConfigLamp));
}

int main(void)
{
	LoadingEEPROM();
	init_io();
	init_int0();
	BtnInit();
	init_pwm();
	_delay_ms(10);
	sei();
    while(1)
    {
		SaveEEPROM();
		BtnUpdate();
	}
	return 0;
}
Добавлено after 13 minutes 29 seconds:
походу у функции чтения др порядок.
eeprom_read_block((void*)ConfigLamp, (void*)E_ConfigLamp, sizeof(ConfigLamp));
Куда.
Откуда.
Размер.

Добавлено after 1 hour 13 minutes 18 seconds:
А есть идеи как можно сделать покомпактней функцию UpdateValue();
Спойлер

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

 #define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
//-------------------------------------------///init_pwm///-----------------------------------------------------------------//
void init_pwm()
{
	TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (1<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00);
	TCCR0B=(0<<WGM02) | (0<<CS02) | (1<<CS01) | (0<<CS00);
	OCR0A=0x00;
	OCR0B=0x00;

	TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (1<<WGM10);
	TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (1<<CS11) | (0<<CS10);
	OCR1AL=0x00;
	OCR1BL=0x00;

	TCCR2A=(1<<COM2A1) | (0<<COM2A0) | (1<<COM2B1) | (0<<COM2B0) | (1<<WGM21) | (1<<WGM20);
	TCCR2B=(0<<WGM22) | (0<<CS22) | (1<<CS21) | (0<<CS20);
	OCR2A=0x00;
	OCR2B=0x00;
}
//--------------------------------------------------------------------------------------------------------------------------//
void init_int0()
{
	//настраиваем на срабатывание INT0 по переднему фронту
	EICRA |= (1<<ISC01)|(0<<ISC00);
	//разрешаем внешнее прерывание INT0
	EIMSK |= (1<<INT0);
}
//--------------------------------------------------------------------------------------------------------------------------//
void init_io()
{
	DDRB=(0<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(0<<PB5)|(0<<PB6)|(0<<PB7);
	PORTB=0x00;
	DDRC=(1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4)|(1<<PC5)|(1<<PC6);
	PORTC=0x00;
	DDRD=(1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3)|(1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7);
	PORTD=0x00;
}
//--------------------------------------------------------------------------------------------------------------------------//
//настройка параметров работы функций
#define BTN_LOCK_TIME		30					/*время обработки дребезга в милисекундах (10-100)*/
#define BTN_LONG_TIME		1000				/*время фиксации длинного нажатия в милисекундах (1000 - 2500)*/
//настройки портов
/*порт чтения кнопок*/
#define BTN_PORT			PORTB
#define BTN_DDR				DDRB
#define BTN_PIN				PINB
/*пины чтения кнопок*/
#define BTN_LINE_UP		(1<<7)
#define BTN_LINE_DN		(1<<6)
#define BTN_LINE_POWER	(1<<5)
#define BTN_LINE_SW		(1<<0)
//глобальные переменные
volatile uint8_t BtnFlags;					//байт флагов нажатия кнопки
#define BTN_SHRT_UP			(1<<0)			/*бит короткого нажатия кнопки up*/
#define BTN_SHRT_DN			(1<<1)			/*бит короткого нажатия кнопки dn*/
#define BTN_SHRT_POWER		(1<<2)			/*бит короткого нажатия кнопки POWER */
#define BTN_SHRT_SW			(1<<3)			/*бит короткого нажатия кнопки SW*/
#define BTN_LONG_UP			(1<<4)			/*бит длинного нажатия кнопки up*/
#define BTN_LONG_DN			(1<<5)			/*бит длинного нажатия кнопки dn*/
#define BTN_LONG_SW			(1<<6)			/*бит короткого нажатия кнопки SW*/
//-------------------------------------------------------------------------------------------------------------------
//Функция настройки библиотеки работы с кнопками
void BtnInit (void)
{
	BTN_DDR &= ~(BTN_LINE_UP| BTN_LINE_DN| BTN_LINE_POWER|BTN_LINE_SW);//на ввод
	BTN_PORT |= (BTN_LINE_UP| BTN_LINE_DN| BTN_LINE_POWER|BTN_LINE_SW);//подтяжка вкл
}
//--------------------------------------------------------------------------------------------------------------------
//Функция чтения данных о нажатии кнопок
char BtnGet (void)
{
	cli();
	char temp = BtnFlags;
	BtnFlags = 0;
	sei();
	return temp;
}
//-----------------------------------------------------------------------------------------------------------------------
//ФУНКЦИЯ ОБРАБОТКИ НАЖАТИЙ КЛАВИШ (вызывать в прерывании с частотой 100 Гц)
//короткое нажатие устанавливает бит BTN_SHRT_X глобальной переменной BtnFlags
//длинное нажатие устанавливает бит BTN_LONG_X глобальной переменной BtnFlags
void BtnExe (void)
{
	static unsigned char BtnLockBit;				//защелка (защита от дребезга)
	static unsigned char BtnLockCoun;			//счетчик защелки (защита от дребезга)
	static unsigned char BtnLongCoun;			//счетчик длинного нажатия
	static unsigned char BtnLastState;			//последнее состояние кнопок перед отпусканием

	char mask = 0;
	if (! (BTN_PIN & BTN_LINE_UP))		mask = BTN_SHRT_UP;
	if (! (BTN_PIN & BTN_LINE_DN))		mask = BTN_SHRT_DN;
	if (! (BTN_PIN & BTN_LINE_POWER))	mask = BTN_SHRT_POWER;
	if (! (BTN_PIN & BTN_LINE_SW))		mask = BTN_SHRT_SW;

	if (mask){									//опрос состояния кнопки
		if (BtnLockCoun < (BTN_LOCK_TIME/10)){	//клавиша нажата
			BtnLockCoun++;
			return;								//защелка еще не дощитала - возврат
		}
		BtnLastState = mask;
		BtnLockBit =1;							//нажатие зафиксировано
		if (BtnLongCoun >= (BTN_LONG_TIME/10))
		return;								//возврат, т.к. счетчик длинн нажат досчитал до максимума еще раньше
		if (++BtnLongCoun >= (BTN_LONG_TIME/10))
		BtnFlags |= (BtnLastState<<4);			//счетчик досчитал до максимума - устанавливаем биты длинного нажатия
	}
	else{										//клавиша отжата
		if (BtnLockCoun){
			BtnLockCoun --;
			return;								//защелка еще не обнулилась - возврат
		}
		if (! BtnLockBit)						//СТАТИЧЕСКИЙ ВОЗВРАТ
		return;
		BtnLockBit =0;							//отжатие зафиксировано
		if (BtnLongCoun < (BTN_LONG_TIME/10))
		BtnFlags |= BtnLastState;			//установка бита короткого нажатия
		BtnLongCoun = 0;					//сброс счетчика длительности нажатия
	}
}
//------------------------------------------------------****7SEG****----------------------------------------------------------
#define SEGA 6
#define SEGB 5
#define SEGC 1
#define SEGD 2
#define SEGE 3
#define SEGF 4
#define SEGG 0

#define ANOD1 4
#define ANOD2 7
#define ANOD3 4
//-------------------------------------------------------------------------------------------------------------------------
void segchar (unsigned char seg)
{
	switch (seg)
	{
		case 0:
		PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(1<<SEGG);break;
		case 1:
		PORTC=(1<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG);break;
		case 2:
		PORTC=(0<<SEGA)|(0<<SEGB)|(1<<SEGC)|(0<<SEGD)|(0<<SEGE)|(1<<SEGF)|(0<<SEGG);break;
		case 3:
		PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(1<<SEGF)|(0<<SEGG);break;
		case 4:
		PORTC=(1<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
		case 5:
		PORTC=(0<<SEGA)|(1<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
		case 6:
		PORTC=(0<<SEGA)|(1<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
		case 7:
		PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG);break;
		case 8:
		PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
		case 9:
		PORTC=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG);break;
		case 99: //OFF Все сегменты
		PORTC=(1<<SEGA)|(1<<SEGB)|(1<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG);break;
	}
}

#define CONFIG_AMOUNT 6
typedef struct
{
	char FlagPower;
	char ValuePWM;
}ConfigurationLamp;

EEMEM ConfigurationLamp E_ConfigLamp[CONFIG_AMOUNT];
ConfigurationLamp ConfigLamp[CONFIG_AMOUNT];

unsigned char ValuePWM[CONFIG_AMOUNT];
unsigned char FlagPower[CONFIG_AMOUNT];

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

void LoadingEEPROM()
{
	eeprom_read_block((void*)ConfigLamp, (void*)E_ConfigLamp, sizeof(ConfigLamp));
	for (unsigned char ValueCount = 0; ValueCount < CONFIG_AMOUNT; ValueCount++)
	{
		FlagPower[ValueCount]=ConfigLamp[ValueCount].FlagPower;
		ValuePWM[ValueCount]=ConfigLamp[ValueCount].ValuePWM;
	}
}

void SaveEEPROM()
{
	for (unsigned char ValueCount = 0; ValueCount < CONFIG_AMOUNT; ValueCount++)
	{
		ConfigLamp[ValueCount].FlagPower=(FlagPower[ValueCount]);
		ConfigLamp[ValueCount].ValuePWM=(ValuePWM[ValueCount]);
	}
	eeprom_update_block((void*)ConfigLamp, (void*)E_ConfigLamp, sizeof(ConfigLamp));
}
//-----------------------------------------------------------------------------------------------------

void UpdateFlagPower(unsigned char ZoneNumber,unsigned char Flag)
{
	FlagPower[ZoneNumber]=Flag;
}

void UpdateValue(void)
{
	for (unsigned char ValueCount = 0; ValueCount < CONFIG_AMOUNT; ValueCount++)
	{
		switch (ValueCount)
		{
			case 0:
			if (FlagPower[ValueCount]==1)
			{
				OCR0A=ValuePWM[ValueCount]*2.56;
			}
			else{
			OCR0A=0;
			}break;
			case 1:
			if (FlagPower[ValueCount]==1)
			{
				OCR0B=ValuePWM[ValueCount]*2.56;
			}
			else{
				OCR0B=0;}break;			
			case 2:
			if (FlagPower[ValueCount]==1)
			{
				OCR1AL=ValuePWM[ValueCount]*2.56;
			}
			else{
			OCR1AL=0;
			}break;			
			case 3:
			if (FlagPower[ValueCount]==1)
			{
				OCR1BL=ValuePWM[ValueCount]*2.56;
			}
			else{
			OCR1BL=0;
			}break;			
			case 4:
			if (FlagPower[ValueCount]==1)
			{
				OCR2A=ValuePWM[ValueCount]*2.56;
			}
			else{
			OCR2A=0;
			}break;			
			case 5:
			if (FlagPower[ValueCount]==1)
			{
				OCR2B=ValuePWM[ValueCount]*2.56;
			}
			else{
			OCR2B=0;
			}break;
		}
	}
}
unsigned char data1 = 0;
unsigned char data2 = 0;
unsigned char count = 0;
unsigned char ZoneNumber=0;

void WriteSeg(unsigned char Number)
{
	data1=ValuePWM[Number]%10;
	data2=ValuePWM[Number]/10;
	PORTB |=(1<<ANOD1);
	PORTD |=(1<<ANOD2);
	PORTD |=(1<<ANOD3);
	segchar(99);
	if(FlagPower[Number]==1)
	{
		count++;
		if (count==1){
			PORTB &= ~(1<<ANOD1);
			segchar(data1);
			PORTD |=(1<<ANOD2);
			PORTD |=(1<<ANOD3);
		}
		if (count==2){
			PORTD &= ~(1<<ANOD2);
			segchar(data2);
			PORTB |=(1<<ANOD1);
			PORTD |=(1<<ANOD3);
		}
		if (count==3){
			PORTD &= ~(1<<ANOD3);
			segchar(Number+1);
			PORTB |=(1<<ANOD1);
			PORTD|=(1<<ANOD2);
		}
		if (count==3){count=0;}
	}
}
ISR(INT0_vect)
{
	WriteSeg(ZoneNumber);
	UpdateValue();
	BtnExe();
}
unsigned char fBtnPower=0;
void BtnUpdate(void)
{
	char BtnMask = BtnGet ();
	if (BtnMask == BTN_SHRT_POWER)
	{
		FlagPower[ZoneNumber]++;
		if (FlagPower[ZoneNumber]>1)
		{
			FlagPower[ZoneNumber]=0;
		}
		SaveEEPROM();
	}
	if ((BtnMask == BTN_SHRT_SW))
	{
		ZoneNumber++;
		if (ZoneNumber==6)
		{
			ZoneNumber=0;
		}
	}
	//одиночное нажатие +
	if ((BtnMask == BTN_SHRT_UP)& (ValuePWM[ZoneNumber] < 99))
	{
		ValuePWM[ZoneNumber]++;
		SaveEEPROM();
	}
	//одиночное нажатие -
	if ((BtnMask == BTN_SHRT_DN)& (ValuePWM[ZoneNumber] > 0))
	{
		ValuePWM[ZoneNumber]--;
		SaveEEPROM();
	}
	//Удержание +
	if ((BtnMask == BTN_LONG_UP) & (ValuePWM[ZoneNumber] < 99))
	{
		while ((!(PINB&0b10000000))& (ValuePWM[ZoneNumber] < 99))
		{
			ValuePWM[ZoneNumber]++;
			_delay_ms(50);
		}
		SaveEEPROM();
	}
	//Удержание -
	if ((BtnMask == BTN_LONG_DN) & (ValuePWM[ZoneNumber] > 0))
	{
		while ((!(PINB&0b01000000))& (ValuePWM[ZoneNumber] > 0))
		{
			ValuePWM[ZoneNumber]--;
			_delay_ms(50);
		}
		SaveEEPROM();
	}
}

int main(void)
{
	LoadingEEPROM();
	_delay_ms(50);
	init_io();
	init_int0();
	BtnInit();
	init_pwm();
	_delay_ms(10);
	sei();
    while(1)
    {
		BtnUpdate();
	}
	return 0;
}
andrei23061996@gmail.com
.................................................................................................................
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

а объясните: зачем вам отдельные массивы ValuePower и FlagPower, если все то же самое у вас хранится в ConfigLamp? двойной расход памяти, лишние действия по переносу данных туда-сюда... зачем все это?
7seg писал(а):А есть идеи как можно сделать покомпактней функцию UpdateValue();
а что она делает? можете словами описать, потому что анализировать ваш код у меня лично желания нет...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

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

7seg писал(а):А есть идеи как можно сделать покомпактней функцию UpdateValue();
У Вас там куча повторяющегося кода, который можно вынести из switch-case. Да и switch-case там скорее всего вообще не нужен.
Контактная информация:
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 303
Зарегистрирован: Ср май 03, 2017 03:22:26

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

Функция UpdateValu() обновляет значения OCRХХ ,также проверяет FlagPower который отвечает за состояние канала (включен/выключен).
Так же сюда предполагал добавить плавное включение , т.е при переходе из состояние OFF в ОN повышать значение OCRХХ до значения записанного в еппром, антологичные действия при подачи питания на МК ( так сказать плавное включение ).
andrei23061996@gmail.com
.................................................................................................................
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

ну, плавное включение явно делать придется по таймеру... наверное.

а что касается остального, то, как я понимаю, функция смотрит флаг и, если он стоит, заносит в соответствующий регистр соответствующее значение, а если флаг сброшен, то заносит туда 0 - верно?

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

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

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

А насчет массивов ValuePower и FlagPower еще не успел переписать под структуру ConfigLamp которая находиться в ОЗУ.
В AtmelStudio вроде можно писать на с++,меня просто отговорили от использования синтаксиса плюсов в мк из за его реализации, если мк все-таки поддерживает парадигму ооп программирования то это все упрощает . можно создать класс и наполнить его методами(но я\ не уверен что МК AVR полноценно поддерживает с++.)
andrei23061996@gmail.com
.................................................................................................................
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

С++ поддерживает компилятор, а не МК.
avr-gcc поддерживает.

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

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

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

На самом деле с плюсами бы было работать проще и привычней . ) но даже не знаю какой стандарт поддерживает avr-gcc в atmelstudio ведь не так давно вышел очередной стандарт с++17 который пришелся сне с разу по душе в другом моем хобби.
А по этой прошивке походу надо с начало адаптировать код к структуре и повыкидывать лишнее.
andrei23061996@gmail.com
.................................................................................................................
Ответить

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