Перейти к содержанию
    

777777

Участник
  • Постов

    1 085
  • Зарегистрирован

  • Посещение

Весь контент 777777


  1. Мы решали аналогичную задачу. Микроконтроллер сам запитывал ротор, подавая на него постоянное напряжение, пока ток в обмотке нарастает, измеряет напряжения на статорных обмотках. Затем напряжение снимается, а через некоторое время подается напряжение противоположной полярности - чтобы ротор не намагничвался - и опять измеряется напряжение статорных обмоток. По их соотношению вычисляется угол. Если запитку менять нельзя, нужно будет измерять переменное напряжение, это тоже не сложно. Математика для вычисления угла примерно такая. Если магнитные датчики расположены под углом 90 градусов (т.е для синусно-косинусного трансформатора) и мы имеем сигналы Y=sin(phi) и X=cos(phi), то для вычисления угла достаточно посчитать арктангенс их отношения. Для этого имеется следующий итеративный алгоритм. Пусть phi0 - значение угла, подстраиваемое на каждой итерации. Для его вычисления домножаем сигнал Y на cos(phi0), а X на sin(phi0) и вычитаем их: Y*cos(phi0) - X*sin(phi0) = sin(phi)*cos(phi0) - cos(phi)*sin(phi0) = sin(phi - phi0) ~ phi - phi0 Мы получили разность, прибавив которую к phi0 сразу получаем текущий угол. Выполняя эту операцию непрерывно мы будем непрерывно отслеживать угол. В случае сельсина угол между обмотками 120 градусов и мы имеем Y=sin(phi) и X=sin(phi + d), где d = 120. Для вышеописанной формулы требуется косинус, для его вычисления выполним следующие преобразования: sin(phi + d) = sin(phi)*cos(d) + cos(phi)*sin(d); заменяем синусы на X и Y X = Y*cos(d) + cos(phi)*sin(d); из этого выражения находим cos(phi) cos(phi)*sin(d) = X - Y*cos(d) cos(phi) = (X - Y*cos(d)) / sin(d) Таким образом, мы получили cos(phi), синус у нас уже есть и задача свелась к предыдущей. Поскольку d=120, то получаем формулу cos(phi) = (X + Y/2) / (sqrt(3)/2) Resolver - это СКТ (синусно-косинусный трансформатор). А сельсин - это selsyn. Отличаются они (если не считать мощностей) углом под которым расположены статорные обмотки.
  2. Что-то я с трудом себе представляю как компилятор может определить размер стека. Кейл хоть и строит дерево вызовов и знает о количестве локальных переменных в каждой функции, но ведь могут быть вызовы по указателю на функцию, а они могут вызываться откуда угодно. Но для указателей там вроде нужно было вручную составлять для линкера дерево вызовов. Но ведь есть еще рекурсивные вызовы, а их компилятор не может просчитать в принципе, так как количество вложений на этапе компиляции неизвестно.
  3. тормозит DMA - 2

    Выводится аналоговый сигнал в ЦАП с помощью DMA. Довольно интенсвно, через 264 нс. Пока работает только он, сигнал ровный. Но стоит запрограммировать любую другую периферию с прерываниями, как сигнал начинает тормозиться, увеличивается его период, появляются искажения. Причем только если выполянются прерывания. Как это может быть? Разве DMA не может захватить шину в любой нужный ему момент времени? Или при обработке прерывания запрещаются не только другие прерывания, но и DMA?
  4. Это назывется "слышал звон, да не знаю где он". А если одну точку измерить в момент t=0, а второй в 2*PI? Нужно не меньше четырех значений, что с ними делать дальше - написано здесь. При идеальном синусе этого достаточно, при неидеальном нужно больше. 20 отсчетов на период - вполне достаточная точность, но я бы выбрал количество кратное четырем. А вообще, я не уверен, что с помощью встроенного АЦП можно добиться хорошей точности. 12 бит - это лишь разрешающая способность, а не точность. У этого корпуса хоть отдельный вход для опроного напряжения?
  5. ATmega8A + ADS1244

    Боюсь, что "дело было не в бобине"... Не знаю как там у вас с обычными средствами устранения шумов - толстые земли, конденсаторы по питанию, ликвидация паразитных токов по земле и т.п. - но главной частью сигма-дельта АЦП является его цифровой фильтр. И его настройка является главной задачей разработчика. Вы же на него плюнули (т.к. поставили первый попавшийся кварц) после чего заявляете что этот АЦП - фуфло.
  6. Atollic TrueSTUDIO®

    На вид довольно солидная студия...
  7. Это не столь очевидно. :) Стек находится в RAM-е, у него нет отдельного пространства. И если ты перенесешь массив из стека и сделаешь глобальной переменной, то свободного места в ОЗУ обльше не станет.
  8. LPC vs STM32 cortex-M3

    Ну, компиляторы тоже проявляют чудеса оптимизации, иногда смотришь на код и диву даёшься - как он до этого додумался? Но это только пока архитектура контроллера не выходит за рамки общепринятой. А вот компиляторы для сигнальных процессоров хоть и тоже умные, однако не используют фичи предназначенные именно для обработки сигналов. В лучшем случае ты можешь воспользоваться библиотечными функциями, поставляемыми с конкретно этим процессором. Так и здесь - те возможности, которые отличают один контроллер от другого, эта программа использовать не будет - просто потому, что их нет в других контроллерах и если ты портируешь проект на другой, то она не сможет "скомпилировать" твой проект. Понятно. Значит придется изучать не только регистры АЦП, но и структуру ADC_InitTypeDef, а также саму функцию инициализации. А я ничего и не утверждаю. Я всего лишь спрашиваю, чтобы понять: какие преимущества дает использование этих функций? Вам меня пока убедить не удалось.
  9. LPC vs STM32 cortex-M3

    Может я чего-то упустил, но все, что я видел - ложатся. И в функциях помимо простого копирования из структуры в регистры были разве что какие-то ассерты. Не дают библиотеки ничего из перечисленного. Все нюансы все равно требуется знать, никаких абстракций они не создают и следовательно время не экономят. Да и какие абстракции могут быть, например, при программировании таймеров? Как можно избежать нюансов? Вот я только что организовал выдачу сигнала слложной формы - там DMA записывает в ЦАП значения из массива, а по окончании он подает запрос другому контроллеру DMA и он записывает в первый DMA адрес следующего массива, который тот должен передавать в ЦАП. Диаграмма формируется только периферией (2 таймера, 2 DMA, ЦАП), без участия процессора. Как вы себе представляете RTOS, которая бы предоставляла такую возможность? Боюсь, что без чтения 2000 страниц даташитов это невозможно. И вообще, любое универсальное (кроссплатформенное) средство будет непременно упрощенным, чтобы использовать только те возможности, которые есть во всех контроллерах, которые оно поддерживает. Следовательно самые интересные фичи, в которых изощряются производители и которыми контроллеры отличчаются друг от друга, не будут поддерживаться. И чтобы ими воспользоваться, придется прочитать даташит.
  10. LPC vs STM32 cortex-M3

    Я использую 144-ногий, но вроде бы в 100-ногом тоже можно. Я уже спрашивал, может здесь кто объяснит - на фига они нужны? В чем глубокий смысл инициализировать структуру, а потому вызвать функцию, которая перепишет эту структуру в регистры? Почему сразу не инициализировать регистры?
  11. Интересное решение проблемы. Особенно если учесть, что убрав массив из стека, ты поместил его в RAM, в котором и находится стек. Как же его стало хватать?
  12. Кажется вы где-то правы. В даташите действительно описаны отдельные прерывания для разных DMA, но в файле STM32F10x.s список прерываний заканчивается на USBWakeUp_IRQHandler. Я нашел другой стартап в CMSIS и все заработало. Какой-то кейл недоделанный, и не всю периферию показывает при отладке, и стартап не полный.
  13. Для 100 мкГн? Такую катушку и без сердечника можно сделать. Но точность, конечно, да.
  14. Нет, прерывания отличаются только Channel-ами. Разные DMA пользуются одинаковыми прерываниями.
  15. Это невозможно посчтать исходя из данных даташита. 3 Вт - это произведение тока на напряжение, но ведь часть мощности уносит свет.
  16. Нет прерываний от DMA

    Импульсы таймера 8 запускают DAC, он с помощью DMA загружает число из памяти и формирует сигнал. Но по окончании цикла прерывание от DMA не приходит. Чего здесь не хватает: void DACSetup(void) { RCC->AHBENR |= RCC_AHBENR_DMA2EN; // DMA clock enable RCC->APB2ENR |= RCC_APB2ENR_TIM8EN; // TIM8 Periph clock enable RCC->APB1ENR |= RCC_APB1ENR_DACEN; // DAC Periph clock enable // TIM8 TIM8->PSC = 0; // Prescaler = 0 TIM8->ARR = 18; // Auto reload value (18+1)*80/72 = 21.12 us TIM8->CR2 = TIM_CR2_MMS(2); // Select the TRGO source // DMA DMA2_Channel3->CCR = DMA_CCR_PL(3) | DMA_CCR_MSIZE(1) | DMA_CCR_PSIZE(1) | DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_DIR | DMA_CCR_HTIE | DMA_CCR_TCIE; DMA2_Channel3->CNDTR = 80; DMA2_Channel3->CPAR = (u32)&DAC->DHR12R1; // Peripheral address, page 45 of RM0008 manual DMA2_Channel3->CMAR = (u32)&Sine; // DMA 2 channel 4 memory address register NVIC->ISER[1] = 1 << (DMA2_Channel3_IRQChannel & 0x1F); // DMA2 Channel 3 global Interrupt // DAC DAC->CR = DAC_CR_TSEL1(1)|DAC_CR_TEN1|DAC_CR_BOFF1; // Trigger = Timer 8 TRGO // Enable everything DMA2_Channel3->CCR |= DMA_CCR_EN; // Enable DMA 2 channel 3 DAC->CR |= DAC_CR_DMAEN1|DAC_CR_EN1; // Enable DAC Channel 1 TIM8->CR1 |= TIM_CR1_CEN; // CEN: Counter enable bit } Обработчик прерывания: DMAChannel3_IRQHandler() { DMA2->IFCR = DMA_IFCR_CTCIF3; { int volatile xx; GPIOA->ODR |= 0x04; for(xx=0; xx < 10; ++xx) __nop(); GPIOA->ODR &= ~0x04; } }
  17. Что значит "религиозный"? Предложение использовать интсрумент только по назначению вы считаете религиозным пылом? Ну да, настоящие пцаны могут и микроскопом гвозди забивать, даже не той стороной. Я надеялся увидеть конкретный пример. Да, здесь вы конечно правы. Но самолетом управлять тоже сложно, но несмотря на это никто их за это не критикует и не требуют запретить. Во-первых, я нигде не писал, что язык с классами - уже ОО. Во-вторых, я даже не представляю где вы выкопали такое определение. Обязательными составными частями ОО всегда считались инкапсуляция, наследование, полиморфизм. Все они есть в С++, о чем еще может быть спор? Или если некая конкретная программа не использует полиморфизм, то она уже не объектно-ориентированная? Но речь вроде бы о языке, а не о программах. Наконец, последние слова меня привели в полное замешательство: "...без виртуальных функций, не несут ООП, это обычный объектный подход". Это не опечатка? ООП и "объектный подход" чем-то отличаются?
  18. Что значит "не нужны"? Что значит "сами по себе"? (почти) всё перечисленное - свойства ООП. Поскольку все это есть в С++, то он является объектно-ориентированным языком. Мне кажется при построении этого предложения вы где-то допустиои опечатку. Изначально он назывался "Си с классами". Потом он получил название С++, а постепенно в него напихали всего, что было модно на текущем этапе развития программирования. Поэтому трудно говорить о том, был ли он когда-нибудь "чистым" ОО языком весьма проблематично. Я понимаю, фаллометрия очень важна для посетителей этого форума.
  19. Еще можно дать возможность пользователю написать формулу, по которой генератор будет выдавать напряжение.
  20. Потому что С++ - это язык ООП. Всё остальное, что в нем есть - это (ненужные) навороты, главная его особенность - объектная ориентированность. О как! Сильно сказано. Только вот как раз ООП и придумано для того, чтобы можно было не сократить, а полностью ликвидировать утечки памяти - просто нужно тщательно продумать структуру программы и распределение объектов. И выделять память в конструкторе объекта, а удалять в деструкторе. Тогда их не будте никогда. Разве что у тех программистов, которые так и не поняли смысл объектно-ориентированного программирования. То есть если в некоем языке есть фича которую вы не понимаете или с которой у вас когда-то были проблемы - то это плохой язык. Вот тот у которого нет такой фичи - хороший. Зачем? Вот убей не пойму, почему когда пишут прикладную программу для обычного компьютера, она не требуется, а в микроконтроллерах непременно нужна? Динамическое размещение объектов встречается везде, но в C нет средств для аккуратной работы с ними, а в C++ есть. Да, это серьезный недостаток! На С можно писать и без головы, только... не хотелось бы мне пользоваться таким устройством.
  21. Кстати, может кто-нибудь объяснит в чем глубокий смысл - сначала заполнять структуру, а потом вызывать функцию, котороая перепишет эту структуру в регистры? Я сразу заполняю регистры, в этом случае описанные глюки невозможны: ненужные регистры инициализируются при сбросе описанным в даташите образом, поэтому нет необходимости инициализировать их в программе.
  22. А что это за макрос __REV16_W?
  23. ATxmega

    Чтобы из-за неравномерности потребления разные узлы не влияли друг на друга. А что, хочется сэкономить? А нельзя.
  24. То есть в точности такой же. Тогда зачем его выдавать? Подайте на выход входной сигнал, раз он ничем не отличается от выходного.
×
×
  • Создать...