Проект посмотрел. Что можно сказать:
1. PLL настроена, ничего менять не надо.
2. Если хотите выжать предельную скорость, то в опциях оптимизации следует выбрать "speed", а не "size".
3. В данном случае п.2 скажется слабо, т.к. подобная "сборка" данных убьет любую производительность:
CODE
#define ADC1_B1 AT91C_PIO_PE17
#define ADC1_B2 AT91C_PIO_PE27
#define ADC1_B3 AT91C_PIO_PE26
#define ADC1_B4 AT91C_PIO_PE28
#define ADC1_B5 AT91C_PIO_PE21
#define ADC1_B6 AT91C_PIO_PE23
#define ADC1_B7 AT91C_PIO_PE15
#define ADC1_B8 AT91C_PIO_PE7
#define ADC1_B9 AT91C_PIO_PE24
#define ADC1_B10 AT91C_PIO_PE12
#define ADC1_B11 AT91C_PIO_PE9
#define ADC1_B12 AT91C_PIO_PE5
...
for(i = 0; i<1000; i++)
{
AT91C_BASE_PIOE->PIO_SODR=ADC_CLK;
if(AT91C_BASE_PIOE->PIO_PDSR & ADC1_B12){D12=1;}else{D12=0;}
if(AT91C_BASE_PIOE->PIO_PDSR & ADC1_B11){D11=1;}else{D11=0;}
if(AT91C_BASE_PIOE->PIO_PDSR & ADC1_B10){D10=1;}else{D10=0;}
if(AT91C_BASE_PIOE->PIO_PDSR & ADC1_B9){D9=1;}else{D9=0;}
if(AT91C_BASE_PIOE->PIO_PDSR & ADC1_B8){D8=1;}else{D8=0;}
if(AT91C_BASE_PIOE->PIO_PDSR & ADC1_B7){D7=1;}else{D7=0;}
if(AT91C_BASE_PIOE->PIO_PDSR & ADC1_B6){D6=1;}else{D6=0;}
if(AT91C_BASE_PIOE->PIO_PDSR & ADC1_B5){D5=1;}else{D5=0;}
if(AT91C_BASE_PIOE->PIO_PDSR & ADC1_B4){D4=1;}else{D4=0;}
if(AT91C_BASE_PIOE->PIO_PDSR & ADC1_B3){D3=1;}else{D3=0;}
if(AT91C_BASE_PIOE->PIO_PDSR & ADC1_B2){D2=1;}else{D2=0;}
if(AT91C_BASE_PIOE->PIO_PDSR & ADC1_B1){D1=1;}else{D1=0;}
DATA[i] = (
(D12<<11)
|((D11<<10)
|((D10<<9)
|((D9<<8)
|((D8<<7)
|((D7<<6)
|((D6<<5)
|((D5<<4)
|((D4<<3)
|((D3<<2)
|((D2<<1)
|((D1)
))))))))))));
AT91C_BASE_PIOE->PIO_CODR=ADC_CLK;
}
Что не так с этим кодом:
3.1. Каждое обращение к AT91C_BASE_PIOE->PIO_PDSR приводит к новому чтению порта. Считайте значение порта в переменную и работайте с ней:
Код
unsigned int x = AT91C_BASE_PIOE->PIO_PDSR;
if(x & ADC1_B12) ...
if(x & ADC1_B11) ...
3.2. Обилие локальных переменных только запутает компилятор. Будьте проще:
CODE
#define _ADC1_B1 17
#define _ADC1_B2 27
#define _ADC1_B3 26
#define _ADC1_B4 28
#define _ADC1_B5 21
#define _ADC1_B6 23
#define _ADC1_B7 15
#define _ADC1_B8 7
#define _ADC1_B9 24
#define _ADC1_B10 12
#define _ADC1_B11 9
#define _ADC1_B12 5
#define SWAP_BITS(x, s, d) ((((x) >> (s)) & 1) << (d))
for(i = 0; i<1000; i++)
{
unsigned int X;
AT91C_BASE_PIOE->PIO_SODR=ADC_CLK;
X = AT91C_BASE_PIOE->PIO_PDSR;
DATA[i] = SWAP_BITS(X, _ADC1_B1, 0) | SWAP_BITS(X, _ADC1_B2, 1) | SWAP_BITS(X, _ADC1_B3, 2) |
SWAP_BITS(X, _ADC1_B4, 3) | SWAP_BITS(X, _ADC1_B5, 4) | SWAP_BITS(X, _ADC1_B6, 5) |
SWAP_BITS(X, _ADC1_B7, 6) | SWAP_BITS(X, _ADC1_B8, 7) | SWAP_BITS(X, _ADC1_B9, 8) |
SWAP_BITS(X, _ADC1_B10, 9) | SWAP_BITS(X, _ADC1_B11, 10) | SWAP_BITS(X, _ADC1_B12, 11);
AT91C_BASE_PIOE->PIO_CODR=ADC_CLK;
}
Это дает не только более короткий текст программы (что тоже немаловажно), но и позволяет компилятору показать себя во всей красе.
3.3. Наиболее скоростным решением будет перекодировка при помощи заранее созданных таблиц. А еще лучше было бы развести шину данных АЦП по порядку, а не вразнобой.
4. Включите кэш. На данном этапе можно ограничиться кэшем инструкций (достаточно вызвать CP15_EnableIcache() в main).
Про кэш данных и MMU могу рассказать позже, но здесь лучше вникать в происходящее, а не просто копировать-вставлять.