|
AT91SAM7xxxx, ADC, 2 канала и PDC |
|
|
|
Dec 14 2012, 13:10
|

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

|
QUOTE (hd44780 @ Dec 14 2012, 14:21)  Народ, я не понял, зачем регистры RNPR (Receive Next Pointer Register) и RNCR (Receive Next Counter Register)? Типа, если я не перепрограммирую RPR/RCR, он сам на те кинется? Типа да. Точнее, в прерывании программировать надо именно RNPR/RNCR, а в RPR/RCR значения из RNPR/RNCR протолкнет DMA контроллер. RPR/RCR программируются только перед запуском процесса.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 14 2012, 18:46
|

Профессионал
    
Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980

|
Написал так: 1. Инициализация АЦП Код void ConfigureAdc(void) { dword shtim, startup, prescal, trgSel; AT91C_BASE_PMC->PMC_PCER = (1UL << AT91C_ID_ADC); // разрешить тактовую для ADC AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST; // reset ADC shtim=8; startup=0x0F; prescal=0x02; trgSel=1; // Запуск по TIOA1 (TC1)
ADC_CfgModeReg (AT91C_BASE_ADC, (shtim << 24) | (startup << 16) | (prescal << 8) | AT91C_ADC_SLEEP_NORMAL_MODE | AT91C_ADC_LOWRES_8_BIT | (trgSel << 1) | AT91C_ADC_TRGEN_EN);
// выкл все каналы AT91C_BASE_ADC->ADC_CHDR = 0xFF; // Включить канал 6, 7 AT91C_BASE_ADC->ADC_CHER = (1 << ADC_CHANNEL_LEFT) | (1 << ADC_CHANNEL_RIGHT); // Разрешить прерывания каналов 6 и 7 в ADC AT91C_BASE_ADC->ADC_IER = ( 1 << ADC_CHANNEL_LEFT ) | ( 1 << ADC_CHANNEL_RIGHT );
// Установка прерывания ADC IRQ_ConfigureIT ( AT91C_ID_ADC, 6, ADC_IrqHandler ); // Set AIC_IECR IRQ_EnableIT(AT91C_ID_ADC); //////////////////////////////////////////////////////////////////////////////// // PDC // Буфер данных AT91C_BASE_ADC->ADC_RPR = (dword)ADCbuf; AT91C_BASE_ADC->ADC_RNPR = (dword)ADCbuf; // Set receive counter register (number of transfers) AT91C_BASE_ADC->ADC_RCR = sizeof ( ADCbuf ); AT91C_BASE_ADC->ADC_RNCR = sizeof ( ADCbuf );
// ENDRX - End of receive buffer interrupt enable (когда регистр ADC_RCR досигает нуля) AT91C_BASE_ADC->ADC_IER = AT91C_ADC_ENDRX;
// Конфигурирование TC1 на переключение TIOA1 23.81kHz ConfigureTc1 ( ); } // ConfigureAdc Всё, что до комментария PDC - рабочее на 100%. Без PDC работает нормально. 2. Запуск: Код void StartConversion ( void ) { // Буфер данных AT91C_BASE_ADC->ADC_RCR = sizeof ( ADCbuf ); AT91C_BASE_ADC->ADC_RNCR = sizeof ( ADCbuf );
// Set receive counter register (number of transfers) AT91C_BASE_ADC->ADC_RCR = sizeof ( ADCbuf ); AT91C_BASE_ADC->ADC_RNCR = sizeof ( ADCbuf );
// Enable PDC receiver requests, disable transmitter requests AT91C_BASE_ADC->ADC_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTDIS; // запуск ТС1 AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG | AT91C_TC_CLKEN; } // StartConversion До PDC здесь был только запуск TC1. Инициализация проходит нормально, а после вызова StartConversion всё наглухо виснет. Даже прерываний от АЦП нету. Проверялось через DBGU. В чём я ошибся?
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
Dec 15 2012, 09:02
|

Профессионал
    
Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980

|
Цитата(RabidRabbit @ Dec 15 2012, 09:35)  Я немного не понимаю, инициализация указателей для PDC происходит только в коде 1.? Зачем в коде 2. дважды инициализируются счётчики? Да то в полусне вчера писал  . Поправил - всё равно виснет  . Цитата(RabidRabbit @ Dec 15 2012, 09:35)  Может, все исходники прицепите? Прицепил, посмотрите. Компилятор - IAR 6.40. Цитата(RabidRabbit @ Dec 15 2012, 09:35)  AT91C_BASE_PMC->PMC_PCER = (1UL << AT91C_ID_ADC); // разрешить тактовую для ADC ADC и так олвэйс клокед. У коллег списал  .
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
Dec 15 2012, 15:34
|

Профессионал
    
Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980

|
Поправил. Прерывания каналов вырубил, добавил AT91C_BASE_AIC->AIC_EOICR = 0; в конец прерывания. Хотя раньше оно и без него работало ... Даже сделал 2-й буфер, для ADC_RNPR .. Ни фига, всё равно виснет  . Вот нашёл осцилл самодельный на таком же проце - http://www.tomeko.net/miniscope_v2.php . Там ADC вроде через PDC тоже шурует. Только буферов там 3 или 4 штуки, в прерывании переключаются. Вроде всё также ....
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|