|
Расчёт скорости GPIO, какова максимальна скорость дрогонья и чтения? |
|
|
|
Dec 23 2008, 10:43
|
.
     
Группа: Участник
Сообщений: 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
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Feb 3 2009, 15:56
|

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

|
Хотел бы поднять тему, с целью получения совета, на вопрос в посте выше №14: Цитата И еще хотел сросить про организацию сохранения результатов в памяти. Можно ли силами си/си++ организовать массив или что-то подобное. Програмирую а IARe. Т.е. мне нужно в оперативу скинуть 2 бита с двух ацп, и таких измерений, т.е. 2 бита всего 1000. Но можно и меньше до 900. Памяти ОЗУ у меня в принципе нечем не занято. Я принимаю команду по SPI, даю одну команду на UART и принимаю данные с АЦП, а затем уже их по SPI сливаю. И потом опять всё повтаряю. Вот как програмно реализовать массив?
|
|
|
|
|
Feb 3 2009, 18:43
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(bullit @ Feb 3 2009, 21:35)  Типа d: array[0..1000;0..1]: short; ?  Типа: Код short d[1000]; Хотя не знаю, чем это может помочь - надо изучать язык. Цитата(bullit @ Feb 3 2009, 21:35)  И еще не понятно насчет быстрых GPIO, т.е. вместо обычных регистров GPIO использовать FGPIO регистры? Да.
|
|
|
|
|
Feb 4 2009, 04:32
|

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

|
Цитата я так понял, что эти два АЦП 8-разрядные? Нет! Это 14 битная АЦП, с паралельным выходом, с возможностью передачи по 8 линиям все 14 бит. Т.е. сначала младший потом старший. А вариант с STM32 я уже смотрел. И Силабсы 06х серии тоже. НО остановился на этом варианте.
|
|
|
|
|
Feb 20 2009, 09:07
|

пуля
   
Группа: Свой
Сообщений: 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);
Причина редактирования: Уменьшение видимого размера цитаты исходника.
|
|
|
|
|
Feb 20 2009, 21:54
|
.
     
Группа: Участник
Сообщений: 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
Причина редактирования: Уменьшение видимого размера цитаты исходника.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Feb 21 2009, 07:42
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(bullit @ Feb 21 2009, 10:39)  А где можно посмотреть в сторону оптимизации кода? В листинге  А длительность инструкций процессора 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 }
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|