реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Не работает прерывание USB, кто знает работу C8051F320
NikP
сообщение Dec 20 2012, 17:05
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-08-05
Пользователь №: 7 944



Решаем задачу:считать данные 4К из внешней микросхемы памяти и передать по USB. Читали в оперативку, перекладывали в фифо USB - работало, но медленно. Решили читать из внешней памяти сразу в фифо в прерывании, т.е. просто перенести код из main в модуль interrupt (с недольшими переделками). И передача пропала. Как будто при компиляции часть программы на Си проигнорировалось. Среда Cygnal IDE (старая, но добросовестно работает с небольшими объёмами (в принципе, нам больше и не надо). Что может быть: недостатки IDE, сам контроллер не любит больших программ в прерывании для USB, или всё же только программу смотреть? Повторю, что код пракически без изменения перенесли !
Go to the top of the page
 
+Quote Post
редактор
сообщение Dec 21 2012, 07:42
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315



WDT случайно вас не вырубает???
в main() оно может почаще крутилось и сбрасывалось, а когда в прерывание ушли, копирование стало много времени кушать, из-за этого main() не успевает собаку сбросить.
Как вариант не более.
Цитата
контроллер не любит больших программ в прерывании

А больших программ в прерывании мало кто любит. Часто вызываемое прерывание с очень длинной обработкой может подвесить любую отлаженную программу.


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
NikP
сообщение Dec 21 2012, 17:17
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-08-05
Пользователь №: 7 944



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. Как заставить компилятор и линкер всё собирать в рабочую программу?
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Dec 21 2012, 19:42
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(NikP @ Dec 21 2012, 19:17) *
Так вот, в начале модуля main определяю unsigned char FlagReady.

Не знаю актуально ли для 51-х...
Определите так:
Код
volatile unsigned char FlagReady.
Go to the top of the page
 
+Quote Post
редактор
сообщение Dec 24 2012, 06:05
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315




Цитата
Не знаю актуально ли для 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")
Ну и напоследок посмотреть ассемблер, к каким адресам обращается в прерывании и в фоне.
Со связкой кейл-силабс работал много, на такие ошибки не нарывался.


Сообщение отредактировал редактор - Dec 24 2012, 06:10


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
NikP
сообщение Dec 25 2012, 15:55
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-08-05
Пользователь №: 7 944



Попробовал определять переменную как посоветовали, но лучше не стало. Выкрутились так: определили функцию MemFull в модуле usb_isr , всё что было написано в обработке внешнего прерывания в main() перенесли в эту функцию, а в самой этой обработке в main() просто вызвали функцию MemFull. Кривовато, но работает.
Попутно возник ещё вопрос, над чем раньше не задумывался. У меня порт Р1 используется попеременно на вывод команд и на ввод данных . Возникло чувство, что после вывода читаю это же самое число число (на шине стоят буферы, позволяющие разделять ). Нужно ли "перенаправлять" направление работы порта : т.е. перед выводом конфигурировать на Out, а перед приёмом на In?
Go to the top of the page
 
+Quote Post
редактор
сообщение Dec 26 2012, 06:54
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315



В этих МК нет явного направления ввод-вывод. Чтобы правильно считывать значения с порта, достаточно записать в него все 1. Реальное чтение идет непосредственно с вывода МК. При этом если в порт-защелку записан 0, то при чтении скорее всего и будет считан 0 (если только внешний сигнал его не вытянет к +VDD :-) ). Ну и обратная ситуация более предпочтительна. Если в порт-защелку записана 1, то внешний сигнал низкого потенциала должен "просадить" выход, и это значение будет считано в МК.


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
NikP
сообщение Dec 26 2012, 16:52
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-08-05
Пользователь №: 7 944



А если к порту подключен мало потребляющий компонент , то при конфигурации с открытым стоком (PnMDOUT=0x00) может случиться, что притянуть к нулю не удасться или же будут ошибки при считывании? И другая ситуация: записали Pn=0xFF, на шине появилось 0x00, считали. Что останется в Pn? Если 0x00, то возникает неприятная ситуация, про которую Вы упоминали. Получается, что после каждого чтения надо перезаписывать Pn=0xFF. Или проблема решается конфигурацией (PnMDOUT=0xFF- push-pull)?
При этом возникает ещё вопрос. В даташите сказано, что при PnMDOUT=0x00 и записи Pn=0xFF соответствующие выводы будут high impedance. Однако если порт подключен к шине, где передаются данные между другими устройствами, то не будет ли открытый сток влиять на данные в шине , если входы внешних устройств мало потребляют?
Go to the top of the page
 
+Quote Post
Harbinger
сообщение Dec 27 2012, 04:17
Сообщение #9


старший лаборант
******

Группа: Свой
Сообщений: 2 702
Регистрация: 30-09-05
Из: ЮЗЖД
Пользователь №: 9 097



В данном случае нужно установить open drain режим с включенными "weak pull-up". Получится обычный для классических 51 квазидвунаправленный порт.
Цитата
то при конфигурации с открытым стоком (PnMDOUT=0x00) может случиться, что притянуть к нулю не удасться или же будут ошибки при считывании
Наоборот - встроенная подтяжка на открытом стоке ток единицы ограничивает.


--------------------
Китайская комплектация - европейское качество! ;)
Go to the top of the page
 
+Quote Post
редактор
сообщение Dec 28 2012, 05:59
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315



если сделать PnMDOUT=0, то вывод можно использовать только как вход уровни формируются внешним источником сигнала, Если же снаружи притянуть вывод к питанию, то он сможет функционировать и как выход.
Цитата
Получается, что после каждого чтения надо перезаписывать Pn=0xFF

При записи в Pn=0xFF значение остается в регистре-защелке, при чтении считывается непосредственно с вывода. Поэтому после чтения перезаписывать необязательно (значение в защелке не меняется). А вот при использовании команд чтение-модификация-запись может потребоваться.


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
NikP
сообщение Dec 29 2012, 05:36
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-08-05
Пользователь №: 7 944



Я так понял, что регистр-защёлка порта Pn и регистр Pn - это не одно и то же? Соответственно PnMDOUT - управляет режимом вывода данных, PnMDIN - режимом ввода, причём ввод и вывод идут по разным каналам к регистру Pn? Задаю вопрос, потому что пока нигде не нашёл простого и толкового описания. Везде пишут так, будто это всё само собой разумеется, без подробностей.
Go to the top of the page
 
+Quote Post
редактор
сообщение Jan 4 2013, 04:51
Сообщение #12


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315



Цитата
Я так понял, что регистр-защёлка порта 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)


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 15th June 2025 - 20:56
Рейтинг@Mail.ru


Страница сгенерированна за 0.01471 секунд с 7
ELECTRONIX ©2004-2016