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

 
 
> Расчёт скорости GPIO, какова максимальна скорость дрогонья и чтения?
bullit
сообщение Dec 22 2008, 11:23
Сообщение #1


пуля
****

Группа: Свой
Сообщений: 674
Регистрация: 10-05-06
Из: Уфа
Пользователь №: 16 959



День добрый всем!

Прошу помочь с расчётом.
Есть мк LPC2194. Необходимо проделать следующее
1) считать значение порта Р0 с 0 по 7 (8 линий)
2) с "0" на "1" переключить одну ногу(не из тех 8 линий)
3) снова считать значение (1)
4) значения по байтно записывать в память оперативную
Условия:
- и на всё это отводится не более 900 нс.
- цикл (1-4) повторяется раз в 2 мкс
- VPBDIV = 0 , т.е. деления частоты для переферии нет = частоте тактирования проца. (хотя не уверен)
- Кварц 10МГц, с ФАПЧ 60 МГц.

Можно ли успеть?
Думаю асм вставку придётся делать... + код в оперативу кидать...

К сожелению генератора под рукой нет... чтоб проверить.

А смысл в следующем: у ацп есть функция смена местами на выводах старшую и младшую байт, тем самым используя 8 линий сосчитать 16 бит. Для этого нужно "менять" уровень на определённой ноге.

Уж не знаю с какой скорость читать будет... но обычный "дрогатель":
Код
IO0SET = 0x40000000;
IO0CLR = 0x40000000;
Дал мне максимум 2,5 МГц при расположение кода в оперативе... Это максимум? (правда сейчас стоит проц 2294 и кварц 14,7456 МГц и ФАПЧ до 56 МГц должно разгонять)
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 29)
GetSmart
сообщение Dec 22 2008, 12:03
Сообщение #2


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Для IOPIN, IOSET, IOCLR запись в порт 7 тактов, чтение порта 8 тактов. В последних ревизиях (/01) работая через быстрые регистры периферии запись будет 2 такта, чтение 3 такта.

Вне зависимости откуда выполняется прога - из рамы или из флэша.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
bullit
сообщение Dec 22 2008, 12:40
Сообщение #3


пуля
****

Группа: Свой
Сообщений: 674
Регистрация: 10-05-06
Из: Уфа
Пользователь №: 16 959



МК именно 01. (только сейчас на олимексовской плате тренеруюсь H2294(старый, не 01))
А что за быстрые регистры? Они: IOPIN, IOSET, IOCLR?

А есть воопче смысл в рам кидать? и для каких операций?

Цитата
Вне зависимости откуда выполняется прога - из рамы или из флэша.
А в мануале прочёл:
Код
For the best performances, compile this code in the ARM mode and execute
from the on-chip SRAM memory.
и код:
ldr r0,=0xe01fc1a0 /*register address--enable fast port*/
mov r1,#0x1
str r1,[r0] /*enable fast port0*/
ldr r1,=0xffffffff
ldr r0,=0x3fffc000 /*direction of fast port0*/
str r1,[r0]
ldr r0,=0xe0028018 /*direction of slow port 1*/
str r1,[r0]
ldr r0,=0x3fffc018 /*FIO0SET -- fast port0 register*/
ldr r1,=0x3fffc01c /*FIO0CLR0 -- fast port0 register*/
ldr r2,=0x00001000 /*select fast port 0.12 for toggle*/
ldr r3,=0xE0028014 /*IO1SET -- slow port1 register*/
ldr r4,=0xE002801C /*IO1CLR -- slow port1 register*/
ldr r5,=0x00100000 /*select slow port 1.20 for toggle*/
/*Generate 2 pulses on the fast port*/
str r2,[r0]
str r2,[r1]
str r2,[r0]
str r2,[r1]
/*Generate 2 pulses on the slow port*/
str r5,[r3]
str r5,[r4]
str r5,[r3]
str r5,[r4]
loop: b loop
Получается есть эфект?

Т.е. регистры FIO0MASK FIO0PIN
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Dec 22 2008, 15:58
Сообщение #4


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(bullit @ Dec 22 2008, 17:23) *
...
Условия:
- и на всё это отводится не более 900 нс.
- цикл (1-4) повторяется раз в 2 мкс
- VPBDIV = 0 , т.е. деления частоты для переферии нет = частоте тактирования проца. (хотя не уверен)
- Кварц 10МГц, с ФАПЧ 60 МГц.

Можно ли успеть?
Думаю асм вставку придётся делать... + код в оперативу кидать...
Успеть можно. На асме не напрягаясь даже на старых чипах. Без использования рамы.

Цитата
Получается есть эфект?
Чуть быстрее предвыборка после перехода. Возможно 1-2 такта. Ещё быстрее выполняются команды типа:
Код
ldr r4,=0xE002801C
А линейный код из рамы и флэша исполняется одинаково быстро.

Кроме того, неясно, кроме чтения/записи в порт будет какая-то основная прога выполняться? Если да, то придётся делать через FIQ, но при этом появится джиттер.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
bullit
сообщение Dec 22 2008, 18:05
Сообщение #5


пуля
****

Группа: Свой
Сообщений: 674
Регистрация: 10-05-06
Из: Уфа
Пользователь №: 16 959



Цитата
Кроме того, неясно, кроме чтения/записи в порт будет какая-то основная прога выполняться? Если да, то придётся делать через FIQ, но при этом появится джиттер.

Да будет конечно...
Необходимо с 2 АЦП в течении порядка 2 мс, с переодичностью 2 мкс, опрашивать байты (8 линий). Кстати забыл совсем, что необходимо сначала с одного сосчитать 2 бита и потом с другого 2 бита. Между чтениями битов переключать "старший/младший"(byteswap помоему) и на всё это 900 нс. Т.е. на каждую ацп по 450 нс.
По программе: запускаем конвертирование (1 на ногу КОНВ) и ждём когда бизи в ноль упадёт... Как лучше всего "ждать бизи"? по прерыванию или по опросу? В это время не на что не отвлекаюсь... все прерывания стороние не интересуют.

А джитер будет больше 1 - 2 тактов?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 22 2008, 19:00
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(bullit @ Dec 22 2008, 21:05) *
Как лучше всего "ждать бизи"? по прерыванию или по опросу? В это время не на что не отвлекаюсь... все прерывания стороние не интересуют.

Однозначно по опросу.

Цитата(bullit @ Dec 22 2008, 21:05) *
А джитер будет больше 1 - 2 тактов?

Да, и значительно больше.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Dec 23 2008, 04:46
Сообщение #7


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(bullit @ Dec 23 2008, 00:05) *
Да будет конечно...
Необходимо с 2 АЦП в течении порядка 2 мс, с переодичностью 2 мкс, опрашивать байты (8 линий). Кстати забыл совсем, что необходимо сначала с одного сосчитать 2 бита и потом с другого 2 бита. Между чтениями битов переключать "старший/младший"(byteswap помоему) и на всё это 900 нс. Т.е. на каждую ацп по 450 нс.
По программе: запускаем конвертирование (1 на ногу КОНВ) и ждём когда бизи в ноль упадёт... Как лучше всего "ждать бизи"? по прерыванию или по опросу? В это время не на что не отвлекаюсь... все прерывания стороние не интересуют.?
А эти две миллисекунды нельзя полностью "посвятить" работе с АЦП? Было бы неплохо и очень надёжно. Ждать бизи лучше по тактам, если известно сколько оно длится. А если он длится больше 400 нс, то становится долго его ждать по опросу, и можно в лимит не уложиться.

Цитата
А джитер будет больше 1 - 2 тактов?
Намного больше. В среднем вход в FIQ будет задержан на 4 такта. Минимум 0 (или 1 - хз), максимум около 20, но недавно исследуя этот вопрос выше 17 я не смог получить, хотя использовал в коде самые длинные команды LDM и STM.

Сообщение отредактировал GetSmart - Dec 23 2008, 04:48


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
bullit
сообщение Dec 23 2008, 04:59
Сообщение #8


пуля
****

Группа: Свой
Сообщений: 674
Регистрация: 10-05-06
Из: Уфа
Пользователь №: 16 959



Цитата
А эти две миллисекунды нельзя полностью "посвятить" работе с АЦП? Было бы неплохо и очень надёжно.

Именно 2 мс буду отданы на АЦП...
Цитата
Ждать бизи лучше по тактам, если известно сколько оно длится. А если он длится больше 400 нс, то становится долго его ждать по опросу, и можно в лимит не уложиться

Т.к. конвертирование на двух АЦП я запускаю одновременно, то ждать буду на каком АЦП появится раньше, с того и начну опрос. Известно, что от запуска конвертирования до спада бизи в ноль как максимум 1100нс. Получается на опрос с двух АЦП 900нс максимум.
Думаю всё таки зациклить опрос бизи... делать паралельно нечего... жди приход да и всё...
Главное успеть за 900нс опросить оба АЦП.
А вот по поводу запуска конвертирования: лучше на таймер 2 мкс отсчёт сделать? потому как более надёжного способа я не вижу...
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Dec 23 2008, 05:14
Сообщение #9


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(bullit @ Dec 23 2008, 10:59) *
А вот по поводу запуска конвертирования: лучше на таймер 2 мкс отсчёт сделать? потому как более надёжного способа я не вижу...
Можно использовать функцию MATx.x на некоторых пинах проца. Она может инвертироваться строго по таймеру. Можно на ней сделать меандр 2 мкс. А в основной процедуре крутиться и ждать "бизи". Потом считывать значения. MATx.x не имеет джиттера и, как я понял, будет запускать оба АЦП одновременно.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 23 2008, 06:50
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(bullit @ Dec 23 2008, 07:59) *
Т.к. конвертирование на двух АЦП я запускаю одновременно, то ждать буду на каком АЦП появится раньше, с того и начну опрос.

Не советую: на этой нехитрой логике Вы потеряете времени больше, чем теоретически можно отыграть на разности времени преобразования. Смотрите оба BUSY вместе.
Go to the top of the page
 
+Quote Post
bullit
сообщение Dec 23 2008, 07:30
Сообщение #11


пуля
****

Группа: Свой
Сообщений: 674
Регистрация: 10-05-06
Из: Уфа
Пользователь №: 16 959



Чесно говоря не понял что Вы предлогаете.
Я считывать буду с обоих входов (бизи), а уж кто первый, тот и первый в опрос уйдёт.
Бизи активен нулём.
1) считали два бита
2) умножили на маску. если равен нуля то определяем какой из них, опятьже маской.
или:
1) опросили одну ногу, равна ли 0, то вперёд
2) опросили вторую, равна ли 0, то вперёд.

Ну вроде как 2 вариант быстрее...
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Dec 23 2008, 07:49
Сообщение #12


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(bullit @ Dec 23 2008, 13:30) *
...
Ну вроде как 2 вариант быстрее...

Быстрее будет первый вариант когда оба бита бизи висят на одном порте. Т.о. считали IOPIN, умножили на маску и... туды или сюды. Если оба в еденице, то декрементируйте счётчик опроса (для защиты от зависона). Если ещё не конец, то снова на чтение IOPIN. Если конец, то выход, АЦП зависло.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 23 2008, 08:23
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(bullit @ Dec 23 2008, 10:30) *
Ну вроде как 2 вариант быстрее...

Оба варианта медленные. Лучше так: считали 2 бита, если оба равны нулю, то начинаем считывать АЦП. Считываем всегда в одном порядке. Иначе потеряете вагон времени.
Go to the top of the page
 
+Quote Post
bullit
сообщение Dec 23 2008, 09:46
Сообщение #14


пуля
****

Группа: Свой
Сообщений: 674
Регистрация: 10-05-06
Из: Уфа
Пользователь №: 16 959



У меня обе АЦПшки висят на одном порту. АЦП имеет 3 состояние, управляемое CS и RD.
Заводить бизи с двух АЦП на одну ногу - значит не иметь информации с какого именно АЦП пришло. Использовать отдельные порты МК для каждого АЦП и накладно (трудно развести плату), да и портов нет. Потому как возможно часть свободных портов может уйти на другие нужды.

Наверое рисунок схемы будет Вам полезен. А то всплывают каждый раз новые подробности... файл бмп в архиве (с 2 Мб до 57 кб smile.gif ).


Цитата
Оба варианта медленные. Лучше так: считали 2 бита, если оба равны нулю, то начинаем считывать АЦП. Считываем всегда в одном порядке. Иначе потеряете вагон времени.
Получается что ждём пока оба не закончут конвертирование. В принципе вариант хорош тем, что шумы при работе МК не пройдут на другой АЦП, который в это время будет опрашиваться... А так только по одной линии - что в принципе снизит уровень "помех наводок". НО тогда надо иметь хороший запас во времени.

И еще хотел сросить про организацию сохранения результатов в памяти. Можно ли силами си/си++ организовать массив или что-то подобное.
И еще: как вы можите видеть: старший бит АЦП на "месте" младшего бита мк. Как можно "перевернуть" данные? Хотя это можно сделать и позднее на ПК. Сделано так с точки зрения разводки платы, нет перекрёсных цепей.
Прикрепленные файлы
Прикрепленный файл  ADC_and_uC.rar ( 57.75 килобайт ) Кол-во скачиваний: 24
 
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 23 2008, 09:56
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(bullit @ Dec 23 2008, 12:46) *
НО тогда надо иметь хороший запас во времени.

Вы же их запускаете одновременно, какой запас по времени? За время между сбросами BUSY разных АЦП Вы ровным счетом ничего не успеете сделать.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Dec 23 2008, 10:43
Сообщение #16


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(bullit @ Dec 23 2008, 15:46) *
Заводить бизи с двух АЦП на одну ногу - значит не иметь информации с какого именно АЦП пришло. Использовать отдельные порты МК для каждого АЦП и накладно (трудно развести плату), да и портов нет. Потому как возможно часть свободных портов может уйти на другие нужды.

Речь шла о том, чтобы весить бизи на два разных пина одного порта. Порт - это IOPIN0 или IOPIN1, или IOPINx. Порт содержит до 32 пинов, то есть бит. Хотя есть вариации у каждого проца, иногда всего пол порта наружу выходит, а иногда с дырками, но не суть. Два пина есть на любом порте. И их оба можно прочитать за одно чтение порта, сэкономив МНОГО времени.

ЗЫ. P0.14 зря задействовали. Он управляет бутлоадером. Его надо бы подтянуть к плюсу через 10к.

Сообщение отредактировал GetSmart - Dec 23 2008, 10:59


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
bullit
сообщение Dec 23 2008, 11:05
Сообщение #17


пуля
****

Группа: Свой
Сообщений: 674
Регистрация: 10-05-06
Из: Уфа
Пользователь №: 16 959



Я подумал на один пин smile.gif
Думаю поступлю именно как Вы указали в 12 посте. Опрос обоих ног "на ноль". А потом покомбенирую: или ждать пока оба в ноль, или пока один из двух в ноль не уйдет. В принципе зависеть будет от реакции.
Даже если я бутлоадер не юзаю?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Dec 23 2008, 11:33
Сообщение #18


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(bullit @ Dec 23 2008, 17:05) *
Даже если я бутлоадер не юзаю?

Если бутлоадер не используется, то P0.14 можно использовать, но только если есть гарантия, что на этом входе во время сброса не будет нуля. Например пин можно использовать для вывода данных из проца. Но подтягивать его к 3.3в обязательно.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
bullit
сообщение Feb 3 2009, 15:56
Сообщение #19


пуля
****

Группа: Свой
Сообщений: 674
Регистрация: 10-05-06
Из: Уфа
Пользователь №: 16 959



Хотел бы поднять тему, с целью получения совета, на вопрос в посте выше №14:
Цитата
И еще хотел сросить про организацию сохранения результатов в памяти. Можно ли силами си/си++ организовать массив или что-то подобное.

Програмирую а IARe.
Т.е. мне нужно в оперативу скинуть 2 бита с двух ацп, и таких измерений, т.е. 2 бита всего 1000. Но можно и меньше до 900. Памяти ОЗУ у меня в принципе нечем не занято. Я принимаю команду по SPI, даю одну команду на UART и принимаю данные с АЦП, а затем уже их по SPI сливаю. И потом опять всё повтаряю.
Вот как програмно реализовать массив?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Feb 3 2009, 16:48
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(bullit @ Feb 3 2009, 18:56) *
Вот как програмно реализовать массив?

Если у Вас проблемы с производительностью, то логичнее вообще не паковать, пока память позволяет.
Или работайте с АЦП пакетами, т.е. делаем линейно 4 измерения - укладываем в 1 байт.
Go to the top of the page
 
+Quote Post
bullit
сообщение Feb 3 2009, 18:15
Сообщение #21


пуля
****

Группа: Свой
Сообщений: 674
Регистрация: 10-05-06
Из: Уфа
Пользователь №: 16 959



1000 прощений!!!
не 2 бита, а 2 байта!!!
2 байта * 2 канала * 1000 = 4000 байт. Памяти в LPC2194 /01 16 кило SRAM, так что "места много"!
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Feb 3 2009, 18:25
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(bullit @ Feb 3 2009, 21:15) *
не 2 бита, а 2 байта!!!

Мне показалось, что у Вас 2 старших бита надо куда-то складывать. Бывает.

А уж с двумя байтами вообще никаких проблем не вижу. Сделайте массив short'ов, чтобы работало побыстрее.
Go to the top of the page
 
+Quote Post
bullit
сообщение Feb 3 2009, 18:35
Сообщение #23


пуля
****

Группа: Свой
Сообщений: 674
Регистрация: 10-05-06
Из: Уфа
Пользователь №: 16 959



К сожелению я с С/С++ пока на Вы. В дельфях еще более менее. Поэтому в виде кода можно увидеть?
И еще не понятно насчет быстрых GPIO, т.е. вместо обычных регистров GPIO использовать FGPIO регистры?
Типа d: array[0..1000;0..1]: short; ? smile.gif
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Feb 3 2009, 18:43
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(bullit @ Feb 3 2009, 21:35) *
Типа d: array[0..1000;0..1]: short; ? smile.gif

Типа:
Код
short d[1000];

Хотя не знаю, чем это может помочь - надо изучать язык.

Цитата(bullit @ Feb 3 2009, 21:35) *
И еще не понятно насчет быстрых GPIO, т.е. вместо обычных регистров GPIO использовать FGPIO регистры?

Да.
Go to the top of the page
 
+Quote Post
koyodza
сообщение Feb 3 2009, 20:44
Сообщение #25


Местный
***

Группа: Свой
Сообщений: 213
Регистрация: 28-02-07
Из: Киев
Пользователь №: 25 744



Вставлю свои 5 копеек:
я так понял, что эти два АЦП 8-разрядные? Тогда выбросьте LPC и возьмите STM32, там это всё на внутренних АЦП реализуемо. Выйдет проще, дешевле, ещё и в потреблении выиграть можно
Go to the top of the page
 
+Quote Post
bullit
сообщение Feb 4 2009, 04:32
Сообщение #26


пуля
****

Группа: Свой
Сообщений: 674
Регистрация: 10-05-06
Из: Уфа
Пользователь №: 16 959



Цитата
я так понял, что эти два АЦП 8-разрядные?

Нет! Это 14 битная АЦП, с паралельным выходом, с возможностью передачи по 8 линиям все 14 бит. Т.е. сначала младший потом старший.

А вариант с STM32 я уже смотрел. И Силабсы 06х серии тоже. НО остановился на этом варианте.
Go to the top of the page
 
+Quote Post
bullit
сообщение Feb 20 2009, 09:07
Сообщение #27


пуля
****

Группа: Свой
Сообщений: 674
Регистрация: 10-05-06
Из: Уфа
Пользователь №: 16 959



Делал тут я испытания...
и вот что у меня получилось:
CODE
// Настройка выводов для работы Первого АЦП
#define CONV_START1 FIO0CLR_bit.P0_29=1; // Старт Конвертирования АЦП
#define CONV_STOP1 FIO0SET_bit.P0_29=1; // Вернуть состояние входа "CONV" АЦП в нормальное состояние
#define START_READ1 FIO0CLR_bit.P0_30=1; // Разрешение на чтение ответа от АЦП
#define STOP_READ1 FIO0SET_bit.P0_30=1; // Запрет чтения ответа от АЦП
#define READ_LOWBYTE1 FIO1CLR_bit.P1_24=1; // Чтение МЛАДШЕГО байта
#define READ_HIGHBYTE1 FIO1SET_bit.P1_24=1; // Чтение старшего байта
#define BUSY_ADC1 FIO0PIN_bit.P0_16 // Чтение стостояния АЦП

// Настройка выводов для работы Второго АЦП
#define CONV_START2 FIO0CLR_bit.P0_10=1; // Старт Конвертирования АЦП
#define CONV_STOP2 FIO0SET_bit.P0_10=1; // Вернуть состояние входа "CONV" АЦП в нормальное состояние
#define START_READ2 FIO0CLR_bit.P0_11=1; // Разрешение на чтение ответа от АЦП
#define STOP_READ2 FIO0SET_bit.P0_11=1; // Запрет чтения ответа от АЦП
#define READ_LOWBYTE2 FIO0CLR_bit.P0_13=1; // Чтение МЛАДШЕГО байта
#define READ_HIGHBYTE2 FIO0SET_bit.P0_13=1; // Чтение старшего байта
#define BUSY_ADC2 FIO0PIN_bit.P0_12 // Чтение стостояния АЦП

// Настройка выводов для работы 2-ух АЦП
#define CONV_START FIO0CLR=0x20000400; // Старт Конвертирования АЦП
#define CONV_STOP FIO0SET=0x20000400; // Вернуть состояние входа "CONV" АЦП в нормальное состояние


// Усиление
#define GAIN1 FIO0SET = 0x1A000000; // Усиление 1(0) dB
#define GAIN2 FIO0SET = 0x18000000; FIO0CLR = 0x02000000; // Усиление 3 dB
#define GAIN3 FIO0SET = 0x12000000; FIO0CLR = 0x08000000; // Усиление 6 dB
#define GAIN4 FIO0SET = 0x10000000; FIO0CLR = 0x0A000000; // Усиление 9 dB
#define GAIN5 FIO0SET = 0x0A000000; FIO0CLR = 0x10000000; // Усиление 12 dB
#define GAIN6 FIO0SET = 0x08000000; FIO0CLR = 0x12000000; // Усиление 15 dB
#define GAIN7 FIO0SET = 0x02000000; FIO0CLR = 0x18000000; // Усиление 18 dB
#define GAIN8 FIO0CLR = 0x1A000000; // Усиление 21 dB


// Variable

u8 dataMB;
u8 dataSB;
u16 data[1000][2];


int main (void)
{
// System initialization, this will map the exception vectors.
LPC2294SystemInit(APBDIVISOR);
// initialization PLL
LPC2194PLLInit();
// Power Control
LPC2194PowerControl();
// First disable interrupts.
__disable_interrupt();
// Setup interrupt controller.
LPC2294InitVIC();
// Enable interrupts.
// __enable_interrupt();
// Set up peripheral registers.
LPC2294InitPIO();

// Установить усиление 5
GAIN5

CONV_STOP1
STOP_READ1
CONV_STOP2
STOP_READ2

for (;;){
// Loop forever.

for (u16 i = 0; i<1000; i++) {
CONV_START
CONV_STOP

while(BUSY_ADC1 == 1){}; //Ждем Busy

START_READ1
dataMB = FIO0PIN0;
READ_HIGHBYTE1
dataSB = FIO0PIN0;
data[i][0] = dataMB;
data[i][0] = data[i][0] | (dataSB << 8);

STOP_READ1
// Чтение со второго канала
START_READ2
dataMB = FIO0PIN0;
READ_HIGHBYTE2
dataSB = FIO0PIN0;
data[i][1] = dataMB;
data[i][1] = data[i][1] | (dataSB << 8);

// Конец
READ_LOWBYTE2
READ_LOWBYTE1
STOP_READ2

}

}
}// End Main

Так при максимальной оптимизации (в сторону скорости) время между стартами конвертирования 2,5 мкс. а мне надо 2 мкс. Время конвертирования 1,1 мкс. Т.е. на все остальные операции не более 0,9 мкс.
К сожелению с асмом тока знаком, но не программировал. Так бы на асме быстрее получилось бы. Или нет?
Или может из генерированного файла взять посмотреть?
Как можно ускорить? Может буфер сделать не двойным, а четверным? тогда можно будет избавиться от data[i][1] = data[i][1] | (dataSB << 8);
Причина редактирования: Уменьшение видимого размера цитаты исходника.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Feb 20 2009, 21:54
Сообщение #28


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(bullit @ Feb 20 2009, 15:07) *
Как можно ускорить? Может буфер сделать не двойным, а четверным? тогда можно будет избавиться от data[i][1] = data[i][1] | (dataSB << 8);

Вы походу не практиковались в написании оптимизированных прог даже на си. Замечания по проге:
1. CONV_START и CONV_STOP сделаны правильно, а все остальные обращения к FIO неправильно, т.к. при побитовом обращение к ним происходит ненужное чтение. Регистры FIO0SET и FIO0CLR аппаратно сделаны для ускорения работы с портами. В них лучше всего только писать и не читать (ну кроме регистра SET, там отдельная песня). Так что записав в регистр 0х00010000 будет сброшен (или установлен) 16-ый бит в порте, а другие биты не изменятся.
2. Цикл переделайте на обращение к массиву через указатель, с увеличивающимся адресом, а не через индекс по i. Лучше сделать dataMB и dataSB локальными, т.к. неизвестно с какой скоростью будет работать компилятор со статикой. Локальные переменные должны быть размером 32 бита для ускорения работы. Например так:
Код
u16 *ptr = (u16 *)&data[0];

u32  mb, sb;

for (u16 i = 0; i<1000; i++) {
CONV_START
CONV_STOP

// перенёс сюда для ускорения
READ_LOWBYTE2
READ_LOWBYTE1

while(BUSY_ADC1 == 1){};

START_READ1
mb = FIO0PIN0;
READ_HIGHBYTE1
sb = FIO0PIN0;
*ptr++ = (mb & 0xff) | (sb << 8);
STOP_READ1

START_READ2
mb = FIO0PIN0;
READ_HIGHBYTE2
sb = FIO0PIN0;
*ptr++ = (mb & 0xff) | (sb << 8);
STOP_READ2
}

Если это не поможет, то придётся делать на асме.

Сообщение отредактировал GetSmart - Feb 20 2009, 22:08
Причина редактирования: Уменьшение видимого размера цитаты исходника.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
bullit
сообщение Feb 21 2009, 04:39
Сообщение #29


пуля
****

Группа: Свой
Сообщений: 674
Регистрация: 10-05-06
Из: Уфа
Пользователь №: 16 959



Спасибо большое! Не думал что так много ошибок, + перенос переключение реад старший младший байт - как это я его не догадался перенести...
Да, оптимизацией кода я действительно никогда не занимался. Имею опыт работы только с Мегами от АVR. Оптимизация никогда не требовалась...

Во вторник буду проверять!

А где можно посмотреть в сторону оптимизации кода? т.е. какие операции выполняются с разной скоростью, ну и все подобное.... Потому как прямо такого не встречал!

PS C наступающим всех, с 23 февралем!
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Feb 21 2009, 07:42
Сообщение #30


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(bullit @ Feb 21 2009, 10:39) *
А где можно посмотреть в сторону оптимизации кода?

В листинге smile.gif
А длительность инструкций процессора ARM7 в файле arm7tdmi.pdf. Должен лежать где-нибудь в сети.

Думаю можно ещё ускорить перенеся CONV_START в конец, сразу после чтения обоих каналов
CODE

CONV_START
CONV_STOP

for (u16 i = 0; i<1000; i++) {
READ_LOWBYTE2
READ_LOWBYTE1

while(BUSY_ADC1 == 1){};

START_READ1
mb = FIO0PIN0;
READ_HIGHBYTE1
sb = FIO0PIN0;
*ptr++ = (mb & 0xff) | (sb << 8);
STOP_READ1

START_READ2
mb = FIO0PIN0;
READ_HIGHBYTE2
sb = FIO0PIN0;
*ptr++ = (mb & 0xff) | (sb << 8);
STOP_READ2
CONV_START
CONV_STOP
}


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 20:09
Рейтинг@Mail.ru


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