NikP 0 20 декабря, 2012 Опубликовано 20 декабря, 2012 · Жалоба Решаем задачу:считать данные 4К из внешней микросхемы памяти и передать по USB. Читали в оперативку, перекладывали в фифо USB - работало, но медленно. Решили читать из внешней памяти сразу в фифо в прерывании, т.е. просто перенести код из main в модуль interrupt (с недольшими переделками). И передача пропала. Как будто при компиляции часть программы на Си проигнорировалось. Среда Cygnal IDE (старая, но добросовестно работает с небольшими объёмами (в принципе, нам больше и не надо). Что может быть: недостатки IDE, сам контроллер не любит больших программ в прерывании для USB, или всё же только программу смотреть? Повторю, что код пракически без изменения перенесли ! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Edit2007 3 21 декабря, 2012 Опубликовано 21 декабря, 2012 · Жалоба WDT случайно вас не вырубает??? в main() оно может почаще крутилось и сбрасывалось, а когда в прерывание ушли, копирование стало много времени кушать, из-за этого main() не успевает собаку сбросить. Как вариант не более. контроллер не любит больших программ в прерывании А больших программ в прерывании мало кто любит. Часто вызываемое прерывание с очень длинной обработкой может подвесить любую отлаженную программу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NikP 0 21 декабря, 2012 Опубликовано 21 декабря, 2012 · Жалоба WDT точно ни при чём, я его выключаю сразу при инициализации. Поработал сегодня с программой через отладчик, заметил следующие заморочки и понял, что вопрос должен относиться скорее к пограммированию или работе со средой Cygnal IDE. Я уж не буду его формулировать в другом разделе форума, может здесь кто ответит. Программа сделана из нескольких модулей . В main забито внешнее прерывание по уровню. В этом прерывании выставляется флаг готовности микросхемы внешней памяти к считыванию (присвоение FlagReady=1), в прерывании от USB идёт анализ флага if ( FlagReady) и передача накопленных данных. Передача закончилась - FlagReady=0, и новый опрос системы. Так вот, в начале модуля main определяю unsigned char FlagReady. Модуль usb_isr тоже просит определить FlagReady. Пожалуйста: делаю unsigned char FlagReady. Система даёт ошибку многократное определение. Меняю в main - extern FlagReady. Компилируется без ошибок, при работе в прерывание модуля main о готовности к передаче заходим, а присвоения FlagReady=1 не происходит(видно в отладчике). Делаю наоборот: в main -unsigned char FlagReady, в usb_isr -extern FlagReady. Теперь в прерывании о готовности к передаче присвоение есть, но в прерывании usb_isr строка if ( FlagReady) игнорируется, отладчик показал, что теперь из этого модуля FlagReady видится как 0. Как заставить компилятор и линкер всё собирать в рабочую программу? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 21 декабря, 2012 Опубликовано 21 декабря, 2012 · Жалоба Так вот, в начале модуля main определяю unsigned char FlagReady. Не знаю актуально ли для 51-х... Определите так: volatile unsigned char FlagReady. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Edit2007 3 24 декабря, 2012 Опубликовано 24 декабря, 2012 (изменено) · Жалоба Не знаю актуально ли для 51-х... Определите так: Код volatile unsigned char FlagReady. для 51 актуально. Компилируется без ошибок... А что насчет варнигов? Если в IDE используете компилятор от KEIL то могу посоветовать следующее Опции компилятора для модулей не отличаются (модели памяти)?. Если модели памяти указаны разные, то необходимо дополнительно указать тип памяти, например data unsigned char FlagReady; ... extern data unsigned char FlagReady; Если используете переключение банков в прерывании, то в опциях компилятора должно быть установлена галка "Don`t use absolute register access". (Это в Keil, в вашей среде скорее всего опция компилятора "NOAREGS") Ну и напоследок посмотреть ассемблер, к каким адресам обращается в прерывании и в фоне. Со связкой кейл-силабс работал много, на такие ошибки не нарывался. Изменено 24 декабря, 2012 пользователем редактор Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NikP 0 25 декабря, 2012 Опубликовано 25 декабря, 2012 · Жалоба Попробовал определять переменную как посоветовали, но лучше не стало. Выкрутились так: определили функцию MemFull в модуле usb_isr , всё что было написано в обработке внешнего прерывания в main() перенесли в эту функцию, а в самой этой обработке в main() просто вызвали функцию MemFull. Кривовато, но работает. Попутно возник ещё вопрос, над чем раньше не задумывался. У меня порт Р1 используется попеременно на вывод команд и на ввод данных . Возникло чувство, что после вывода читаю это же самое число число (на шине стоят буферы, позволяющие разделять ). Нужно ли "перенаправлять" направление работы порта : т.е. перед выводом конфигурировать на Out, а перед приёмом на In? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Edit2007 3 26 декабря, 2012 Опубликовано 26 декабря, 2012 · Жалоба В этих МК нет явного направления ввод-вывод. Чтобы правильно считывать значения с порта, достаточно записать в него все 1. Реальное чтение идет непосредственно с вывода МК. При этом если в порт-защелку записан 0, то при чтении скорее всего и будет считан 0 (если только внешний сигнал его не вытянет к +VDD :-) ). Ну и обратная ситуация более предпочтительна. Если в порт-защелку записана 1, то внешний сигнал низкого потенциала должен "просадить" выход, и это значение будет считано в МК. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NikP 0 26 декабря, 2012 Опубликовано 26 декабря, 2012 · Жалоба А если к порту подключен мало потребляющий компонент , то при конфигурации с открытым стоком (PnMDOUT=0x00) может случиться, что притянуть к нулю не удасться или же будут ошибки при считывании? И другая ситуация: записали Pn=0xFF, на шине появилось 0x00, считали. Что останется в Pn? Если 0x00, то возникает неприятная ситуация, про которую Вы упоминали. Получается, что после каждого чтения надо перезаписывать Pn=0xFF. Или проблема решается конфигурацией (PnMDOUT=0xFF- push-pull)? При этом возникает ещё вопрос. В даташите сказано, что при PnMDOUT=0x00 и записи Pn=0xFF соответствующие выводы будут high impedance. Однако если порт подключен к шине, где передаются данные между другими устройствами, то не будет ли открытый сток влиять на данные в шине , если входы внешних устройств мало потребляют? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Harbinger 10 27 декабря, 2012 Опубликовано 27 декабря, 2012 · Жалоба В данном случае нужно установить open drain режим с включенными "weak pull-up". Получится обычный для классических 51 квазидвунаправленный порт. то при конфигурации с открытым стоком (PnMDOUT=0x00) может случиться, что притянуть к нулю не удасться или же будут ошибки при считыванииНаоборот - встроенная подтяжка на открытом стоке ток единицы ограничивает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Edit2007 3 28 декабря, 2012 Опубликовано 28 декабря, 2012 · Жалоба если сделать PnMDOUT=0, то вывод можно использовать только как вход уровни формируются внешним источником сигнала, Если же снаружи притянуть вывод к питанию, то он сможет функционировать и как выход. Получается, что после каждого чтения надо перезаписывать Pn=0xFF При записи в Pn=0xFF значение остается в регистре-защелке, при чтении считывается непосредственно с вывода. Поэтому после чтения перезаписывать необязательно (значение в защелке не меняется). А вот при использовании команд чтение-модификация-запись может потребоваться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NikP 0 29 декабря, 2012 Опубликовано 29 декабря, 2012 · Жалоба Я так понял, что регистр-защёлка порта Pn и регистр Pn - это не одно и то же? Соответственно PnMDOUT - управляет режимом вывода данных, PnMDIN - режимом ввода, причём ввод и вывод идут по разным каналам к регистру Pn? Задаю вопрос, потому что пока нигде не нашёл простого и толкового описания. Везде пишут так, будто это всё само собой разумеется, без подробностей. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Edit2007 3 4 января, 2013 Опубликовано 4 января, 2013 · Жалоба Я так понял, что регистр-защёлка порта Pn и регистр Pn - это не одно и то же? Для аналогии приведу регистр SBUF0. Один адрес для чтения и записи, но физически регистры разные. Чтение производится из одного регистра, запись в другой. Примерно то же самое с портами ввода-вывода. Регистр-защелка только для записи (в качестве буфера порта ввода-вывода). Чтение осуществяется непосредственно с пина (он же выход регистра-защелки) Такая схемотехника была заложена в классический MCS-51 Intel-ом. Только не спрашивайте зачем именно так. Все остальные производители поддерживают это для совместимости. Некоторые добавляют свои навороты (как Силабс например). Задаю вопрос, потому что пока нигде не нашёл простого и толкового описания. Везде пишут так, будто это всё само собой разумеется, без подробностей. DataShit на C8051F32X v1.4 стр.132 П 14.3 When writing to a Port, the value written to the SFR is latched to maintain the output data value at each pin. When reading, the logic levels of the Port's input pins are returned regardless of the XBRn settings (i.e., even when the pin is assigned to another signal by the Crossbar, the Port register can always read its corresponding Port I/O pin). The exception to this is the execution of the read-modify-write instructions. Ну и схема порта на стр.127 дает представление о внутренней организации (линии port-input, port-output) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться