|
|
  |
MSP430 - снова вопросы от чайника, Вопросы от чайника про MSP и магнитный компас |
|
|
|
Aug 21 2008, 21:19
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Daria @ Aug 22 2008, 00:01)  для чего делается вот это #pragma pack(2) ... #pragma pack() Как я понимаю, это выравнивание? Да, это выравнивание структуры. Цитата(Daria @ Aug 22 2008, 00:01)  т.е. #pragma pack(2) - теперь структура будет иметь четное количество байтов, Нет, не "иметь четное количество байт", а члены структуры будут выровнены на границу 2-х байтового слова. Цитата(Daria @ Aug 22 2008, 00:01)  а #pragma pack() - возвращение к установке "по умолчанию"? Да. Цитата(Daria @ Aug 22 2008, 00:01)  А зачем тогда именно pack(2)? Потому, что MSP430 16-и разрядный микроконтроллер и доступ к переменным структуры по невыровненному на границу 16-и битного слова указателю может привести к очень неприятным ошибкам. Цитата(Daria @ Aug 22 2008, 00:01)  Если написать pack(1) - то будет ровно то количество байт, которое задается, т.е. четыре. Общее количество байт занимаемое данной конкретной (упоминаемой ранее) структурой будет то же самое, т.к. она уже сама по себе выровнена за счет подбора порядка следования переменных внутри структуры. Но на архитектуре большей разрядности, при другом размере выравнивания размер структуры может увеличиться. Цитата(Daria @ Aug 22 2008, 00:01)  ? Объясните чуть подробнее, пожалуйста.  Объясняю. Имеем вот такую структуру, выровненную на размер 1 байта Код #pragma pack(1) typedef struct qqq_t { char a; int b; long c; char d; } qqq_t; #pragma pack(1)
qqq_t QQQ;
qqq_t *pQ=&QQQ; Допустим, что компилятор расположил структуру, начиная с адреса 0x0200, выровняв ее на границу байта. Тогда структура займет в памяти 8 байт. QQQ.a расположена по адресу 0x0200 - нормально, 1 байт QQQ.b расположена по адресу 0x0201 - внимание! слово по нечетному адресу!!!, 2 байта QQQ.c расположена по адресу 0x0203 - опять внимание!!!, 4 байта QQQ.d расположена по адресу 0x0207 - допустимо, т.к. переменная 1-но байтовая, 1 байт Теперь, если мы захотим изменить значение, например, элемента b, то в указатель будет загружен ее адрес 0x0201. Код pQ->b += 1; И мы получим полный облом - обращение к 16-и битному слову по нечетному адресу!!! Но поскольку архитектура MSP430 такого не позволяет, то этим оператором будет считано значение слова по четному адресу (0x0200, вместо 0x0201) и увеличенное на единицу значение будет записано по этому же адресу (0x0200). В результате изменится не только значение переменной под именем b, но и значение переменной a тоже. Если же мы предусмотрительно сделаем выравнивание на границу 16-и разрядного слова, то структура расположится в памяти, заняв правда уже 9 байт, так. QQQ.a по адресу 0x0200 - нормально, 1 байт неиспользуемый 1 байт по адресу 0x0201 QQQ.b по адресу 0x0202 - нормально, 2 байт QQQ.c по адресу 0x0204 - нормально, 4 байт QQQ.d по адресу 0x0208 - нормально, 1 байт Но зато при этом выравнивании не будет никаких проблем при обращении с помощью указателя к любому члену структуры, т.к. все адреса членов структур четные и выравнены на границу 16-и разрядного слова. В случаях когда мы сами себе хозяева, а состав структуры данных нам не "спущен сверху", то можно перетасовать элементы структуры так, чтобы они располагались в памяти более оптимально, без "дырок", образующихся при выравнивании. Лучше располагать их в порядке убывания размеров переменных. Например. Код #pragma pack(2) typedef struct qqq_t { long c; int b; char a; char d; } qqq_t; #pragma pack() Еще момент. Вроде бы тут структура уже самоупорядочилась и выравнивание вроде не требуется. Но это только для того случая, когда структура сама по себе единица данных. Если же мы попробуем включить эту структуру в состав другой ( невыравненной) структуры, то можем получить снова такую же ситуацию, которая описана чуть выше. Так что я за то, чтобы структуры всегда были выровнены. Причем если используется 32-х битная архитектура, то выравнивать лучше на границу 32-х битного слова (на 4 байта). Вообще говоря, стандартом Си гарантируется только порядок следования членов структуры, а насчет занимаемого в памяти размера структуры стандарт ничего не говорит. Это отдается на откуп программисту и компилятору. Поэтому при переносе структур данных на архитектуры разной разрядности нужно быть очень внимательным. Цитата(Daria @ Aug 22 2008, 00:01)  И еще - почему именно buf[10], чем обусловлено 10 и как его выбирать?  А данном случае 10 это абстрактное число взятое мной "с потолка"  Размер буфера выбирается, исходя из максимального размера пакета или, исходя из времени определяемого неравномерностью доступа к буферу. Первый случай рассматривать по-моему не стоит. Размер буфера д.б. не меньше, чем максимальный размера принимаемого пакета. Это для случая когда требуется принять весь пакет целиком и только потом начать его разбор. Второй случай. Допустим, нам хочется организовать непрерывный поток данных через UART и для этого мы хотим использовать буфер аля FIFO - линейный буфер по принципу "первый вошел-первый вышел". Пускай отправка 1 символа UART занимает условно 10мс. А темп поступления данных на конвейер UART определяется какими-либо внешними событиями, распределенными по времени неравномерно от 0,2 мс до 20мс. Какого размера буфер требуется? Исходя из самого худшего предположения, за время отправки 1 символа (10мс) мы можем получить до 50 символов с периодом 0,2мс. Значит размер буфера должен быть (10-0,2)/0,2>=49 элементов. Конечно, это для случая нормального (гауссового) распределения задержек в указанном диапазоне. В противном случае нам может не хватить даже буфера из 1000 элементов, если на каком-то весьма продолжительном отрезке времени данные будет поступать с высоким темпом (с минимальной задержкой). Цитата(Daria @ Aug 22 2008, 00:01)  И вообще мне не понятно, при таком протоколе, а это вроде довольно распространенный: *, данные, #- как быть при приеме? Вот цифровое значение # - 35, а если приходит такое число? Вот азимут у меня, допустим, 35 - тогда же путаница получится? Вот у меня такой флажок 0хFF - уникален, учитывая, что передаю по 6 бит  А как обычно делают? Обычно символы начала (и конца) пакета являются уникальными. При этом либо весь пакет как-то обрабатывается (кодируется) так, чтобы не допустить символ с кодом начала (конца) пакета, либо совпадающие по коду символы дублируются, либо заменяются на последовательность уникальных символов. Посмотрите, например, описание протокола Wake, там эта проблема решена вполне изящно.
|
|
|
|
|
Aug 29 2008, 18:53
|
Местный
  
Группа: Участник
Сообщений: 229
Регистрация: 24-02-08
Пользователь №: 35 345

|
Здравствуйте снова. Вот опять вопросы_ Делаю усреднение по по тридцать отсчетов Код int filter1(int input[], int in) { float result = 0; int i; if (in>0) { for (i = 0; i < 30; i++) result += input[i]; result=result/in; for (i = 0; i < 30; i++) input[i] = input[i+1];
return (int)(result); } } Потом в прерывании АЦП Код if((index>=29)|(f==1))//если уже набрался массив из 30 элементов для усреднения { f=1; Vr[0][29]= ADC12MEM3; Vr[1][29] = ADC12MEM4; ADC12CTL0 &= ~ENC; buf[0] = filter1(Vr[0], 30); //фильтр buf[1] = filter1(Vr[1], 30); offset[0] = (Vs[0] -buf[0])/2; // вычисляются смещения на основе Vset, Vreset offset[1] = (Vs[1] - buf[1])/2; Vx = buf[0] - offset[0]; //координаты вектора маг. индукции Vy = buf[1] - offset[1]; index=0; float F[2]; azimut = calculation (Vx,Vy,F); send_int(azimut); } if ((index<29)&(f==0))// пока массив не набрался { Vr[0][index]= ADC12MEM3; Vr[1][index] = ADC12MEM4; index++; ADC12CTL0 &= ~ENC; } Массив Vr[2][30] глобальный. Преобразование АЦП разрешается в прерываниях от таймера, которые происходят через 5мс. флаг f становится равным единице, когда уже набрался массив, индекс потом обнуляется, чтобы не возрастал постоянно до максимального значения, а флаг остается. Кривовато? Дело в том, что почему-то для 30 отсчетов работает, для 35 - тоже, а для 40 - уже нет, передача данных не идет. Хотя в отладчике все вроде происходит нормально, хоть до ста отсчетов давай. И все-таки по поводу буфера,rezident. Выравнивание #pragma pack(2) почему-то дает какой-то жуткий эффект - данные перепутываются и вообще не идут. А если по одному байту выравнивать, то нормально...но и данные ведь по одному байту пишутся. И вообще-то, зачем делать счетчик буфера int? Буфер же однобайтовый... Поясните еще, я все же видимо, непонятливая
|
|
|
|
|
Aug 29 2008, 20:16
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Daria @ Aug 30 2008, 00:53)  Делаю усреднение по по тридцать отсчетов Что-то не совсем понятно, что за сдвиг вы формируете при усреднении? Вы пытаетесь фильтровать скользящим средним что ли? Или просто накапливаете 30 значений, а потом среднее арифметическое берете? Тогда зачем сдвиг элементов буфера? Цитата(Daria @ Aug 30 2008, 00:53)  Потом в прерывании АЦП Вычисления и фильтрация в прерывании???  Эх, Дарья, ничево вы видимо не поняли Цитата(Daria @ Aug 30 2008, 00:53)  if((index>=29)|(f==1))//если уже набрался массив из 30 элементов для усреднения Сразу же ошибка. Оператор | это "побитовое ИЛИ". Более уместное в логическом выражении "логическое ИЛИ" записывается как ||. Цитата(Daria @ Aug 30 2008, 00:53)  ... Поскипано. Мне грустно видеть как жуткие вычисления с плавучкой в прерывании транжирят драгоценное время Цитата(Daria @ Aug 30 2008, 00:53)  if ((index<29)&(f==0))// пока массив не набрался Опять аналогичная ошибка. "Логическое И" записывается как &&. Одиночный амперсанд & это "побитовое И". Цитата(Daria @ Aug 30 2008, 00:53)  Кривовато? Не то слово! Цитата(Daria @ Aug 30 2008, 00:53)  Дело в том, что почему-то для 30 отсчетов работает, для 35 - тоже, а для 40 - уже нет, передача данных не идет. Хотя в отладчике все вроде происходит нормально, хоть до ста отсчетов давай. А вы в отладчике посмотрите сколько циклов занимает ваш расчет и фильтрация  Поделите на тактовую MCLK и выясните, как оно соотносится с 5мс таймерными прерываниями? Ведь пока вы в прерывании АЦП считаете, все остальные прерывания запрещены. Цитата(Daria @ Aug 30 2008, 00:53)  И все-таки по поводу буфера,rezident. Выравнивание #pragma pack(2) почему-то дает какой-то жуткий эффект - данные перепутываются и вообще не идут. А если по одному байту выравнивать, то нормально...но и данные ведь по одному байту пишутся. Что перепутывается? Кто куда не идет? Про какой именно буфер речь? Если про буфер UART, то что там не так с выравниванием? Вынесите сам буфер (массив) типа unsigned char наружу структуры, как самостоятельный глобальный массив переменных. Его-то выравнивать не нужно. А в структуре только указатель на начало этого массива оставьте. Цитата(Daria @ Aug 30 2008, 00:53)  И вообще-то, зачем делать счетчик буфера int? Буфер же однобайтовый...  Потому, что в Си тип int является машинно-ориентированно-оптимальным. Поскольку MSP430 16-и разрядный микроконтроллер, то 16-и битовое слово является для него оптимальным. А, например, на ARM тип int 32-х битный. Нет, вы конечно же можете имеете право и unsigned char для счетчика использовать, если стоит задача экономии ОЗУ. У MSP430 есть команды для работы с байтовыми операндами. Я же совершенно не против
|
|
|
|
|
Aug 30 2008, 18:33
|
Местный
  
Группа: Участник
Сообщений: 229
Регистрация: 24-02-08
Пользователь №: 35 345

|
Да знаю я, знаю, что долго сидеть в прерывании нехорошо, не ругайтесь так...  Но тут какая проблема была - если вычисления делать просто в цикле for(;;), то за время, пока эти вычисления делаются, уже успевает прийти несколько прерываний, и данные обновляются прямо по ходу вычислений. И происходит такая вещь - если плавно поворачивать плату, то оцифрованый уровень меняется далеко не плавно, жутко скачет во время поворота и долго "успокаивается", если вращать быстро, то будет долгий переходной процесс - т.е. улетает сначала намного выше реального уровня, затем медленно возвращается. Вот, по-женски так объясняю, самой смешно  я думаю, это происходит оттого, что допустим координата Х уже просчиталась, а У еще нет, пришло прерывание, данные обновились, У считается, и уже характеризует новое положение, а Х - еще старое, поэтому при вращении возникают большие ошибки. Такое дело нежелательно, потому что компас может медленно вращаться во время использования, или сразу после остановки может быть обращение к нему. Я перенесла вычисления прямо в прерывание, и все стало меняться просто на заглядение плавно  Кстати, на ваш вопрос - да, усредняю скользящим, среднее арифметическое - это глупо даже для меня  Каждый раз дожидаться, пока наберется 30 отсчетов... Я жду, пока они наберутся только в самом начале работы, а потом каждое новое число записывается 30-м элементом массива, и массив усредняется и сдвигается. Ну да, зато теперь тратится куча времени... А, если все же не в прерывании считать, то как бы избавится от той проблемы, о которой я говорю? если, конечно, вы меня поняли  у меня в последнее время с объяснением не лады
|
|
|
|
|
Aug 30 2008, 21:04
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Daria @ Aug 31 2008, 00:33)  Да знаю я, знаю, что долго сидеть в прерывании нехорошо, не ругайтесь так...  Но тут какая проблема была - если вычисления делать просто в цикле for(;;), то за время, пока эти вычисления делаются, уже успевает прийти несколько прерываний, и данные обновляются прямо по ходу вычислений. Есть два способа решения этой проблемы. Либо на время вычислений в основном цикле запрещать прерывания от АЦП (либо останавливать его) - все равно АЦП не работает, когда вы считаете в прерывании. Либо использовать два циклических буфера. В то время пока вы обсчитываете результаты одного буфера, в другой буфер (по прерываниям АЦП) идет запись новых результатов изменений. В основном цикле вы только устанавливаете номер буфера и флаг сигнализирующий обработчику прерывания АЦП о смене номера буфера. В прерывании АЦП сначала анализируется состояние флага и при необходимости изменяется указатель на буфер, а запись новых значений происходит уже в другой буфер. Цитата(Daria @ Aug 31 2008, 00:33)  И происходит такая вещь - если плавно поворачивать плату, то оцифрованый уровень меняется далеко не плавно, жутко скачет во время поворота и долго "успокаивается", если вращать быстро, то будет долгий переходной процесс - т.е. улетает сначала намного выше реального уровня, затем медленно возвращается. Вот, по-женски так объясняю, самой смешно  я думаю, это происходит оттого, что допустим координата Х уже просчиталась, а У еще нет, пришло прерывание, данные обновились, У считается, и уже характеризует новое положение, а Х - еще старое, поэтому при вращении возникают большие ошибки. Значит у вас где-то ошибка в алгоритме. нужно синхронизировать обновления значений переменных координат так, чтобы не было разбега, как он у вас описан. Цитата(Daria @ Aug 31 2008, 00:33)  Кстати, на ваш вопрос - да, усредняю скользящим, среднее арифметическое - это глупо даже для меня  Каждый раз дожидаться, пока наберется 30 отсчетов... Я жду, пока они наберутся только в самом начале работы, а потом каждое новое число записывается 30-м элементом массива, и массив усредняется и сдвигается. Ну да, зато теперь тратится куча времени...  А вам приниципально усреднять уже готовые значения координат или можно усреднять непосредственно отсчеты АЦП? Ведь просуммировать целые числа получается гораздо быстрее, чем получить сумму "плавучих" чисел? К тому же при целочисленных вычислениях не накапливается ошибка округления. Поэтому алгоритм скользящего вычисления среднего можно значительно ускорить. Для этого нужно лишь хранить отдельно текущее значение суммы элементов буфера. При поступлении нового значения в буфер достаточно вычесть из этой суммы значение самого древнего элемента буфера, прибавить значение нового элемента буфера и вуаля! - вы получаете готовую сумму. Итого одно сложение и одно вычитание, вместо суммирования всего буфера. Для "плавучки" такой способ не годиться, т.к. довольно быстро набегает ошибка вычисления суммы. К тому же зачем вы каждый раз при записи нового значения в буфер сдвигаете все элементы в буфере? Это же лишнее время и совершенно ненужное действие. Сдвигайте не сам буфер, а лишь индекс-указатель на текущий элемент буфера. Получается то же самый неоднократно упомянутый циклический буфер. Код #define MAXNUMFLTRBUF 30
unsigned int funcSMA(unsigned int val) { static unsigned int fltrBuf[MAXNUMFLTRBUF]; static unsigned int idx; static unsigned long sumBuf; sumBuf-=fltrBuf[idx]; //вычитаем из суммы значение самого старого элемента sumBuf+=val; //прибавляем к сумме значение нового элемента fltrBuf[idx]=val; //записываем в буфер значение нового элемента if (idx<(MAXNUMFLTRBUF-1))//сдвигаем индекс idx++; else idx=0; return(sumBuf/MAXNUMFLTRBUF);//высисляем среднее значение } При желании можно добавить команды управления фильтром. Например, команду очистки буфера или инициализация его определенным значением. Для того, чтобы увеличить начальную крутизну его переходной характеристики. Код #define MAXNUMFLTRBUF 30
unsigned int funcSMA(unsigned int cmd, unsigned int val) { static unsigned int fltrBuf[MAXNUMFLTRBUF]; static unsigned int idx; static unsigned long sumBuf; if (cmd==0) //это случано не команда инициализации фильтра? { sumBuf-=fltrBuf[idx]; //нет, вычитаем старое значение sumBuf+=val; //прибавляем к сумме значение нового элемента fltrBuf[idx]=val; //записываем в буфер значение нового элемента if (idx<(MAXNUMFLTRBUF-1))//сдвигаем индекс idx++; else idx=0; return(sumBuf/MAXNUMFLTRBUF);//вычисляем среднее значение } else //да, инициализируем буфер фильтра новым значением { sumBuf=val*MAXNUMFLTRBUF; idx=MAXNUMFLTRBUF-1; while (idx!=0) fltrBuf[idx--]=val; return(val); } } Учитывая, что входные значения 12-и разрядные и сумма заведомо не превышает разрядности типа long, то при целочисленном вычислении среднего можно повысить точность, если перед делением сдвигать сумму до заполнения разрядности типа, а потом сдвигать обратно. Код return(((sumBuf<<8UL)/MAXNUMFLTRBUF)>>8UL);
|
|
|
|
|
Aug 31 2008, 16:48
|
Местный
  
Группа: Участник
Сообщений: 229
Регистрация: 24-02-08
Пользователь №: 35 345

|
Цитата(rezident @ Aug 31 2008, 01:04)  Есть два способа решения этой проблемы. Либо на время вычислений в основном цикле запрещать прерывания от АЦП (либо останавливать его) - все равно АЦП не работает, когда вы считаете в прерывании. А разве не тож на тож получится?  Та же самая потеря времени... Единственное, что таймер не будет пробрасывать свои прерывания и будет четко вести счетчик прерываний... но лишние 10-20мс до начала короткого импульса - вроде не проблема... Цитата(rezident @ Aug 31 2008, 01:04)  Либо использовать два циклических буфера. В то время пока вы обсчитываете результаты одного буфера, в другой буфер (по прерываниям АЦП) идет запись новых результатов изменений. В основном цикле вы только устанавливаете номер буфера и флаг сигнализирующий обработчику прерывания АЦП о смене номера буфера. В прерывании АЦП сначала анализируется состояние флага и при необходимости изменяется указатель на буфер, а запись новых значений происходит уже в другой буфер. Ух. Жестко! Ладно, спасибо, попробую. Цитата(rezident @ Aug 31 2008, 01:04)  Значит у вас где-то ошибка в алгоритме. нужно синхронизировать обновления значений переменных координат так, чтобы не было разбега, как он у вас описан. Нужно. Вопрос - как Цитата(rezident @ Aug 31 2008, 01:04)  А вам приниципально усреднять уже готовые значения координат или можно усреднять непосредственно отсчеты АЦП? Э-э... а я вроде именно отсчеты АЦП и усредняю...  так мне казалось... Цитата(rezident @ Aug 31 2008, 01:04)  Для этого нужно лишь хранить отдельно текущее значение суммы элементов буфера. При поступлении нового значения в буфер достаточно вычесть из этой суммы значение самого древнего элемента буфера, прибавить значение нового элемента буфера и вуаля! - вы получаете готовую сумму. Точно! Спасибо большое! Действительно, куча лишних действий получалась! Только немного не ясно, почему строка sumBuf-=fltrBuf[idx];- это вычитание самого старого элемента  Вы записываете новый элемент fltrBuf[idx]=val; и сдвигаете счетчик - idx++. Значит, при поступлении следующего элемента fltrBuf[idx] будет хранить значение предыдущего, а не самого старого... Поясните, пожалуйста. Цитата(rezident @ Aug 31 2008, 01:04)  Учитывая, что входные значения 12-и разрядные и сумма заведомо не превышает разрядности типа long, то при целочисленном вычислении среднего можно повысить точность, если перед делением сдвигать сумму до заполнения разрядности типа, а потом сдвигать обратно. Код return(((sumBuf<<8UL)/MAXNUMFLTRBUF)>>8UL); А почему это повышает точность? как всегда спасибо за комментарии!
|
|
|
|
|
Aug 31 2008, 18:39
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Daria @ Aug 31 2008, 22:48)  Нужно. Вопрос - как  Как обычно. С помощью буферов. Две переменные которые будут обновляться одновременно и считывание значений из которых не будет прерываться вычислениями. Цитата(Daria @ Aug 31 2008, 22:48)  Э-э... а я вроде именно отсчеты АЦП и усредняю...  так мне казалось...  Опс! Это я ошибся  Извиняюсь! Почему-то отложилось в памяти, что у вас там фильтрация плавающих числе идет, а страницу с вашим кодом еще раз посмотреть поленился. Цитата(Daria @ Aug 31 2008, 22:48)  Только немного не ясно, почему строка sumBuf-=fltrBuf[idx];- это вычитание самого старого элемента  Вы записываете новый элемент fltrBuf[idx]=val; и сдвигаете счетчик - idx++. Значит, при поступлении следующего элемента fltrBuf[idx] будет хранить значение предыдущего, а не самого старого... Поясните, пожалуйста. В полностью заполненном циклическом буфере фильтра индекс указывает на тот элемент, куда нужно записать новое значение, которое замещает самое старое значение. Следовательно индекс указывает на самое старое значение. Пример. Буфер из трех элементов. Поток состоит из последовательности натуральных чисел. Код | значения значение | элементов индекса | буфера --------------------------- 0 -, -, - - буфер пуст 1 1, -, - - 1 элемент, единственный и самый старый, индекс указывает на следующий, но буфер ЕЩЕ НЕ ЗАПОЛНЕН 2 1, 2, - - 2 элемента, самый старый 1-й, буфер ЕЩЕ НЕ ЗАПОЛНЕН, индекс указывает на следующий 0 1, 2, 3 - 3 элемента, буфер заполнен!!!, индекс указывает на следующий (1-й элемент), который является самым старым 1 4, 2, 3 - 3 элемента, буфер заполнен, индекс указывает на следующий (2-й элемент). который является самым старым 2 4, 5, 3 - 3 элемента, буфер заполнен, индекс указывает на следующий (3-й элемент). который является самым старым 0 4, 5, 6 - ну и т.д. 1 7, 5, 6 Цитата(Daria @ Aug 31 2008, 22:48)  А почему это повышает точность? Это особенности целочисленной математики. Хотя пожалуй в данном конкретном случае (единственная операция в выражении) это рояли не играет. Я просто перестраховался. Отставить сдвиги!
|
|
|
|
|
Aug 31 2008, 20:29
|
Местный
  
Группа: Участник
Сообщений: 229
Регистрация: 24-02-08
Пользователь №: 35 345

|
Цитата(rezident @ Aug 31 2008, 22:39)  В полностью заполненном циклическом буфере фильтра индекс указывает на тот элемент, куда нужно записать новое значение, которое замещает самое старое значение. Ага, ясно. Спасибо за очень подробное разъяснение Цитата(rezident @ Aug 31 2008, 22:39)  Это особенности целочисленной математики. Хотя пожалуй в данном конкретном случае (единственная операция в выражении) это рояли не играет. Я просто перестраховался. Отставить сдвиги!  Есть "отставить сдвиги" Я теперь неделю буду в отпуске  так что можете от меня недельку отдохнуть а через неделю жду вас с новыми ответами на новые вопросы
|
|
|
|
|
Sep 12 2008, 18:04
|
Местный
  
Группа: Участник
Сообщений: 229
Регистрация: 24-02-08
Пользователь №: 35 345

|
Ну вот, отпуск кончился, пошли суровые будни И вопросы Такая беда. У меня был iar, версия 4.11в - тридцатидневная демо-версия с официального сайта. Срок лицензии истек, я снесла эту версию, скачала опять и поставила снова. И вот фиг. Удаляю отовсюду, откуда только можно, но в реестр он прописался в закрытую область, которую нельзя удалить. Теперь сколько новый iar не ставь, все бестолку Как быть? переустанавливать винду не хочется. Попробовать какую-нибудь другую версию? Где взять? У меня был ломаный iar 3.2, но он почему-то жутко глючил. Можно как-нибудь почистить и закрытые области? Вот такая проблема, немного не по теме, но печальная
|
|
|
|
|
Sep 13 2008, 17:31
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(rezident @ Sep 13 2008, 20:48)  А вы сами-то при передаче заказчику исходников своей программы строго следуете условиям лицензии GPL?  Заказчику мы обычно передаём только паспорт и РЭ, в крайнем случае схему. А вообще, как говорил кот Матроскин, холодильник чей - государственный, а холод, который он вырабатывает - наш. Так же и тут. Компилятор - GPL, а код, который он вырабатывает - наш.
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
  |
4 чел. читают эту тему (гостей: 4, скрытых пользователей: 0)
Пользователей: 0
|
|
|