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

 
 
> ADC c PDC и программным запуском, sam7x
xelax
сообщение May 12 2008, 06:49
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Про работу АЦП c PDC в мануале честно говоря мало информации. Я посчитал, что настроив PDC и ADC на работу с ним и программно запустив первое преобразование, далее PDC самостоятельно запустит N преобразований, а затем дернет прерывание, о том что приёмный буфер полный.

На практике оказалось иначе. Стартую преобразование, оно происходит один раз, причём вижу, что результат сохранился в регистре, а в PDC значение N(количество преобразований), стало равно N-1.
Далее отпускаю программу поработать какое-то время, затем останавливаю и вижу что в регистрах картина не изменилась. Тот же самый результат преобразования, теже значения в регистрах PDC.
Проверял в связке sam7x-ek + arm-elf-gdb + sam-ice + eclipse.

Собственно вопросы:
1. Может ли вообще АЦП работать таким образом? И если может, то почему у меня не работает?
2. А если не может, то на кой ляд они прикрутили к АЦП контроллер доступа к памяти, в чём его глубокий смысл?

вот код работы с АЦП
Код
void adcHandler(void)
{  
  if (AT91C_BASE_ADC->ADC_SR & AT91C_ADC_RXBUFF)
  {       
     // Disable data ready Interrupt
     AT91C_BASE_ADC->ADC_IDR = AT91C_ADC_RXBUFF;
     // disables all channels  
     AT91C_BASE_ADC->ADC_CHDR = ALL_CHANNEL_DISABLE;          
     AdcInterrupt();
  }
}

/******************************************************************************
Inits the ADC.
******************************************************************************/
void  OpenAdc(AdcParams_t *param)
{    
  //enable the clock of ADC
  AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_ADC;
                
  // initialization adc
  // reset adc
  AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;
  
  /* disable receiver PDC transfer requests */
  AT91C_BASE_ADC->ADC_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;
  
  // Starting a conversion is only possible by software. 8-bit resolution mode.
  AT91C_BASE_ADC->ADC_MR = (uint32_t)sampleRate | AT91C_ADC_LOWRES;
  
  /* set pdc pointer and counter */
  AT91C_BASE_ADC->ADC_RCR = selectionsAmount;
  AT91C_BASE_ADC->ADC_RPR = bufferPointer;
      
  // disables all channels  
  AT91C_BASE_ADC->ADC_CHDR = ALL_CHANNEL_DISABLE;                                                                                                                                                                                                      
  // disable all adc interrupt                  
  AT91C_BASE_ADC->ADC_IDR = ALL_PERIPHERIAL_INTERRUPT_DISABLE;
              
  if (AT91C_BASE_AIC->AIC_SVR[AT91C_ID_ADC] != (uint32_t)adcHandler)
  {    /*first start*/                           
    /* Enable interrupts */
    /* Disable the interrupt on the interrupt controller */
    AT91C_BASE_AIC->AIC_IDCR = (1 << AT91C_ID_ADC);
    /* Save the interrupt handler routine pointer and the interrupt priority */
    AT91C_BASE_AIC->AIC_SVR[AT91C_ID_ADC] = (uint32_t)adcHandler;
    /* Store the Source Mode Register */
    AT91C_BASE_AIC->AIC_SMR[AT91C_ID_ADC] = AT91C_AIC_SRCTYPE_HIGH_LEVEL |
    AT91C_AIC_PRIOR_LOWEST;
    /* Clear the interrupt on the interrupt controller */
    AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_ADC);  
    /* Enable the interrupt on the interrupt controller */
    AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_ADC);
  }                       
}

/******************************************************************************
Starts convertion on the ADC channel.
Parameters:
  channel - channel number.
******************************************************************************/
void StartAdc(AdcChannelNumber_t channel)
{
  // enable current channel
  AT91C_BASE_ADC->ADC_CHER = channel;  
  // enable receiver PDC transfer requests  
  AT91C_BASE_ADC->ADC_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
  // enable receiver buffer full interrupt                     
  AT91C_BASE_ADC->ADC_IER = AT91C_ADC_RXBUFF;        
  // Starts conversion
  AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
}
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
nicks80
сообщение Jun 9 2008, 21:18
Сообщение #2


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

Группа: Участник
Сообщений: 97
Регистрация: 18-10-07
Пользователь №: 31 485



Вот как надо и все работает непрерывно в два буффера попеременно


#include "cpu.h"


volatile unsigned short *adc_buffers;
volatile unsigned char adc_current_buffer=0; ///
volatile unsigned char adc_samples=0;
volatile unsigned char adc_num_channels=0;


char s[32];
void adc_interupt_irq(void) __irq
{
unsigned int status = AT91C_BASE_ADC->ADC_SR;
int i;
int k=0;
int flg=0;
AT91F_PDC_SetNextRx(AT91C_BASE_PDC_ADC, (char *)&adc_buffers[adc_current_buffer*adc_samples/2], adc_samples*sizeof(unsigned short)/4); // çàðÿæàåì âòîðîé áóôåð
if(adc_current_buffer==0)
adc_current_buffer = 1;
else
adc_current_buffer=0;
// Delay(10);
// lsd_clear_screen() ;


sprintf(s,"%d",adc_buffers[0]);

for(i=0;i<128;i++)
{
// if(adc_buffers2[i]>120 || adc_buffers2[i]<132)
// if(adc_buffers2[i]<adc_buffers2[i+1])
// flg=1;
// if(flg)
lcd_set_pixel(i,(adc_buffers[i])/8,0x0000);
}

// lcd_set_str(s,32,32,0,0xFFFFFF, 0x000000) ;




AT91C_BASE_AIC->AIC_EOICR = status;
//âàø êîä
}


/// Èíèöèàëèçàöèÿ ÀÖÏ
void adc_init(volatile unsigned short *buffers,unsigned short samples,unsigned char channels)

{
adc_buffers = buffers;
adc_samples = samples/2;
adc_current_buffer = 0;
AT91C_BASE_ADC->ADC_MR = 0;

/// Ìàòåìàòèêà êðàñèâî ïîëó÷èëàñü

//adc_num_channels = channels;

AT91C_BASE_ADC->ADC_CHER = AT91C_ADC_CH7;//channels;

/// ADCClock = 47.9232 / (7+1)*2 = 2.9952 Mhz
AT91C_BASE_ADC->ADC_MR =(AT91C_ADC_SHTIM & (3<<24)) | (AT91C_ADC_STARTUP & (8 << 16)) | (AT91C_ADC_PRESCAL & (7<<8)) //3F
| AT91C_ADC_SLEEP_NORMAL_MODE | AT91C_ADC_LOWRES_8_BIT | AT91C_ADC_TRGSEL_TIOA0 | AT91C_ADC_TRGEN_EN;

// çàðÿæàåì ïåðâûé áóôåð
AT91F_PDC_SetRx(AT91C_BASE_PDC_ADC, (char*)&adc_buffers[adc_current_buffer*adc_samples], (adc_samples*sizeof(unsigned short)) );
adc_current_buffer = 1;

// çàðÿæàåì âòîðîé áóôåð
AT91F_PDC_SetNextRx(AT91C_BASE_PDC_ADC, (char*)&adc_buffers[(adc_current_buffer*adc_samples)/2], (adc_samples*sizeof(unsigned short)) );

AT91F_PDC_EnableRx(AT91C_BASE_PDC_ADC);
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_TC0; // Enable clock to TC0 // 47.9232/AT91C_TC_CLKS_TIMER_DIV1_CLOCK[/2] = 23.9616 Mhz
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK|AT91C_TC_WAVESEL_UP_AUTO|AT91C_TC_WAVE|AT91C_TC_A
CPA_SET|AT91C_TC_ACPC_CLEAR;
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN; // Enable timer
AT91C_BASE_TC0->TC_RC = 768;
AT91C_BASE_TC0->TC_RA = AT91C_BASE_TC0->TC_RC>>1; ///meander

AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_ADC, AT91C_AIC_PRIOR_HIGHEST, AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE , (void *)adc_interupt_irq);
AT91C_BASE_ADC->ADC_IER = AT91C_ADC_ENDRX; // IRQ enable, end of receive buffer
AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_ADC; // Enable interrupt in AIC
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; // Start timer
};
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 9 2008, 21:37
Сообщение #3


Гуру
******

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



Цитата(nicks80 @ Jun 10 2008, 01:18) *
Вот как надо и все работает непрерывно в два буффера попеременно

Нет, так не надо:
Во-первых, ознакомьтесь с темой - про запуск АЦП от таймера все уже давно все поняли; во-вторых, если уж выкладываете исходник, то приведите его в человеческий вид; в-третьих, пользуйтесь тегами [сode][/сode].
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- xelax   ADC c PDC и программным запуском   May 12 2008, 06:49
- - _dem   Можно "клокить" ADC от таймеров. Пример...   May 12 2008, 09:22
- - xelax   Это понятно. Только всё таки мне интересно, при ...   May 12 2008, 11:08
|- - prottoss   Цитата(xelax @ May 12 2008, 19:08) пару н...   May 12 2008, 12:30
- - _dem   Вы либо пинаете его программно (на одно преобразов...   May 12 2008, 12:22
- - xelax   Наверное примерно также и прийдётся сделать. По п...   May 12 2008, 12:59
- - _dem   Да елки-палки все работает нормально, автоматичес...   May 12 2008, 13:21
|- - prottoss   Цитата(_dem @ May 12 2008, 21:21) вот это...   May 12 2008, 13:32
- - _dem   Вечером ткну Сейчас на работе, занят. Курим пока...   May 12 2008, 14:22
|- - prottoss   Цитата(_dem @ May 12 2008, 22:22) Вечером...   May 12 2008, 14:41
- - _dem   Понятно. Из вашего сообщения "пару недель на...   May 12 2008, 14:53
|- - prottoss   Цитата(_dem @ May 12 2008, 22:53) Из ваше...   May 12 2008, 15:23
|- - xelax   2 _dem Где же обещанный пример без таймера, где ...   May 13 2008, 05:27
- - defunct   В атаче выдранные исходники из рабочего проекта. П...   May 12 2008, 16:21
- - _dem   А кто обещал пример без таймера 8( ??? Нет пока во...   May 13 2008, 08:34
- - xelax   Я думал у Вас без таймера работает, а с таймером и...   May 13 2008, 10:22
- - nicks80   Цитата(aaarrr @ Jun 10 2008, 00:37) Нет, ...   Jun 9 2008, 22:19


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

 


RSS Текстовая версия Сейчас: 20th June 2025 - 19:25
Рейтинг@Mail.ru


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