![](https://electronix.ru/forum/uploads/set_resources_23/84c1e40ea0e759e3f1505eb1788ddf3c_pattern.png)
![](https://electronix.ru/forum/uploads/set_resources_23/84c1e40ea0e759e3f1505eb1788ddf3c_default_photo.png)
jcxz
Свой-
Постов
13 618 -
Зарегистрирован
-
Посещение
-
Победитель дней
38
Весь контент jcxz
-
Быстрое деление в AVR - Как?
jcxz ответил MPetrovich тема в AVR
Какие "12 тыс. отображений"? Какие "10 минут"? Вы о чём??? Нужно отображать обороты. С указанной дискретностью и указанной реалтаймовостью. Хоть 12 тыс., хоть 12 миллионов раз. Попробуйте ещё раз перечитать и попытаться понять написанное. А потом: всё-таки - ответить на поставленный вопрос. -
Это всегда было так: Хочешь получить гарантированно работающий код? Решение: Напиши его сам. Во все времена так было, а не только с современными. А ещё есть поговорка: "Дарёному коню в зубы не смотрят".
-
Быстрое деление в AVR - Как?
jcxz ответил MPetrovich тема в AVR
Предположим: Обороты = не 1rpm, а пускай - около ~600 rpm. Нормально? Измерять нужно с точностью/дискретностью = ~0.1rpm. Датчик даёт = 1 импульс на оборот. Требуемая реалтаймовость индикации = не хуже 0.1сек (а лучше = от 0.1сек до 0.05сек). Как в этом случае "считать число импульсов за фиксированное время"? За какое время? 1 сек? 0.1сек? ...? Что будет на индикаторе при этом - представляете? -
Быстрое деление в AVR - Как?
jcxz ответил MPetrovich тема в AVR
Интересно - каким образом это сделать? Особенно при учёте того, что ТС вроде даже не рассказывал: какой датчик оборотов он использует и какие скорости вращения с какой точностью нужно измерять? Может его датчик даёт один импульс на оборот? Или используются датчики Холла (дискретные)? А скорость вращения не очень высокая. Может есть неравномерности вращения, вибрации, которые нужно сгладить фильтрацией? Предлагаете ему в обязательном порядке добавить в устройство какой-либо датчик точного углового положения с разрешением в доли градуса? -
С чего сделан вывод, что это "отладочные данные"? А не данные самой программы.
-
Быстрое деление в AVR - Как?
jcxz ответил MPetrovich тема в AVR
А какой смысл? Автор же написал, что не дружит с асмом. А си-компилятор сам умеет аналогичные функции для операции деления подставлять. Может даже более оптимальные. Только чтобы оценить степень оптимальности (какая лучше), опять же нужно дружить с асмом. Так что - тупик. Понятия "действие" в CPU нет. Есть такты, циклы, команды. И любая FPU-операция будет дольше, чем аналогичная целочисленная. PS: Кроме того - си-компилятор может заинлайнить какие-то операции или оптимизировать их, слепив с соседними. Поэтому (в общем случае) - результат его работы будет лучше, чем бездумное использование ассемблерных функций. Без понимания асма и умения их доработать под себя. -
Быстрое деление в AVR - Как?
jcxz ответил MPetrovich тема в AVR
На STM32 есть аппаратное деление (по крайней мере на тех, которые >=Cortex-M3), на многих DSP - нет. Так что в этом плане к AVR они ближе. Да и на тех STM32 тоже не факт, что "в одно действие". А всё сильно зависит от разрядности. О которой вы так ничего и не сказали. Тогда речь об "оптимизировать деление" вести бессмысленно. PS: Хочу написать супер-пупер роман. Объясните как. Да - с грамотой не дружу, алфавита не знаю.... -
Быстрое деление в AVR - Как?
jcxz ответил MPetrovich тема в AVR
Имхо - для индикации достаточно обновления ~10Гц. Ну пускай, для самых быстроглазых = 20Гц. Неужто ваш AVR не справится с делениями 20 раз в секунду? И про какую точность идёт речь? 16 бит? 32 бита? ... PS: При большой разрядности делителя, можно попробовать рядом Тейлора найти 1/x в несколько итераций, а затем - умножать. Но накладные расходы - большие, не факт что будет выигрыш. На DSP (без аппаратного деления, но с многоразрядными умножениями) это был вариант, на AVR - надо смотреть. Ведь у него и команды умножения дохлые. И вряд-ли есть другие альтернативы, кроме тупого деления в лоб (сдвигами/вычитаниями). Пускай и отимизированным на асме кодом. Иначе команды деления в разных CPU не были бы такими тормозными. При малой разрядности - таблица. (как уже писали выше) -
Зачем? У меня эти 16 адресов использовались всеми участниками CAN-сети. Типа - как параллельная шина. Самый старший адрес (базовый_CAN_ID + 15) - для передачи кадров управления (заголовки мультикадров и различные команды управления этой "шиной"). Точнее - старший адрес у каждого устройства был свой, а вот остальные 15 адресов - общие (для передачи тела данных мультикадров). Хотя наверное всё-таки = было 16 адресов для тела данных, а адреса управления - отдельно, у каждого устройства свой. У меня в сети были мастер и много слэйвов. Инициатива обмена мультикадром (на ввод или вывод) - всегда по инициативе мастера. Поэтому все слэйвы по дефолту держат свои 16 MO тела данных в режиме приёма; мастер - в режиме передачи. В прерывании выигрыша арбитража (вроде так) адреса управления мастер переключает свои 16 MO данных на приём (так как в этот момент все MO данных гарантированно уехали в шину); потом передаётся собственно кадр из MO управления. Один из слэйвов (который получил в свой адрес управления) финальный управляющий кадр; перед ответом переключает 16 MO данных на передачу; передаёт ответный мультикадр (или короткий ACK через адрес управления; если тело данных не нужно) и также в прерывании выигрыша арбитража на передачу заголовка переключает свои 16 MO данных на приём. Так нет коллизий (нет двух наборов MO данных одновременно настроенных на передачу в разных устройствах). Вобщем - такая себе полудуплексная квази-параллельная шина из 16 MO данных и одного MO управления. С одним прерыванием на передачу мультикадра и одним - на приём. Всего у нас устройств в шине планировалось - до 33 шт. Значит для всего интерфейса нужно: 16+33 шт. адресов. Вроде как не особо много. Требования по ресурсу CPU - очень низкие получились, практически незаметные на общей загрузке CPU Cortex-M4 144MHz. Только надо добавить небольшие защитные паузы перед переключением MO данных на передачу. Чтобы другая сторона гарантированно успела переключить свои на приём. Чтобы не мешали задержки входа в ISR на разных участниках обмена. ЗЫ: Глянул в исходники: всё-таки наврал - ширина шины у меня == 8 MO. Но задаётся дефайном, так что можно поменять в любой момент. #define CAN_NSLAVES 32 //макс.кол-во слэйвов #define CAN_UG_D_WIDTH 8 //кол-во MO (и адресов) используемых для отправки тела UG-кадра //Распределение адресов (11-битных) на внутренней CAN-шине. Адрес == смещению от начала ICanAddrSpace. struct ICanAddrSpace { char unuse0[16]; char obReset; //адрес сброс-сообщения (протокол обзора + UG) char unuse1[15]; char torque; //адрес рассылки задания крутящего момента char unuse2[32]; char obData; //протокол обзора. данные char obCmd; //протокол обзора. команды char obGarbage; //протокол обзора. сбор мусора char obScan[4]; //протокол обзора. сканирование серийных номеров char obInfo; //протокол обзора. информация о совместимости прошивок char unuse3[7]; char ugData[CAN_UG_D_WIDTH]; //адреса тела UG-кадра struct { char master; //адрес UG-master char slave[CAN_NSLAVES]; //адрес UG-slave } ugCtl; }; //Распределение CAN.MO. Номер MO == смещению от начала CanMoSpace. //Чем больше смещение - тем ниже приоритет при отправке на передачу. struct CanMoSpace { struct T_ug { //MO UG-протокола. Использование мастером и слэйвом: char data[CAN_UG_D_WIDTH]; //все: приём/передача тела UG-кадра char ctlRx; //все: приём заголовков char ctlTx; //все: отправка заголовков; мастер: отправка сброс-сообщений struct Observe { //MO протокола обзора. Использование MO мастером и слэйвом: char data; //мастер: отправка тела команды (свой UID); слэйв: приём тела команды (UID мастера) char cmd; //мастер: отправка заголовка команды; слэйв: приём заголовка команды char scanRx; //мастер: приём ответов от слэйва на проверку живости UID (в OBF_DELAY3); слэйв: приём RTR-запросов сканирования char scanTx; //слэйв: отправка ответов на RTR-запросы сканирования char misc; //мастер: приём информационных кадров (в OBF_SCAN0); слэйв: отправка ответов на проверки живости UID } observe; char reset; //все: приём сброс-сообщения } ug; struct T_ecan { char tele[CfgTele::STREAM_N]; //телеметрия char remote[CfgRemote::ITEM_n]; //дистанционное управление } ecan; }; ICanAddrSpace::ugCtl - как раз адреса интерфейса передачи мультикадров. CanMoSpace::data, CanMoSpace::ctlRx, CanMoSpace::ctlTx - MO этого протокола. Как видно - ресурсов шины он требует немного.
-
Так вы же вроде свой протокол ваяете? Почему тогда для передачи мультикадров выделили только один адрес (CAN-ID)? Почему не выделить например - 16 последовательных адресов? Когда-то также пилил свой протокол поверх CAN. С передачей мультикадров. Просто выделил для него 16 последовательных адресов (CAN-ID). И передавал мультикадр так: вырезАл очередные <=8*15 байт данных (из передаваемого массива данных); пристыковывал к нему заголовок мультикадра (с необходимой инфой: индексом мультикадра в потоке, количеством кадров в мультикадре, CRC и т.п.). Затем нарезал тело мультикадра по 8 байт и передавал начиная от хвоста с нарастающим адресом: В таком случае FIFO не нужно - каждый кадр попадает в свой MO. И для отправки не нужна возможность в МК задавать порядок отправки: можно по порядку CAN-ID передавать - заголовочный CAN-ID всегда придёт последним. И прерывание нужно только одно - для заголовочного (последнего кадра); кадры тела принимаются/передаются без прерываний. Так сделал на всякий случай - хотя у меня был XMC4700 с аппаратными FIFO и множеством MO, но на всякий случай, если нужно будет подключать к шине МК с CAN-контроллером послабее.
-
Судя по сообщениям ТС, он изобретает свой велосипед. И ему все эти канопены с их проблемами - не указ. Вот уж точно - такое есть не в каждом МК. Тем более. Не то что FIFO..... А ещё можно - часть ID под данные кадра. И тем - повысить плотность потока. Хотя степени двойки конечно уже не будет....
-
Почему не помогает? Если в МК имеется 2+ шт. MO для приёма, то этого достаточно для двойной буферизации. И если не пропускать прерывания, то порядок приёма не будет нарушен.
-
Тогда: не пропуская прерываний. Или вместо прерываний - DMA. Ну или действительно - выделить часть CAN-ID под индекс кадра внутри мульти-кадра.
-
Зависит от конкретного МК и от протокола. Могу сказать как в XMC4xxx. Надо? В XMC4xxx достаточно для каждого mailbox-а указать маску адреса - какие CAN-ID в него принимать. А если все кадры - с одинаковыми CAN-ID, то можно например соединить mailbox-ы в цепочку FIFO. Которое будет заполняться по порядку. Ну и другие способы можно придумать.... например - при помощи DMA и FIFO уже в общей памяти. Хотя для XMC4700, с его 256 майлбоксами, это не нужно. Это уж не говоря о том, что можно просто тупо реагировать на каждое прерывание о приёме каждого нового кадра. И делать всё программно. А как в жизни - расскажете? У вас биты по CAN гуляют сами по себе, куда вздумается? Кроме пустых общих фраз, есть что по делу сказать?
-
В смысле? А почему они должны приняться не в том порядке, в котором следуют по шине? Никаких роутеров, с ретрансляцией очевидно у ТС-а на шине нет.
-
Можно выделять можно и не выделять. Так как при отправке хвостовой (или головной) кадр пакета кадров можно отправить последним. Сам делал такой протокол. Без дополнительных счётчиков.
-
А кто мешает? Не очень понятно - что мешает отправить в нужном порядке? Приёмная сторона примет их точно в том порядке, в котором они будут передаваться по шине. Ибо - другое невозможно по определению.
-
Ну тогда - для XMC4xxx: раздел "Transmit Acceptance Filtering". Но вкратце - нет никакой обязательной связи CAN-ID с порядком выставления на арбитраж. Порядок задаётся другими инструментами.
-
Из исходного поста следует, что именно отправили: а не просто "положили в ящик". Почему я и попросил уточнения. Насчёт порядка отправки готовых для отправки MO, то в XMC4xxx вроде как порядок такой отправки (выхода MO на фазу TX-арбитража) вообще не зависит от CAN-ID кадра. А зависит только от положения MO в списке MO для данной ноды и поля приоритета, прописанного в свойствах MO. Нет такой гарантии. Или о чём вы тут говорите? Сам CAN описывает только фазу арбитража. А выставлять или нет на него кадр - решает CAN-контроллер МК. Решает в общем случае - никак не согласуясь с CAN-ID. Более того: CAN XMC4xxx позволяет программисту определять: участвовать ли готовому к отправке кадру в повторном TX-арбитраже, если он проиграл предыдущий арбитраж или нет? Программист может указать как действовать для каждого конкретного кадра.
-
Если вы их уже отправили, то как они могут поменять порядок будучи уже отправленными? Странный вопрос.... Может вы всё-таки неверно сформулировали вопрос и он касается очередности выставления для участия в арбитраже для отправки на шину кадров из мэйл-боксов готовых к передаче? А не уже отправленных кадров. Порядок отправки зависит от вашего контроллера - он может отправлять как угодно, совершенно никак не связывая это с CAN-ID. Почитайте мануал на него. Для XMC4xxx например можно задать порядок отправки. И там есть несколько возможных режимов отправки. Постановка на арбитраж (для отправки) никак не связана с CAN-ID.
-
Наверное всё-же - не в любых. IAR 7.80.4, си-файл: typedef unsigned char byte; byte PID_CODE[4]; void LongToBytes(long LG, char* BYTES, byte Index); void mm1(void); void LongToBytes(long LG, char* BYTES, byte Index) { byte i; for (i=0;i<4;i++) { BYTES[Index+i] = (*((unsigned char *)&(LG)+i)); } } void mm1(void) { LongToBytes(0x4445, PID_CODE, 0); LongToBytes(0x4445, (char *)&PID_CODE[0], 0); } результат: Warning[Pe167]: argument of type "byte *" is incompatible with parameter of type "char *" B:\TST\11.c 27 варнинг Pe167 на первую строку mm1(). Возможно вы правы. Не буду гадать - что там у автора, так как половину необходимой для понимания инфы он скрыл. Я просто говорил, что объявление функции нужно не такое, какое вы приводили. А с типом указателя byte *. Ну или добавить ещё приведение типа.
-
При том, что неявное преобразование типа byte * -> char * компилятор автора видимо не умеет. Поэтому не может использовать имеющееся: void LongToBytes (long LG, char * BYTES, byte Index) без явного приведения типа. Имхо.
-
Может здесь у автора также - есть халявный доступ к неограниченному количеству ионисторов? Как у автора недавней темы про "электровелосипед на ионисторах". И очень хочется их куда-нить пристроить. Не важно куда. Его ещё купить нужно. А ионисторы оне вот - в столе лежат... целой кучей... и "на халяву".
-
Линия автоматического монтажа
jcxz ответил inmatened тема в Пайка и монтаж
Видимо - эффективные манагеры сократили всех дармоедов программеров и больше некому за "крайние 25-ть лет" переработать изделие на новую элементную базу. -
Прошу помощи в разработке энкодера колеса мыши
jcxz ответил Darmok тема в Схемотехника
Имхо - рациональнее будет не мышь свою деревянную пилить, а сделать адаптер: USB-мышь -> КР580ВМ80. На любом МК с USB-хостом. Тогда можно будет (почти) любую современную USB-мышь использовать. Подходящую по руке например. Да и проще в изготовлении.