Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Кстати, возможно, есть смысл хранить не весь массив, а только пару-тройку коэффициентов.

Если зависимость линейная - то R = a1 * T + a0.

Нелинейная зависимость, возможно, достаточно хорошо будет аппроксимироваться параболой R = a2 * T * T + a1 * T + a0.

Просто нужно сделать пару-тройку замеров в разных точках, и решить систему, найдя эти коэффициенты. Их в EEPROM и хранить.
Контактная информация:
Реклама
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница

Сообщение urry »

от себя добавлю, что вероятность повреждения данных в епром очень высокая - нужно данные дублировать и закрывать контрольной суммой.
Контактная информация:
Реклама
Опытный кот
Аватара пользователя
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США

Сообщение Pink-Pank »

Это уж сверхмера. Думаю, вопрошающему в его применении такие усложнения ни к чему. )) Хотя, ради тренеровки можно было бы замутить. ;)
Fucking static initialization order fiasco
Контактная информация:
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

ibiza11 писал(а):
kelod писал(а):это храню массивом... задаю его самостоятельно, при создании массива
Приведите код, который вы пишете для этого. Я вам покажу, где там размер массива.

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

uint32_t EEPROM mass[]={177, 192,240};
значений намного больше, около 15
WiseLord писал(а):Кстати, возможно, есть смысл хранить не весь массив, а только пару-тройку коэффициентов.
зависимость не линейная и не квадратичная, скорее похожа на логарифм, интерполирование или слишком сложное или не удовлетворяет точности, поэтому после долгих размышлений принял решение о линейной интерполяции относительно двух ближайших точек
urry писал(а):вероятность повреждения данных в епром очень высокая
перезапись будет происходить очень редко, только при смене датчика
Реклама
Эиком - электронные компоненты и радиодетали
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

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

uint32_t EEPROM mass[]={177, 192,240};
#define MASS_SIZE (sizeof(mass)/sizeof(uint32_t))
uint32_t massSize = MASS_SIZE;
Ставим плюсы: )
Реклама
aam
Собутыльник Кота
Аватара пользователя
Сообщения: 2994
Зарегистрирован: Сб фев 20, 2010 14:00:12
Откуда: Москва

Сообщение aam »

Всем спасибо, все получилось. Сделал так:

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

#define STR(s) #s
#define TO_STR(s) STR(s)

char __flash start0[]="MDIOv1.0 LD" TO_STR(LD_NUM)
***
kelod писал(а):но я думал можно узнать количество элементов, как это есть в обычном си
В обычном си вы тоже не создадите просто так массив произвольной длины. Размер массива в си определяется на этапе компиляции.

В вашем случае размер лучше хранить не в 1-й ячейке ЕЕПРОМ (легко забыть поменять размер), а ввести завершающий символ, который не встречается в реальных данных (например, 0 или 0xFF). И просто просматривать всю таблицу, пока не наткнетесь на этот символ. Если опасаетесь за быстродействие, просматривайте таблицу 1 раз при включении питания и запоминайте в ОЗУ ее размер в переменной.
urry писал(а):от себя добавлю, что вероятность повреждения данных в епром очень высокая
Почему?
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

urry писал(а):от себя добавлю, что вероятность повреждения данных в епром очень высокая - нужно данные дублировать и закрывать контрольной суммой.
Могу сказать, что если данные записываются/читаются не очень интенсивно, то с надежностью все хорошо (а на них никто и не будет писать интенсивно, циклов перезаписи же мало). У нас много лет используется по несколько EEPROM в составе частотного инвертора (условия не лучшие), за все время был только один зарегистрированный косяк.
aam
Собутыльник Кота
Аватара пользователя
Сообщения: 2994
Зарегистрирован: Сб фев 20, 2010 14:00:12
Откуда: Москва

Сообщение aam »

Скажите, а можно ли использовать return; в прерываниях?
Ато тут у меня какая-то фигня получается в нештатных ситуациях. Использую библиотеку протокола wake, так если слишком часто слать запросы от компа, то МК виснит и бесконца вызывает прерывание по поступлению данных в приемник УАРТ. Причем не отвисает когда уже я слать данные перестал. Сторожевой таймер тоже не оживляет МК - без конца вызывается прерывание, хотя я смотрел - флаг того, что UDR полон - уже сброшен.
menzoda писал(а):если данные записываются/читаются не очень интенсивно, то с надежностью все хорошо (а на них никто и не будет писать интенсивно, циклов перезаписи же мало)
А я тут девайс с пультом от телека сделал, особых мер, кроме проверки на допустимость значения, не принимал. Вот теперь думаю, а это правильно?
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

aam писал(а):Скажите, а можно ли использовать return; в прерываниях?
Ато тут у меня какая-то фигня получается в нештатных ситуациях. Использую библиотеку протокола wake, так если слишком часто слать запросы от компа, то МК виснит и бесконца вызывает прерывание по поступлению данных в приемник УАРТ. Причем не отвисает когда уже я слать данные перестал.
а каким боком return может быть связан с вашей бедой?! avr-gcc не нуждается в return в обработчике прерываний, но и при наличии ничего не ухудшается - плевать он хотел на return. на счет других компиляторов не скажу, не знаю.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

ARV писал(а):плевать он хотел на return
Наверное, корректнее сказать, что обработчик прерывания отработает return как и обычная void-фунция, коей он, по большому счёту, и является.
Контактная информация:
aam
Собутыльник Кота
Аватара пользователя
Сообщения: 2994
Зарегистрирован: Сб фев 20, 2010 14:00:12
Откуда: Москва

Сообщение aam »

С return понятно уже...
Непонятно другое. Вот щас завел сторожевой таймер. При этом глюке 1 раз срабатывает ватчдог, проц ресетится и начинает выполнять прогу. Но сразу после команды sei начинает беспорядочный вызов прерывания по приему данных, хотя данные УЖЕ не передаются (это видно на осциллографе и терминале Протеуса), бесконечно выскакивает сообщение
Reading from UDR1 while no data received.
При этом регистры имеют значения:
UBBR1H=0
UBBR1L=0x07
UCSR1A=0x20
UCSR1B=0xD8
UCSR1C=0x06
UDR1=0
Прерывание таймера 0, тактирующее прогу, при этом вызывается как и положено.

Не могу понять, это глюк Протеуса или косяк проги?
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

Здравствуйте, решил я сделать отладку по uart. Т.е расставить контрольные точки в программе и смотреть в терминале как они выполняются ). Естественно что в готовом варианте эта отладка не нужна и чтобы каждый раз не удалять сделал через

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

#if __DEBUG__
....
#endif  
Но в итоге получается не сильно удобный код. Можно ли его как-то ужать до 1 функции ?

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

#if __DEBUG__      
if(debug_ON_OFF==ON){ // вкл/выкл по usart
    USART_SendStr("INIT:......\0"); 
}
#endif   
Пробовал внести #if __DEBUG__ #endif внутрь функции, но после выключения отладчика функция всё равно остаётся хоть она и пустая но это неприемлемо.
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

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

#if __DEBUG__ 
   debug_send_str("INIT:...");
#endif 

//...

void debug_send_str(char * str){
   if(debug_ON_OFF==ON){ // вкл/выкл по usart
      USART_SendStr(str);
   }
}
так?) чего вы добиться то хотите?
Ставим плюсы: )
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

Не так. Вот так:

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

extern void UartSend(const char *msg);

...

#ifdef __DEBUG
    #define Trace(x)    UartSend(x)
#else
    #define Trace(x)
#endif

...

void main(void)
{
    Trace("Hello");
    Trace("World");
}
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

menzoda, во то что надо. А если UartSend(x) с переменным числом параметров ? Типа функции printf();

чего вы добиться то хотите?
Что бы можно было писать так.

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

DEBUG("ERROR1");
DEBUG("ERROR1",var1);
DEBUG("ERROR2",var2,var3);
DEBUG("ERROR3",var4,var5,var6);
А в готовом варианте что бы можно было убрать/вернуть с минимальными трудозатратами =)
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 175
Зарегистрирован: Пт июн 29, 2012 23:48:11

Сообщение virus33 »

Вопрос тупенький, но все же.
есть два камня которые должны общатся по uart. изначально была следующая мысль - шлем 1 байт на скорости 9600 ввиде 0b0000xxxx, где хххх - состояние уровней на входах RB4-RB7, остальные биты пока не используются.
Создал массив типа short int, по таймеру (1 секунда) в нужные ячейки записывал состояние уровней, сформированный байт отправил в путешествие. По приходу данного байта через сдвиговый регистр хотел так же развалить в подобный массив, чтобы
обработать полученную информацию. Но к сожалению ничего не получилось, компилятор(HI-Tech) выдал следующие предупреждения:
Warning [360] C:\Users\Enter\Documents\pic\sender\main.c; 90.8 array index out of bounds
Warning [358] C:\Users\Enter\Documents\pic\sender\main.c; 111.17 illegal conversion of pointer to integer
банально не знаю как сформировать байт из массива. Подскажите кто знает, заранее благодарен.
Опытный кот
Аватара пользователя
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США

Сообщение Pink-Pank »

Судя по ругательствам компилятора, Вы запихиваете в массив больше переменных, чем его размер. И пытаетесь указатель (адрес) преобразовать в целое. Чтобы это сделать, нужно указатель разыменовать (т.е. получить значение по его адресу операцией *)
Fucking static initialization order fiasco
Контактная информация:
Встал на лапы
Сообщения: 145
Зарегистрирован: Ср фев 01, 2012 10:55:53

Сообщение BorisSPB »

virus33, сколько элементов в массиве? Не следует забывать что в PIC память распределена по банкам и индексный регистр 8 бит, так что ругается на ограничение непрерывного пространства в банке или индекс больше 255.
У HI-TECH short int 16 бит, так что размер массива таких элементов может быть не больше 32.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

pokk писал(а):Что бы можно было писать так.

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

DEBUG("ERROR1");
DEBUG("ERROR1",var1);
DEBUG("ERROR2",var2,var3);
DEBUG("ERROR3",var4,var5,var6);
А в готовом варианте что бы можно было убрать/вернуть с минимальными трудозатратами =)
GCC поддерживает макросы с переменным числом параметров:
#define debug(format, ...) fprintf (stderr, format, __VA_ARGS__)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 175
Зарегистрирован: Пт июн 29, 2012 23:48:11

Сообщение virus33 »

код убогий, но как то так.

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

unsigned short int array[8];
///////////////////////////////////////////////////////////////////////////////////
void send_Usart(unsigned char e) //	Отправка байта
{
	while(TXIF!=1)	//	Устанавливается, когда регистр свободен
	{}
	TXREG = e;	
}

unsigned char getch_Usart(void)//	Получение байта
{
	while(!RCIF)	//	Устанавливается, когда регистр не пуст.
		continue;
	return RCREG;
}


void interrupt send_data(void)
{
if (T0IF == 1)
	{
	RA2 = ~RA2;
	array[0]=0;
	array[1]=0;
	array[2]=0;
	array[3]=0;
	array[4]=0;
	array[5]=0;
	array[6]=0;
	array[7]=0;
		if (com_0==1)
		{
		array[0]=1;
		} 
	
		if (com_1==1)
		{
		array[1]=1;
		} 
	
		if (com_2==1)
		{
		array[2]=1;
		} 
	
		if (com_3==1)
		{
		array[3]=1;
		} 
	
	send_Usart(*array);
	TMR0 = 1;
	T0IF = 0;					
	}

//	if (TMR2IF == 1)										//таймер 2 - говорим что соединение присутствует
//	{
//	RA2 = ~RA2;			
//	send_Usart(0b00000001);
//	TMR2 = 1;
//	T2CKPS0 = 0; T2CKPS1 = 1; 								//делим тактовую частоту на 4
//	TOUTPS0 = 0; TOUTPS1 = 0; TOUTPS2 = 1; TOUTPS3 = 0; 	//выходной делитель на 5
//	TMR2IF = 0;												// сброс флага
//	}

}
но в протеусе не вижу изменений при подаче уровней на входы мк
вот кстати вопрос, терминал показывает только определенные символьные коды, осцилограф как то странно отображает передачу по uart, есть ли еще способы посмотреть что на выходе имеется?
Последний раз редактировалось virus33 Чт июл 03, 2014 17:30:43, всего редактировалось 1 раз.
Ответить

Вернуться в «Разные вопросы по МК»