-
Постов
200 -
Зарегистрирован
-
Посещение
Весь контент Dir
-
Так все ж про него, про Аппнот Атмеля, который про ПИД. Вот какой он есть для AVR: http://atmel.com/dyn/resources/prod_documents/AVR221.zip http://atmel.com/dyn/resources/prod_documents/doc2558.pdf И вот что от него остается для ARM: typedef struct { float fKp; float fKi; float fKd; float fLastProcessValue; float fSumError; float fMaxPID; float fMinPID; } PID_DATA; WORD ContrPID(float fSetPoint, float fProcessValue, PID_DATA *pid) { float fError, fPterm, fDterm, fIterm, fRet, fsError; fError = fSetPoint - fProcessValue; // Вычисление P-терма fPterm = pid->fKp * fError; // Вычисление D-терма fDterm = pid->fKd * (fProcessValue - pid->fLastProcessValue); pid->fLastProcessValue = fProcessValue; // Вычисление I-терма fsError = pid->fSumError + fError; fIterm = pid->fKi * fsError; // fRet = fPterm + fDterm + fIterm + pid->fMinPID; // if (fRet > pid->fMaxPID) return (WORD)(pid->fMaxPID); else if (fRet < pid->fMinPID) return (WORD)(pid->fMinPID); pid->fSumError = fsError; return (WORD)fRet; } Остается добавить инициализацию и ... фсе, можно использовать :yeah: Конкретный пример: void FlowRatePID(void) { WORD U_reg; // вычисление нижней и верхней границы переменной регулирования PidDataFR.fMinPID = DELTA_LOWLIM + K_LOWLIM * fPin; PidDataFR.fMaxPID = DELTA_HIGHLIM + K_HIGHLIM * fPin; // вычисление коеффициентов Kp, Ki, Kd PidDataFR.fKp = fKpFR; PidDataFR.fKi = fKiFR; PidDataFR.fKd = fKdFR; // регулирование U_reg = ContrPID(fSetFlowRate, fFlowRate, &PidDataFR); setPWM_pr(U_reg); } Куда в реальной жизни может убежать интегральный терм, если он во флоуте? Или в дабле? Это в целом виде он может переполнить 16-битную разрядную сетку (AN221). PS. Пример реальный, но писался очень давно для регулирования скорости расхода газа (Flow Rate) регулятором на ARM по мотивам AN221. Тонкости уже подзабылись. PPS. "Для ARM" это я, конечно, говорю условно. Ничто не мешает его и на AVR запустить. Но вот что-то не много я знаю людей, которые на AVR свободно флоутами и даблами ворочают. Все боятся (и правильно!), что производительности не хватит...
-
О, очень многим :) При реализации алгоритма ПИД на ARM в подавляющем большинстве случаев можно вообще не заморачиваться эффектами насыщения интегрального терма. Работай в лоб с флоутами (и даже даблами) и в ус не дуй. Быстродействия хватает. Для AVR же приходится морочиться с целочисленной арифметикой, перекалибровками, следить за границами термов... В общем, ARMы для ПИДов зверски упрощают жизнь :)
-
Перефразирую "сколько людей - столько мнений", в "сколько разработчиков - столько задач"... мне вот их DMA и перекроссировка периферии и нафиг не нужны, а 8 UARTов - самое ценное, что там есть :)
-
А я слышал, что Infineon вроде собрался сливаться с NXP. Что здесь замешана еще и ST - большая новость :blink:
-
Вот-вот. Мне тоже вся эта "презентация" с охаиванием вырвавшихся вперед конкурентов, живо напомнила оправдания пассажира, опоздавшего на поезд. Типа: "Не очень то и хотелось ехать..."
-
А что в STM32 не устраивает?
-
Так это тоже будет. Но в серии LPC1000. В 3...4 квартале 2009 года согласно рис. на стр.72. Пока, очевидно, не хотят создавать сами себе конкуренцию. Бросилась в глаза фраза "Единственной причиной, почему бенч в DMIPS Cortex-M3 больше, чем ARM - наличие аппаратного делителя" (перевод вольный). Да и диаграммы производительности ARM и Cortex-M3 явно диссонируют с такими же у STM. Хотя у той тоже есть внутренний тормоз в виде STR912, не позволяющей быстро выпустить Cortex с Ethernet. Был бы у Luminary проц поприличнее (ну хотя бы до 75МГц), думаю, дала бы она прикурить этим гигантам.
-
Точно не имеет права? volatile это ведь говорит только о том, что переменная на чтение меняется когда хочет. Момент записи volatile не регламентирует. Сам я на всякий случай процедуру инициализации провожу с прагмами no optimize или no code motion
-
В оптимизации. Вот несколько причин, когда оптимизатор кардинально ломает функционирование: 1. может соптимизировать (вообще выбросить) переменную, которая ошибочно не была объявлена как volatile 2. может переставить порядок следования команд при инициализации периферии, что ведет к их неправильной работе 3. может выбросить несколько подряд следующих команд в функции, например, задержки, что приводит к неправильному функционированию времязадающих функций. 4. редко (но вполне возможно) может быть просто глюк оптимизатора. Резюме. Не обольщайтесь, что у вас в Debug-е программа вроде бы работает. Оптимизатор - мощная штука не только для уменьшения объема используемой памяти и скорости выполнения, но и для вывления скрытых (неочевидных) ошибок программиста. Так что ищите и найдете ;) PS. Ну, это все если я правильно понял ваш вопрос и Debug с Release отличаются уровнем оптимизации.
-
Загрузка программы в МК ADuC7026 - помощь начинающему.
Dir ответил dm-ternovsky тема в ARM
1. Если в Options установлен симулятор, значит программа в ADuC не грузится, а симулируется на ПК 2. Для генерации Hex-файла используй 4 строку Options "Output Converter". Там выбираешь intel-standart 3. Для прошивки hex-фала в ADuC используй ARMWSD. Как вариант можешь протестировать мой ArmBL. Я его, правда, писал для ADuC7128, но учитывая одинаковый протокол ADuC702x тоже должен шить. Его преимущество - связь по USB, гальваническая развязка, Windows-интерфейс. Кроме того он сам дергает ножками BM/ и RES/, что упрощает массовое программирование. Недостатки - кроме железа (см.схему) нужно на комп установить драйвера USBXPress от Silabs. Запускается exe-ник. В той же папке должен быть и dll. В общем, если будет желание воспользоваться загрузчиком - спрашивай. ArmBl.RAR -
;) Тоже так думаю, что напутано с объявлениями (или присвоениями) типа char по умолчанию (radio button "plain char is" в настройке компилятора). Вот и путает 255 с -1;
-
Т.е. AVR? Странно, однако, про такое слышать. Чем лечите? Памяти на компе сколько? Под какие еще камни IAR EWB стоит и в какие директории установлено? Может ну его нахрен эти антивирусы или, наоборот, крутой вирь затесался? Больше ничего не могу придумать. Стоят 5.11 (ARM), 5.10 (AVR), 4.10 (MSP) и 7.40 (51). ОЗУ на компе, правда, 2М. Вылетают, правда, иногда, с предупреждениями о неизвестной фатальной ошибке при высоких уровнях оптимизации http://electronix.ru/forum/index.php?showtopic=45441 но редко и несмертельно PS. Да, с 4.21А в свое время тоже проблем не было...
-
Тревор Мартин "Микроконтроллеры ARM7 ..." Изд-во Додека, 2006 год + CD Пол книги про Keil. С упражнениями.
-
Понятно, что не встречал. Eval без них идет. А зачем нужны исходники - читай User Manual на компилятор. Там подробно расписано какие настройки компилятора требуют перекомпилирования исходников библиотек. В некоторых случаях, например, определение какие регистры при обработке прерываний нужно, а какие не нужно сохранять, это может значительно поднять скорость выполнения программы. В общем, вещь очень желательная для достижения максимальной эффективности. Но доступная только легальным юзерам, купившим программу.
-
Спасибо! Cняли подозрения в том, что это вирус :)
-
То ли я где-то вирей набрался, то ли совсем крыша едет, но у меня компиллер вылетает на этом простейшем примере с грозным предупреждением о неизвестной фатальной ошибке. Причем на низких уровнях оптимизации все ОК. Также перестает вылетать, если раскомментарить закоментаренный код. Что это может быть: баг компилятора, погрызенный вирем комп, глюки лицензионного менеджера? Проверьте у кого 5.11 и подскажите, что делать. Глючит аналогично на двух компах. Но поиск вирей пока ничего не дал. Пардон, с файлом что-то не получилось. Код вот: typedef unsigned short WORD; typedef struct { float fKp; float fKi; float fKd; float fLastProcessValue; float fLastIterm; float fSumError; float fMaxPID; float fMinPID; } PID_DATA; WORD ControllPID(float fSetPoint, float fProcessValue, PID_DATA *pid) { static float fmProcessValue[16], fmError[16], fmPterm[16], fmDterm[16], fmIterm[16], fmRet[16]; static int index=0; float fError, fPterm, fDterm, fIterm, fRetPD, fRet; fError = fSetPoint - fProcessValue; fmProcessValue[index] = fProcessValue; fmError[index] = fError; fPterm = pid->fKp * fError; fmPterm[index] = fPterm; fDterm = pid->fKd * (fProcessValue - pid->fLastProcessValue); fmDterm[index] = fDterm; pid->fLastProcessValue = fProcessValue; fIterm = pid->fKi * (pid->fSumError + fError); fmIterm[index] = fIterm; fRetPD = fPterm + fDterm + pid->fMinPID; fRet = fRetPD + fIterm; fmRet[index] = fRet; /* if (++index == 16) return (WORD)pid->fMinPID; */ if (fRet > pid->fMaxPID) return (WORD)pid->fMaxPID; else if (fRet < pid->fMinPID) return (WORD)pid->fMinPID; pid->fLastIterm = fIterm; pid->fSumError += fError; return (WORD)fRet; }
-
Да, круто вы переходите на новую версию ;) Даже в релиз нотес не заглядывали. А там ведь все написано. И то, что линкер другой, а потому файлов xcl уже не существует в природе (зато есть icf). И то, что конструкции #pragma vector уже тоже не существует. Вообще 5 версия довольно сильно отличается от 4, так что читайте, не ленитесь. PS. Если взглянете на стартап, то сразу увидите куда идут вектора и сработает, например, самая примитивная конструкция (без всяких прагм): __arm __irq void IRQ_Handler(void) { } Ну или воспользуйтесь примером для вашего МК. PPS. Тут уже обсуждали, чем отличается 5 весия от 4 и делились впечатлениями. Так что поищите.
-
У меня ADuC7128, но разницы в загрузчике, думаю, нет и все шуршит без проблем. Не учитывая, что защита 7128 через загрузчик пока ADI не реализована. Даже сделал свой загрузчик по AN724, чтобы не вручную с выводами BM/ и RES/ играться. Использую при прошивке ADuC7128 в серии. Может BM/ не через 1кОм к земле тянешь, а напрямую? Не знаю, правда, что в таких случаях происходит, т.к. как все делал как рекомендуют. Если хочешь, то можешь мой загрузчик проверить. Он на базе CP2103 и вся дока (кроме исходников на С++Builder в комплекте). http://upload.caxapa.ru/ArmBl.RAR Не гарантирую, правда, корректной работы с твоим ADuC, т.к. хотя программа и задумывалась универсальной, но пока проверялась только с ADuC7128. Других МК пока просто под рукой нет.
-
Были у меня случаи с m162, когда при всей тщательности разводки все-таки не удалось заставить ее безпроблеммно работать в реальном шумовом окружении. Решил проблему использованием вместо кварца внешнего SMD MEMS-генератора. Слава богу, они сейчас все меньше и меньше и все дешевле и дешевле ;) Размеры этих генераторов достигли 2x2,5мм (например, KXO-V95 у Geyer) http://www.geyer-electronic.de/pdfs/qurz/m...5.pdf?langSel=0 а цена в розницу спустилась до уровня меньше 1$ как, напрмер, 5х7мм SMD-генераторы фирмы SJK. Жалко, что не одновременно, но все к этому идет. И в то же время точность 50ppm сохраняется :) Так что, похоже, очень скоро все разговоры о проблемах встроенных в МК генераторах для работы с внешними резонаторами будут просто неактуальны. PS. Эти генераторы еще и повышенную вибростойкость имеют, так что в вашем случае это дополнительный повод задуматься ;) PPS. А если проблема вибраций сильно достает, то почему бы вам не подумать о калибровке внутреннего RC-генератора (подбором значения OSCCAL). Может это будет и самый оптимальный в вашем случае выход. Хотя, конечно, 8МГц это не 16. Но может хватит?
-
Вообще то не лишний, а наоборот одного байта не будет до поры до времени. Но, ИМХО, не в этом проблема. И это нужно делать руками (т.е. запрещать прерывания)? Встроенных средств в компилере для этого нет?
-
Итак, ADuC7128 + C от IAR v5.11. Тестовая и программирующая аппаратура J-Link v3.78d (JetLink-5) . Проблема с отработкой обычного кольцевого буфера по прерываниям. Одна программа putBYTE() пишет в этот буфер, а по прерыванию от таймера этот буфер выгребается и посылается на UART. Период прерываний от таймера 50мкс, UART настроен на скорость 115200. Вот ее текст: typedef unsigned char BYTE; #define TX_BUFFER_SIZE0 64 #define COM_TEMP 6 // COMxTX Empty volatile BYTE tx_buffer0[TX_BUFFER_SIZE0]; volatile char tx_wr_index0, tx_rd_index0, tx_counter0; void putBYTE0(BYTE c) { while (tx_counter0 == TX_BUFFER_SIZE0); tx_buffer0[tx_wr_index0] = c; if (++tx_wr_index0 == TX_BUFFER_SIZE0) tx_wr_index0=0; tx_counter0++; } __arm __irq void IRQ_Handler(void) { if (IRQSTA & (1 << INT_T0)) // сброс прерывания от таймера T0ICLR = 0; BYTE status; status = COM0STA0; if (status & (1 << COM_TEMP)) { if (tx_counter0) { tx_counter0--; // 1 COM0TX = tx_buffer0[tx_rd_index0]; if (++tx_rd_index0 == TX_BUFFER_SIZE0) // 2 tx_rd_index0=0; // test ------- if (!tx_counter0 && (tx_rd_index0 != tx_wr_index0)) LED_OFF; // test ------- } } } Глюк в том, что в передатчик UART иногда посылается на 1 байт больше! Этот факт отражен в тестовом фрагменте между двумя // test. Т.е. при уменьшении tx_counter до 0, tx_rd_index0 становится больше (на 1), чем tx_wr_index0. Так реально и происходит. ПК получает лишний байт, стоящий за буфером. Бряк, останавливающий Jet-Lin и поставленный на макрос LED_OFF, показывает в Watch, что tx_rd_index = tx_wtr_index+1 (с учетом, естественно закольцовки буфера). Дальше идет, как и положено, полная ерунда :( Что тут не так? В п/п putBYTE() инкремент tx_counter0 идет самым последним, так что, вроде, ни о какой атомарности и необходимости запрещать прерывания речи не идет. Хотя ХЗ. HELP!!! PS. Вся оптимизация выключена. Даже не LOW, а NO. Хотя при LOW-уровне было тоже самое.
-
STR912 + CW 1.7
Dir ответил SimpleSoft тема в ARM
IARу RDI (Remote Debugger Interface) не надо. Это надо Keilу. Он через них с Segger-овским отладчиком J-link (JTAG) работает. IAR с этим отладчиком работает напрямую. Вся информация по J-link, в том числе и драйвера - у так нелюбимых буржуев http://www.segger.de/ Ключики к RDI - на FTP. Нагло содранные аналоги J-Link: JetLink, JetLink-5, MT-Link. Купить можно у MT-systems (Россия) или тут: http://rusar.net/ru/file/jetlink.html (Украина) Так что, ИМХО, понять буржуев можно. Они работают, а мы, по их мнению, норовим то, что ини разработали (т.е. потратили свое время и деньги) уворовать бесплатно. А люди они везде примерно одинаковы. Т.е. всякие есть... -
STR912 + CW 1.7
Dir ответил SimpleSoft тема в ARM
Не удержался. А Вы у них там не пробовали вопросы позадавть, прежде чем вот так огульно "не уважать"? Как на мой взгляд практически ничем, кроме языка, ни там, ни тут люди не отличаются. Тем более, что ничего нашего никто не предложил. Все только ихнее - "буржуйское". И ничего такого, чего бы не было на их официальных сайтах. -
Ну прямо таки "разработало" :/ Прокукарекала только, что хочет разработать. http://www.nxp.com/search/?query=LPC1000&industry_type= А что хочет и когда - ХЗ. Т.е. НИЧЕГО. Никаких анонсов, никаких инженерных образцов, никаких планов. Так что в полном пролете NXP с Cortex-M3. А на процах Luminary и STM уже серийные вещи выпускаются. Многие уже испытали их и готовятся к выпуску. А вы сидите, наблюдайте хвост уходящего поезда... PS. А чего ARM сам не поизводит - так он и раньше не выпускал железо. На лицензионных отчислениях жил и на software.
