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

 
 
> AT91SAM7S работа ADC совместно с PDC (прямой доступ к памяти)
kumle
сообщение Dec 7 2011, 12:17
Сообщение #1


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

Группа: Участник
Сообщений: 149
Регистрация: 15-12-09
Из: Москва
Пользователь №: 54 280



Очень плохо этот момент описан в даташите и примера в IAR как назло нет.
Пробовал сам сделать но не получилось. Может там есть какая то хитрость ?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Сергей Борщ
сообщение Dec 9 2011, 23:21
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (kumle @ Dec 9 2011, 13:38) *
Ура нашел ошибку, забыл вот это: PMC_EnablePeripheral(AT91C_ID_TC0);
То есть не включил питание периферии таймера TC0.


Как же оно без PDC работало? wacko.gif

QUOTE (kumle @ Dec 8 2011, 09:28) *
Хотя я первоначально сделал проектик для обычного АЦП, без PDC, и все отлично работало, но вот когда я его изменил для работы с PDC, "что-то сломалось" и прога даже в прерывание перестала входить.





--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
kumle
сообщение Dec 10 2011, 12:37
Сообщение #3


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

Группа: Участник
Сообщений: 149
Регистрация: 15-12-09
Из: Москва
Пользователь №: 54 280



Цитата(Сергей Борщ @ Dec 10 2011, 02:21) *
Как же оно без PDC работало? wacko.gif

Работало,так как там в инициализации ADC бит внешнего триггера был отключен, и каждое следующее преобразование вызывалось
вручную в главном цикле.

Все у меня все заработало (правда подмену буферов пока недоделал)
Инициализация
Код
//ADC init (with PDC)
  AT91C_BASE_ADC->ADC_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS; //канал PDC связанный с АЦП
  ADC_Initialize( AT91C_BASE_ADC,
                    AT91C_ID_ADC,
                    AT91C_ADC_TRGEN_EN,            //включаем работу АЦП от внешнего триггера
                    AT91C_ADC_TRGSEL_TIOA0,        //используем таймер TC0 в качестве внешнего триггера
                    AT91C_ADC_SLEEP_NORMAL_MODE,
                    AT91C_ADC_LOWRES_8_BIT,        //8-и битный результат
                    BOARD_MCK,                     //48000000
                    BOARD_ADC_FREQ,                //5000000
                    10,                            //stattup_time = 10us
                    1200);                         //sample & hold time = 1200ns
  

  
  ADC_EnableChannel(AT91C_BASE_ADC, ADC_NUM_3);
  IRQ_ConfigureIT(AT91C_ID_ADC, AT91C_AIC_PRIOR_LOWEST, ADC_IrqHandler);
  IRQ_EnableIT(AT91C_ID_ADC);

  
  

  //ADC_Ptr1 = ADC_Result;
  //AT91C_BASE_ADC->ADC_RPR = (unsigned long)ADC_Ptr1; // Receive Pointer Register
  //AT91C_BASE_ADC->ADC_RCR = 512; // Receive Counter Register
  //  Set receive pointer register for next transfer
  //AT91C_BASE_ADC->ADC_RNPR = (unsigned long)ADC_Ptr1;
  //  Set receive counter register for next transfer
  //AT91C_BASE_ADC->ADC_RNCR = 512;    
  

//timer TC0 init
  
// Enable TC0 peripheral clock
  PMC_EnablePeripheral(AT91C_ID_TC0);
  TC_Configure( AT91C_BASE_TC0,
                    (AT91C_TC_ASWTRG_CLEAR      |       //сброс TIOA от программного триггера
                     AT91C_TC_ACPC_CLEAR        |       //при достижении RС отрицательный фронт
                       AT91C_TC_ACPA_SET        |       //при достижении RA положительный фронт
                         AT91C_TC_LDRA_RISING   |       //загрузка RA при положительном фронте
                     AT91C_TC_WAVE              |       //выбран режим формирования импульсов
                     AT91C_TC_WAVESEL_UP_AUTO   |       //инкрементирование счетчика от 0 до RC
                     AT91C_TC_CLKS_TIMER_DIV1_CLOCK));  //выбираем источник синхросигнала MCK/2 = 24000000
  
  AT91C_BASE_TCB->TCB_TC0.TC_RC = 1000; //значение счетчика для окончания импульса
  AT91C_BASE_TCB->TCB_TC0.TC_RA = 990; //значение счетчика для начала импульса
  
AT91C_BASE_ADC->ADC_IER = AT91C_ADC_ENDRX; //enable interrupt on transfer complete
AT91C_BASE_ADC->ADC_PTCR = AT91C_PDC_RXTEN; //ADC start

TC_Start(AT91C_BASE_TC0);


Прерывание
Код
void ADC_IrqHandler(void)
{
  unsigned int status, i;
  unsigned short* ADC_Ptr2;

  status = AT91C_BASE_ADC->ADC_SR;

  //if (status & AT91C_ADC_ENDRX)
  //{//Both bit set when get the end of next buffer
  //  ADC_Ptr2 = ADC_Result;
  //  AT91C_BASE_ADC->ADC_RPR = (unsigned long) ADC_Ptr2; // Receive Pointer Register
  //  AT91C_BASE_ADC->ADC_RCR = AD_DATA_BUFFER_SIZE; // Receive Counter Register
  //  //AT91C_BASE_ADC->ADC_RNPR = (unsigned long)ADC_Ptr_Next; // Receive Next Pointer Register
  //  //AT91C_BASE_ADC->ADC_RNCR = AD_DATA_BUFFER_SIZE; // Receive Next Counter Register
  //  conv_done = 1;
  //}
  //else if((status & AT91C_ADC_ENDRX) == AT91C_ADC_ENDRX)
  //{//ENDRX bit set when reach the end of buffer.
  //  AT91C_BASE_ADC->ADC_RNCR = AD_DATA_BUFFER_SIZE; //Write the register to Clear STATUS register ENDRX bit ==>But don't clear the flag???
  //}

  conv_done = 1;
  AT91C_BASE_AIC->AIC_EOICR = 0;    
}
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 15:17
Рейтинг@Mail.ru


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