Easyelectronics.ru

Электроника для всех
Текущее время: 24 окт 2020, 20:36

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 13 ] 
Автор Сообщение
 Заголовок сообщения: ADC +DMA
СообщениеДобавлено: 23 сен 2012, 04:43 
Здравствуйте!

Зарегистрирован: 23 сен 2012, 04:36
Сообщения: 2
может кому то понадобится
буфер приема данных необходимо выравнивать по 32х битному типу


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ADC +DMA
СообщениеДобавлено: 25 сен 2012, 13:33 
Старожил

Зарегистрирован: 14 мар 2012, 13:58
Сообщения: 1727
Спасибо! Grably international всегда рады видеть вас своим клиентом ;)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ADC +DMA
СообщениеДобавлено: 01 окт 2012, 19:39 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 10 фев 2012, 16:40
Сообщения: 197
Откуда: Украина г.Кировоград
Доброго дня!
Реальная проблема, причем детская видимо...

ПРоц STM32f103RE
Код передачи с помощью ДМА данных преобразования встроенного АЦП в фоне с использованием в кач-ве триггера- таймера 4 и канала 4.
typedef struct
{
u16 SensBuff[4];

u8 _TempReady;

} ADCtemps_structure;
ADCtemps_structure Temper;

GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;


RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1, ENABLE);
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM4, ENABLE);
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE);


/* Configure INput for temperature sensor as push-pull */
//ADC_Channel_8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);


/* DMA1 channel1 configuration ----------------------------------------------*/
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&Temper.SensBuff;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // read from continious address
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //write to different address
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //2 bytes
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //2 bytes
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
//DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); //TCIE bit enable interrupt
/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);


/* TIM4
TIM_TimeBaseStructure.TIM_Period = 10000; // TIMx->ARR áóäåì ñ÷èòàòü ïîëíûé ïåðèîä îáåñïå÷èâàåì 1 c ïåðèîäè÷íîñòü îïðîñà äàò÷èêà òåìïåðàòóðû
TIM_TimeBaseStructure.TIM_Prescaler = 7199; // TIMx->PSC Ïðåñêàëëåð = 5, ÷àñòîòà = = 12 MÃö
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; // TIMx->CR1 for digital filter
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

/* Output Compare Timing Mode configuration: Channel4 */

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // TIMx->CCMR1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // TIMx->CCER
TIM_OCInitStructure.TIM_Pulse = 100; // TIMx->CCR2 îáåñïå÷èâàåò âðåìÿ âêëþ÷åíèÿ ôóíêöèè UPDATE ïîñëå 5 ìñ.
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // TIMx->CCER
TIM_OC4Init(TIM4, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
//TIM_ITConfig(TIM4, TIM_IT_CC4, ENABLE);
TIM_ARRPreloadConfig(TIM4, ENABLE);



/* ADC configuration SCAN mode!!!!!!!------------------------------------------------------*/
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //Çàïóñêàåì ñêàíèðîâàíèå äâóõ êàíàëîâ ÀÖï è îñòàíàâëèâàåìñÿ.
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1; //SQR1 reg L[3:0]
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channels configuration */

ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_28Cycles5);

ADC_ExternalTrigConvCmd(ADC1, ENABLE); //EXTTRIG enable


/*Enable interrupt*/
//ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
/* Enable ADC1 */
//ADC_TempSensorVrefintCmd(ENABLE);

ADC_Cmd(ADC1, ENABLE); //ADON bit SET

/* Enable ADC1 reset calibration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
/* Start ADC1 Software Conversion */
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);

ADC_SoftwareStartConvCmd(ADC1, ENABLE);//SWSTART enable

TIM_Cmd(TIM4, ENABLE);

Этот код работает так, что в буфере Temper.SensBuff получаются не 12 бит данных, а только 4 бита.
Таким образом DMA почему-то сдвигает передаваемые данные на 8 разрядов!
Как это может быть не могу догнать!
Подскажите, в чем проблема. Не первый день бьюсь.(((
Спасибо!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ADC +DMA
СообщениеДобавлено: 01 окт 2012, 19:54 
Старожил

Зарегистрирован: 14 мар 2012, 13:58
Сообщения: 1727
Как ТС писал, проверьте выровнено ли по 32х битному адресу. Это видно по начальному адресу в окошке watch.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ADC +DMA
СообщениеДобавлено: 01 окт 2012, 22:29 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 10 фев 2012, 16:40
Сообщения: 197
Откуда: Украина г.Кировоград
dima2611 писал(а):
Как ТС писал, проверьте выровнено ли по 32х битному адресу. Это видно по начальному адресу в окошке watch.

Буфер приема выровнен по 32 битн адресу в ДМА инициализации.

Выходит так, что в дебаге Keil видны правильные данные в регистре DR, а при передаче ДМА эти данные сдвинуты вправо на 8 разрядов.
Типы данных приведены все к u16. По другому никак. Получаем полслова от АЦП и записываем их в массив.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ADC +DMA
СообщениеДобавлено: 01 окт 2012, 22:54 
Старожил

Зарегистрирован: 14 мар 2012, 13:58
Сообщения: 1727
Koder писал(а):
dima2611 писал(а):
Как ТС писал, проверьте выровнено ли по 32х битному адресу. Это видно по начальному адресу в окошке watch.

Буфер приема выровнен по 32 битн адресу в ДМА инициализации.

ADCtemps_structure Temper как в памяти лежит, с какого адреса начиная? То, что DMA, точнее кастинг, округлит, куда надо, понятно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ADC +DMA
СообщениеДобавлено: 01 окт 2012, 23:04 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 10 фев 2012, 16:40
Сообщения: 197
Откуда: Украина г.Кировоград
Хм...
ADCtemps_structure Temper лежит по адресу 0x200014E1. И что это значит?

Тип данных ставил u32 для массива, но это ничего не дало.((


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ADC +DMA
СообщениеДобавлено: 02 окт 2012, 10:22 
Старожил

Зарегистрирован: 14 мар 2012, 13:58
Сообщения: 1727
Последние 2 бита должны быть нулевыми в адресе, т.е. 0, 4, 8, 12...
Эта тема про alignment. http://www.keil.com/support/man/docs/ar ... AJDDHB.htm

что, если Вам перед объявлением ADCtemps_structure Temper объявить нечто квардатное вроде u32 dummy в надежде, что Temper встанет в памяти сразу после него, а u32 в принципе выровнено. А кардинально должно помочь __align или подобное в зависимости от компилятора.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ADC +DMA
СообщениеДобавлено: 02 окт 2012, 11:37 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 10 фев 2012, 16:40
Сообщения: 197
Откуда: Украина г.Кировоград
Очень благодарен!
Ща попробую повозиться..не имел дело с такой задачей еще(


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ADC +DMA
СообщениеДобавлено: 02 окт 2012, 13:13 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 10 фев 2012, 16:40
Сообщения: 197
Откуда: Украина г.Кировоград
Запрацювало! Аж гай зашумів!
Прописал

#pragma pack(2)
typedef struct
{
u16 SensBuff[4];

u8 _TempReady;

} ADCtemps_structure;


Еще вопрос. Есть в контроллере еще такие данные как ReferenceVoltage (Vrefint) подключено к ADCx_IN17.
У меня это занчение отображается равным 0x05D6.
К чему это значение вообще можно привязать? Оно даже не участвует в расчете тем-ры, измеряемой штатным темп. датчиком STM32.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ADC +DMA
СообщениеДобавлено: 02 окт 2012, 14:26 
Старожил

Зарегистрирован: 14 мар 2012, 13:58
Сообщения: 1727
Koder писал(а):
Есть в контроллере еще такие данные как ReferenceVoltage (Vrefint) подключено к ADCx_IN17.
У меня это занчение отображается равным 0x05D6.
К чему это значение вообще можно привязать? Оно даже не участвует в расчете тем-ры, измеряемой штатным темп. датчиком STM32.
Internal voltage reference, возможно 1.2 вольт. Посмотрите в мануале и/или даташите. Смысл, только когда её подцепляете, а не пользуетесь внешним эталоном.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ADC +DMA
СообщениеДобавлено: 02 окт 2012, 15:34 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 08 сен 2011, 19:58
Сообщения: 74
Откуда: Украина, Харьков
Koder писал(а):
К чему это значение вообще можно привязать? Оно даже не участвует в расчете тем-ры, измеряемой штатным темп. датчиком STM32.
Измеряя это значение, можно точно посчитать значение напряжения питания, зная точное напряжение питания, вы точнее меряете температуру.

_________________
Лучше жалеть о том, что сделано, чем о том, что не сделано.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: ADC +DMA
СообщениеДобавлено: 03 окт 2012, 16:02 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 10 фев 2012, 16:40
Сообщения: 197
Откуда: Украина г.Кировоград
Ясно.
А были у кого-либо проблемы с тем, что сбивается индекс в массиве при передачи с помощью DMA данных преобразованных каналов АЦП ?
Вначале, после старта, спустя неск. преобразований массив u16 SensBuff[4]; вмещает четко по очередности данные, а затем индек этих данных начинает плыть.
Это при условии, что DMA полность отрабатывает весь регистр CNDTR до нуля. ПРи следующих транзакциях CNDTR вмещает число уст. при инициализации, а индекс массива в памяти должен начинаться снова с 0 ! Почему-то этого не происходит....

Я так понял в режиме калибровки происходит холостое преобразование АЦП. Далее, по идее идет установившийся режим


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 13 ] 


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB