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

 
 
> sam7s/7x пример ADC c PDC, sam7s/7x пример ADC c PDC
taoga
сообщение Jun 7 2013, 14:09
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 51
Регистрация: 8-10-09
Пользователь №: 52 809



Здравствуйте! Может кто-нибудь поделиться примером непрерывного приема данных от АЦП с использованием PDC для at91sam7s/sam7x?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
SpiritDance
сообщение Jun 17 2013, 05:03
Сообщение #2


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



Вот код целиком и з модуля, рабочий. Надеюсь разберетесь.

CODE
#include "adc.h"

/*==========================================================
=======================*/

static t_adc_channels *buf1;
static t_adc_channels *buf2;
static u8 adcflag = 0;

u16 channel0;
u16 channel2;
u16 channel4;
u16 channel5;
u16 channel6;
#if DEVICE < AUTO
u16 channel1;
u16 channel3;
#endif
t_adc_channels *adc_buf;
struct pt_sem adc_dtmf_sem = {0};
struct pt_sem adc_sem = {0};

/*===============================================================================
=======================*/
/*
================================================================================
===================
Description:
Returns :
Notes :
================================================================================
===================
*/
__irq __arm __ramfunc static void adc_interrupt_handler (void)
{
volatile u32 status = AT91C_BASE_ADC->ADC_SR & AT91C_BASE_ADC->ADC_IMR;

/* обрабатываем ovverrrun перезапуская АЦП сначала */
if ( status & AT91C_ADC_GOVRE)
{
AT91C_BASE_ADC->ADC_LCDR;
AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;
AT91C_BASE_ADC->ADC_MR = AT91C_ADC_TRGEN_EN
|AT91C_ADC_TRGSEL_TIOA0
|AT91C_ADC_LOWRES_10_BIT
|AT91C_ADC_SLEEP_NORMAL_MODE
| ((unsigned int)(0x3) << 8) & AT91C_ADC_PRESCAL //1
| ((unsigned int)(0xA) << 16) & AT91C_ADC_STARTUP
| ((unsigned int)(0xF) << 24) & AT91C_ADC_SHTIM;


/* конфигурируем прерывания от ADC_PDC */
AT91C_BASE_ADC->ADC_IER = AT91C_ADC_ENDRX | AT91C_ADC_GOVRE;

/* включаем приемник PDC */
/* Initialize the Transmit and Receive Pointer */
if (adc_buf == buf2)
{ AT91C_BASE_ADC->ADC_RPR = (unsigned int)buf1; }
else
{ AT91C_BASE_ADC->ADC_RPR = (unsigned int)buf2; }
/* Intialize the Transmit and Receive Counters */
AT91C_BASE_ADC->ADC_RCR = (DTMF_BLOCK_SIZE*ADC_CHANNEL_NUM);


/* включаем нужные каналы, входы мультиплексированные в PIO должны автомантически стать входами ADC */
#if DEVICE < AUTO
AT91C_BASE_ADC->ADC_CHER = AT91C_ADC_CH0 | AT91C_ADC_CH1 | AT91C_ADC_CH2 | AT91C_ADC_CH3 |
AT91C_ADC_CH4 | AT91C_ADC_CH5 | AT91C_ADC_CH6 | AT91C_ADC_CH7;
#else
AT91C_BASE_ADC->ADC_CHER = AT91C_ADC_CH0 | AT91C_ADC_CH2 |
AT91C_ADC_CH4 | AT91C_ADC_CH5 | AT91C_ADC_CH6 | AT91C_ADC_CH7;
#endif

/* запуск АЦП */
AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;

AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
} else

/* преключаем буферы при нормальной работе ADC */
if ( status & AT91C_ADC_ENDRX)
{
if (adc_buf == buf2)
{ AT91C_BASE_ADC->ADC_RPR = (unsigned int)buf2; adc_buf = buf1; }
else
{ AT91C_BASE_ADC->ADC_RPR = (unsigned int)buf1; adc_buf = buf2; }
AT91C_BASE_ADC->ADC_RCR = (DTMF_BLOCK_SIZE*ADC_CHANNEL_NUM);
adcflag = 1;
}

AT91C_BASE_AIC->AIC_EOICR = 1;
}


/*
================================================================================
===================
Description: Конфигурируем АЦП
Returns :
Notes : Вклюяаются каналы DTMF и аналоговых входов. Триггер АЦП - таймер 2, генерирующий
меандр с частотой 8000 Гц. Количество включенных каналов зависит от версии устройства
================================================================================
===================
*/
int adc_open
(
t_adc_channels *ext_buf1, /* (вх.) буфер для dma работы с АЦП */
t_adc_channels *ext_buf2 /* (вх.) буфер для dma работы с АЦП */
)
{
buf1 = ext_buf1;
buf2 = ext_buf2;
adc_buf = buf1;

AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;
AT91C_BASE_ADC->ADC_IDR = 0xFFFFFFFF;
AT91C_BASE_AIC->AIC_IDCR = 0x1u << AT91C_ID_ADC;


AT91C_BASE_ADC->ADC_CHDR = AT91C_ADC_CH0 | AT91C_ADC_CH1 | AT91C_ADC_CH2 | AT91C_ADC_CH3 |
AT91C_ADC_CH4 | AT91C_ADC_CH5 | AT91C_ADC_CH6 | AT91C_ADC_CH7;

//* Disable the RX and TX PDC transfer requests
AT91C_BASE_ADC->ADC_PTCR = AT91C_PDC_RXTDIS;

//* Reset all Counter register Next buffer first
AT91C_BASE_ADC->ADC_TNPR = 0;
AT91C_BASE_ADC->ADC_TNCR = 0;
AT91C_BASE_ADC->ADC_RNPR = 0;
AT91C_BASE_ADC->ADC_TNCR = 0;
AT91C_BASE_ADC->ADC_TPR = 0;
AT91C_BASE_ADC->ADC_TCR = 0;
AT91C_BASE_ADC->ADC_RPR = 0;
AT91C_BASE_ADC->ADC_RCR = 0;

AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;

/* режим АЦП */
/* выбираем в качестве триггера TIOA2, 10 бит, чатота оцифровки максимальная MCK/10 */
AT91C_BASE_ADC->ADC_MR = AT91C_ADC_TRGEN_EN
|AT91C_ADC_TRGSEL_TIOA0
|AT91C_ADC_LOWRES_10_BIT
|AT91C_ADC_SLEEP_NORMAL_MODE
| ((unsigned int)(0x3) << 8) & AT91C_ADC_PRESCAL //1
| ((unsigned int)(0xA) << 16) & AT91C_ADC_STARTUP
| ((unsigned int)(0xF) << 24) & AT91C_ADC_SHTIM;

/* конфигурируем AIC на обработку прерываний от ADC */
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_ADC] = (unsigned int) adc_interrupt_handler;
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_ADC] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | ADC_INTERRUPT_LEVEL;
AT91C_BASE_AIC->AIC_IECR = 0x1u << AT91C_ID_ADC;

/* конфигурируем прерывания от ADC_PDC */
AT91C_BASE_ADC->ADC_IER = AT91C_ADC_ENDRX | AT91C_ADC_GOVRE;

/* включаем приемник PDC */
/* Initialize the Transmit and Receive Pointer */
AT91C_BASE_ADC->ADC_RPR = (unsigned int)buf1;
/* Intialize the Transmit and Receive Counters */
AT91C_BASE_ADC->ADC_RCR = (DTMF_BLOCK_SIZE*ADC_CHANNEL_NUM);

AT91C_BASE_ADC->ADC_PTCR = AT91C_PDC_RXTEN;

AT91C_BASE_ADC->ADC_SR & AT91C_BASE_ADC->ADC_IMR;

/* включаем нужные каналы, входы мультиплексированные в PIO должны автомантически стать входами ADC */
#if DEVICE < AUTO
AT91C_BASE_ADC->ADC_CHER = AT91C_ADC_CH0 | AT91C_ADC_CH1 | AT91C_ADC_CH2 | AT91C_ADC_CH3 |
AT91C_ADC_CH4 | AT91C_ADC_CH5 | AT91C_ADC_CH6 | AT91C_ADC_CH7;
#else
AT91C_BASE_ADC->ADC_CHER = AT91C_ADC_CH0 | AT91C_ADC_CH2 |
AT91C_ADC_CH4 | AT91C_ADC_CH5 | AT91C_ADC_CH6 | AT91C_ADC_CH7;
#endif

/* запуск АЦП */
AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;

return 0;
}


/*
================================================================================
===================
Description:
Returns :
Notes :
================================================================================
===================
*/
__arm __ramfunc PT_THREAD ( pt_adc_oversampling
(
struct pt *pt /* (вх) структура состояния потока */
))
{
u8 i, j;
u16 sample_channel0 = 0;
u16 sample_channel2 = 0;
u16 sample_channel4 = 0;
u16 sample_channel5 = 0;
u16 sample_channel6 = 0;
#if DEVICE < AUTO
u16 sample_channel1 = 0;
u16 sample_channel3 = 0;
#endif


PT_BEGIN(pt);

PT_WAIT_UNTIL(pt, adcflag);
adcflag = 0;

PT_SEM_SIGNAL(pt, &adc_dtmf_sem);
PT_SEM_SIGNAL(pt, &adc_sem);

/* указатель буфера для DTMF устанавливаем на определенный заполненный буфер и выставляем семафор */
/* для остальных каналов сумммируем полученное число для оversamlinga */
for (j = 0; j < DTMF_BLOCK_SIZE / 64; j++)
{
sample_channel0 = 0;
sample_channel2 = 0;
sample_channel4 = 0;
sample_channel5 = 0;
sample_channel6 = 0;
#if DEVICE < AUTO
sample_channel1 = 0;
sample_channel3 = 0;
#endif
for (i = (j*64); i < ((j*64)+64); i++ )
{
sample_channel0 += adc_buf[i].ch0;
sample_channel2 += adc_buf[i].ch2;
sample_channel4 += adc_buf[i].ch4;
sample_channel5 += adc_buf[i].ch5;
sample_channel6 += adc_buf[i].ch6;
#if DEVICE < AUTO
sample_channel1 += adc_buf[i].ch1;
sample_channel3 += adc_buf[i].ch3;
#endif
}

/* 13 бит */
/* вычисляем текущее среднее для каналов */
channel0 = (channel0 * j + (sample_channel0 >> 3)) / (j+1);
channel2 = (channel2 * j + (sample_channel2 >> 3)) / (j+1);
channel4 = (channel4 * j + (sample_channel4 >> 3)) / (j+1);
channel5 = (channel5 * j + (sample_channel5 >> 3)) / (j+1);
channel6 = (channel6 * j + (sample_channel6 >> 3)) / (j+1);
#if DEVICE < AUTO
channel1 = (channel1 * j + (sample_channel1 >> 3)) / (j+1);
channel3 = (channel3 * j + (sample_channel3 >> 3)) / (j+1);
#endif
}

PT_END(pt);
}


Сообщение отредактировал IgorKossak - Jun 17 2013, 06:46
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!! (и не новичок, вроде бы)


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post



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

 


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


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