WiseLord писал(а):Кстати, возможно, есть смысл хранить не весь массив, а только пару-тройку коэффициентов.
зависимость не линейная и не квадратичная, скорее похожа на логарифм, интерполирование или слишком сложное или не удовлетворяет точности, поэтому после долгих размышлений принял решение о линейной интерполяции относительно двух ближайших точек
urry писал(а):вероятность повреждения данных в епром очень высокая
перезапись будет происходить очень редко, только при смене датчика
kelod писал(а):но я думал можно узнать количество элементов, как это есть в обычном си
В обычном си вы тоже не создадите просто так массив произвольной длины. Размер массива в си определяется на этапе компиляции.
В вашем случае размер лучше хранить не в 1-й ячейке ЕЕПРОМ (легко забыть поменять размер), а ввести завершающий символ, который не встречается в реальных данных (например, 0 или 0xFF). И просто просматривать всю таблицу, пока не наткнетесь на этот символ. Если опасаетесь за быстродействие, просматривайте таблицу 1 раз при включении питания и запоминайте в ОЗУ ее размер в переменной.
urry писал(а):от себя добавлю, что вероятность повреждения данных в епром очень высокая
urry писал(а):от себя добавлю, что вероятность повреждения данных в епром очень высокая - нужно данные дублировать и закрывать контрольной суммой.
Могу сказать, что если данные записываются/читаются не очень интенсивно, то с надежностью все хорошо (а на них никто и не будет писать интенсивно, циклов перезаписи же мало). У нас много лет используется по несколько EEPROM в составе частотного инвертора (условия не лучшие), за все время был только один зарегистрированный косяк.
Скажите, а можно ли использовать return; в прерываниях?
Ато тут у меня какая-то фигня получается в нештатных ситуациях. Использую библиотеку протокола wake, так если слишком часто слать запросы от компа, то МК виснит и бесконца вызывает прерывание по поступлению данных в приемник УАРТ. Причем не отвисает когда уже я слать данные перестал. Сторожевой таймер тоже не оживляет МК - без конца вызывается прерывание, хотя я смотрел - флаг того, что UDR полон - уже сброшен.
menzoda писал(а):если данные записываются/читаются не очень интенсивно, то с надежностью все хорошо (а на них никто и не будет писать интенсивно, циклов перезаписи же мало)
А я тут девайс с пультом от телека сделал, особых мер, кроме проверки на допустимость значения, не принимал. Вот теперь думаю, а это правильно?
aam писал(а):Скажите, а можно ли использовать return; в прерываниях?
Ато тут у меня какая-то фигня получается в нештатных ситуациях. Использую библиотеку протокола wake, так если слишком часто слать запросы от компа, то МК виснит и бесконца вызывает прерывание по поступлению данных в приемник УАРТ. Причем не отвисает когда уже я слать данные перестал.
а каким боком return может быть связан с вашей бедой?! avr-gcc не нуждается в return в обработчике прерываний, но и при наличии ничего не ухудшается - плевать он хотел на return. на счет других компиляторов не скажу, не знаю.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
С return понятно уже...
Непонятно другое. Вот щас завел сторожевой таймер. При этом глюке 1 раз срабатывает ватчдог, проц ресетится и начинает выполнять прогу. Но сразу после команды sei начинает беспорядочный вызов прерывания по приему данных, хотя данные УЖЕ не передаются (это видно на осциллографе и терминале Протеуса), бесконечно выскакивает сообщение
Reading from UDR1 while no data received.
При этом регистры имеют значения:
UBBR1H=0
UBBR1L=0x07
UCSR1A=0x20
UCSR1B=0xD8
UCSR1C=0x06
UDR1=0
Прерывание таймера 0, тактирующее прогу, при этом вызывается как и положено.
Не могу понять, это глюк Протеуса или косяк проги?
Здравствуйте, решил я сделать отладку по uart. Т.е расставить контрольные точки в программе и смотреть в терминале как они выполняются ). Естественно что в готовом варианте эта отладка не нужна и чтобы каждый раз не удалять сделал через
Вопрос тупенький, но все же.
есть два камня которые должны общатся по 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
банально не знаю как сформировать байт из массива. Подскажите кто знает, заранее благодарен.
Судя по ругательствам компилятора, Вы запихиваете в массив больше переменных, чем его размер. И пытаетесь указатель (адрес) преобразовать в целое. Чтобы это сделать, нужно указатель разыменовать (т.е. получить значение по его адресу операцией *)
virus33, сколько элементов в массиве? Не следует забывать что в PIC память распределена по банкам и индексный регистр 8 бит, так что ругается на ограничение непрерывного пространства в банке или индекс больше 255.
У HI-TECH short int 16 бит, так что размер массива таких элементов может быть не больше 32.
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 раз.