-
Постов
83 -
Зарегистрирован
-
Посещение
Весь контент luben111
-
"Общение"
luben111 ответил тема в Новости и обсуждения сайта и форума
Форум Electronix - ето не место для чата. Нет. -
Я согласен с цель DXF импорта - он для контура. То что предложили используется в Gerber файлы. Проблема в том что формы очень сложные и потом в Алтиуме нужно часто их легко редактировать.
-
Импортирование polygons в Алтиуме
luben111 опубликовал тема в Altium Designer, DXP, Protel
Здраствуйте, У меня проблема мучить уже несколько лет - как в Алтиуме импортировать полигонов которые потом можно сделать copper pour. Представьте у вас много фигур сложной формы в DXF файле. Мне нужно чтобы все фигуры были заполнены (copper pour). После импортирование DXF файла в Алтиуме все фигуры будут выглядит как tracks. Чтобы сделать формы плотные мне надо выбрать все траки одной формы и использовать Tools/ Convert/Create Polygon from selected primitives. Если фигуры довольно сложные процесс очень медленный. То же самое очень просто в ORCAD - при импорте все формы правильно держаться (при выборе одного трака вся формя селектируеться) и конверсия в copper pours проходить мигновенно. Попробовал тоже с использование plane в DXF файле - plane конвертируются в region в Алтиуме, проблема в том что plane имеет только 3 - 4 вершины. Буду очень благодарен если кто нибудь подскажет как можно сразу импортировать polygons в Алтиуме, речь идет об множество сложных форм (емкостные слайдеры или скрины). -
-
Универсальный ассемблер
luben111 ответил luben111 тема в Все остальные микроконтроллеры
К сожалению TASM не подходит к мою 16 bit архитектуру команд - в таблице нужно указать все возможные команды (например ADD R0, R0; ADD R1, R0; ADD R2, R0.... ADD R15, R0.... ADD R15,R15 - 256 команды только для ADD). ИМНО лучше пользоваться SWITCH (где в коде каждая команда имеет программная секция). -
Универсальный ассемблер
luben111 ответил luben111 тема в Все остальные микроконтроллеры
Спасибо всем, Я тоже нашел что то - http://www.drdobbs.com/embedded/222600279 Конечно универсального ассемблера не может существовать, я был рад иметь что то довольно близкое к конечному продукту. -
Универсальный ассемблер
luben111 опубликовал тема в Все остальные микроконтроллеры
Здравствуйте, У меня такая задача - написать на C++. C# или Delphi макроассемблер для нестандартного микроконтроллера (который еще не в продаже). Контроллер имеет ~90 комманд и 16 бит архитектуры. Конечно самый легкий путь - взять кокой то универсальный ассемблер и написать только таблицы инструкции. Буду благодарен для идеи. -
Конечно - решение проблемы точно как вы уже писали! Большое спасибо за идею! Я прочитал все что написали и только добавил почему надо так сделать. Всегда лучше знать почему что то происходить.
-
К сожалению проблема хуже чем вам кажется. Я говорил с гуру в области Atmel и теперь все понятно как это происходить и как можно обмануть: 1. Tiny88 может принимать SLA в Power sleep моде но не может принимать и посылать данные в Power sleep моде !! Причина об этом очень долго объяснить но находиться в внутренний state machine. 2. Так если SLA уже принять не надо входить в Power sleep в никаком случае - это может сломать коммуникации. Можно использовать только Idle Sleep 3. Проблема можно увидеть в практически каждом камне Atmel !!!! То что Power Down Sleep не используется так часто и то что обычно в Power Down sleep принимается SLA в 99.9% делает эту проблему трудной для отыскания. Решение - следить за SLA и если он принять идти в Idle sleep. Нужно сделать хорошая state machine в TWI прерывание. Я сделал все это и проблема ушла навсегда!
-
Я забыл сказать что проблема не в просыпания! Просто модуль перестает работать - как бы SCL отключен от модуля. Но буду попробавать ваши идеи! Спасибо за идеи!
-
Осциллограммы показывают что TWI Tiny88 при введение в sleep моде просто перестает действовать (если SLA уже принять). Так если Tiny88 посылает данные и SDA находится в 0 в момент введения в sleep моде то SDA застрянет в 0 и не будет меняться из за SCL. После окончания sleep SDA линия будет навсегда в 0 и только reset TWI может восстанавить коммуникации. Решение (если можно называть это решение) - если SLA уже принять не идти в sleep. Я ну буду удивлен если проблема находится не только в Tiny88 но и в другие контроллеры is Tiny или AtMega.
-
Здраствуйте, Я нашел что Tiny88 держится непослушно в TWI slave mode и тянет линия SDA к GND на неопределенное время после просыпание. Сценарий возникновение проблемы такой: 1. Tiny88 в TWI slave моде, имеет адрес SLA и прерывание только на TWI. Чип работает на внутренним осцилляторе 8MHz. 2. Host посылает SLA+R и чип успешно принимает SLA+R в прерывание. Host начинает читать следующий байт. 3. В то время когда чтения байта происходить (после выполнения прерывании для SLA+R) Tiny88 разрешает прерывание из WDT и уходит в deep sleep mode - все модули с исключение TWI отключенный из питания из PRR. Просыпание возможно только из TWI или WDT. 4. Когда последний бит уже послан Tiny88 находиться в deep sleep моде. 5. Здесь происходить что то неладное (я в процесс уточнения что конкретно происходить )- чип просыпается но держит линия SDA к GND. Только установка и сброс TWSTO или забрана/разрешения TWEN может восстановить SDA. Вопрос - кто то встречал уже такое поведение Tiny88? Как можно обманут процессора и избежать задержка SDA?
-
Спасибо - сейчас работает!
-
Оптимизация кода не принимает во внимание ISR
luben111 опубликовал тема в MCS51, AVR, PIC, STM8, 8bit
У меня проблема такая возникла с компилятором IAR 5.3 для AVR, камень Tiny88 - оптимизатор не 'видит' что переменная можно менять в прерывание. В результате код не правильно оптимизирован - MoreCode() удален так как while (flagWasI2C != 1) всегда true. Код на уровне main() в MainCode.c модуле: extern uint8_t flagWasI2C; void main(void) { ....... Protect(); flagWasI2C = 0; UnProtect(); do // wait for I2C communication { __watchdog_reset(); } while (flagWasI2C != 1); MoreCode(); // this section is not compiled } Protect() - CLI, UnProtect - SEI и в перерывание для TWI (находиться в I2C.c модуле): uint8_t flagWasI2C; #pragma vector=TWI_vect __interrupt void TWI_ISR( void ) { DoSomething(); flagWasI2C = 1; } При компиляции с максимальной оптимизации можно увидеть что MoreCode() просто удален - переменная flagWasI2C установлена в нуль и в main() не видно что она можно меняться в TWI ISR. Как можно обмануть компилятор чтобы он не удалял MoreCode()? Нашел что если поставит операция с регистрами и как то оптимизатор начинает правилно 'смотреть' и код работает: extern uint8_t flagWasI2C; void main(void) { ....... Protect(); flagWasI2C = 0; UnProtect(); DDRA = 12; // и MoreCode() уже присуствует!!! do // wait for I2C communication { __watchdog_reset(); } while (flagWasI2C != 1); MoreCode(); // this section is not compiled } -
Странное поведение JMP
luben111 ответил luben111 тема в Программирование
Программа сейчас работает, но возникла вот такая проблема поддержки и структурной чистотой - адрес установлен в линкере и он не виден из компилятора. Если хочу использовать то же значение 0200 для установки других параметров мне надо заново установит в файле параметр (например #define SIZE_AREA 0x200). Поддержка кода усложнена и возможность сделать ошибки больше потому что надо менять данные на 2 места . Я попробовал #define SIZE_AREA 0x200 ..... ((void (*)())SIZE_AREA)(); Все работает прекрасно но нахожу в дизассемблере LDI R30, 00 LDI R31, 02 IJMP В итоге 4 байта больше! Подскажите как вернут добрый RJMP на месте и вместе с тем установить адрес SIZE_AREA внутри С файла - т.е. был доступен внутри С файла для дополнительные операции как __root __flash uint16_t MARKER @ (SIZE_AREA-2) = 0x434C; -
Странное поведение JMP
luben111 ответил luben111 тема в Программирование
Спасибо Сергей,! Сейчас вижу RJMP и все работает как надо. Видно что у вас большой опыт в программирование! -
Странное поведение JMP
luben111 ответил luben111 тема в Программирование
Мне надо было сделать JMP к адресу 0200. Код такой: /*---------------------------------------------------------------------------*/ __C_task void main(void) /* the main code is here */ /*---------------------------------------------------------------------------*/ { Initialize(); if (testCode == 0) /* bad code */ { ((void (*)())0x200)(); /* jump to the fixed address (!!!! USES ICALL!!!!)*/ } if (busReceiveByte() == seq1) { if (busReceiveByte() == seq2) { loader(); } } ((void (*)())0x200)(); /*(!!!! USES IJMP!!!!) */ } Но на дизассемблере находил что первый JMP \"сделан\" из ICALL а второй из IJMP, что то вроде: LDI R30, 0x00 LDI R31, 0x02 ICALL LDI R30, 0x00 LDI R31, 0x02 IJMP Мне хотелось как нибудь чтобы компилятор поставил RJMP и не мучил меня с IJMP. Конечно я совсем не согласен когда он огорчил меня с ICALL. Слово goto точно подходить для меня но как установить этикет по адресу 0x200? Камень - Tiny88. -
Странное поведение JMP
luben111 опубликовал тема в Программирование
Мне надо было сделать JMP к адресу 0200. Код такой: /*---------------------------------------------------------------------------*/ __C_task void main(void) /* the main code is here */ /*---------------------------------------------------------------------------*/ { Initialize(); if (testCode == 0) /* bad code */ { ((void (*)())0x200)(); /* jump to the fixed address (!!!! USES ICALL!!!!)*/ } if (busReceiveByte() == seq1) { if (busReceiveByte() == seq2) { loader(); } } ((void (*)())0x200)(); /*(!!!! USES IJMP!!!!) */ } Но на дизассемблере находил что первый JMP \"сделан\" из ICALL а второй из IJMP, что то вроде: LDI R30, 0x00 LDI R31, 0x02 ICALL LDI R30, 0x00 LDI R31, 0x02 IJMP Мне хотелось как нибудь чтобы компилятор поставил RJMP и не мучил меня с IJMP. Конечно я совсем не согласен когда он огорчил меня с ICALL. Слово goto точно подходить для меня но как установить этикет по адресу 0x200? -
Спасибо - это точно что хотел узнать. Вопрос - а что будет если использовать #pragma inline=forced перед fooxx(). Мне все таки не хочется вызывать процедуру где можно и не вызывать (каждый CALL может сопровождаться громоздким сегментом сохранения - восстановления регистров).
-
Tiny88 не имеет UART (но имеет хороший I2C) . Конечно можно сделать софт UART но проблема в том что на I2C шине есть и другие устройства так что надо быть осторожным. Загрузка нового софта делает какой то DSP контроллер с Linux OS. Разстояние между чипа и DSP контроллера не больше 70мм
-
Если установка PORTA DDRA произходить в цикле разница получается доволно большая и заметная. LDI R0, 15; // установка значения LDI R1, 61; LDI R2, 45; LDI R3, 1; .... for (uint16_t ii = 0; ii < 1000; ii++) { OUT DDRA, R0; OUT PORTC, R1; OUT DDRA, R2; OUT DDRB, R3; } намного быстрее (1000 clocks!!!!) чем : for (uint16_t ii = 0; ii < 1000; ii++) { LDI R0, 15; OUT DDRA, R0; LDI R0, 61; OUT PORTC, R0; LDI R0, 45; OUT DDRA, R0; LDI R0, 1; OUT DDRB, R0; }
-
Если идет слово об программирование процессора при разработке проекта я не имею проблемы - я имею JTAG-ICEMkII , AVROne и т.д. Bootloader нужен для апгрейда софта, когда чип уже работает в каком то устройстве где я не могу пользовать внешние компоненты для программирование. И связь с процессором только через I2C
-
Конечно компилятор надо инициализировать переменные, но я говорю об что то совершенно другое - компилятор видит что переменная все время имеет одна и та же стойность и делает что то неладное - вместо чтобы загрузит регистр и хранит этот регистр только для этой переменной он использует один и тот регистр для все переменные var1..var4 - перед каждой установке PORTA, DDRA и т.д. он загружает константу в регистр и только потом загружает PORTA, DDRA. В итоге это одна инструкция больше!
-
Не тайна что через использование ключевое слово register можно указать компилятору поставит переменную в регистр. В проекте можно тоже указать компилятору не использовать определенные регистры и потом создать глобальные регистровые переменные. Вопрос идет об локальных переменных в какой то процедуре - если в процедуре много переменных оптимизация часто не принимает во внимание мои инструкции поставит переменные в регистры. Например: register uint8_t var1, var2, var3, var4; // переменные в регистры var1 = 15; // установка значения var2 = 61; var3 = 45; var4 = 1; DDRA = var1; PORTC = var2; DDRA = var3; DDRB = var4; После компиляции часто можно увидеть что в листинге находиться что то вроде: // DDRA = var1; 0000017A E07F LDI R23, 15 // load R23 with 15 0000017C B97D OUT 0x0D, R23 // out to DDRA вместо ожидаемого: // DDRA = var1; 0000017C B97D OUT 0x0D, R21 // out directly var1 to DDRA Как можно обмануть компилятору и поставить локальные переменные воистину в регистры (без использование глобальных переменных в регистров).
-
Мне надо сделать bootloader для Tiny88. Задача не легка - процессор не имеет встроенные bootloader фюзы для защиты памяти и не имеет UART - только I2C. Буду благодарен за все идеил