Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту

Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей...

Закрытая тема
Опции темы
Непрочитано 13.03.2012, 15:21   #1
Nik_UFO
Частый гость
 
Регистрация: 22.04.2007
Сообщений: 26
Сказал спасибо: 10
Сказали Спасибо 4 раз(а) в 4 сообщении(ях)
Nik_UFO на пути к лучшему
По умолчанию STM32F103 ADC+DMA

Всем добрый день.

Настроил DMA и ADC c двумя каналами, данные приходят с обоих каналов, но расположение данных в массиве каждый раз разное, такое:
dataChanel1, dataChanel2, dataChanel1, dataChanel2, .....

или такое
dataChanel2, dataChanel1, dataChanel2, dataChanel1, .....

Как сделать, чтобы всегда первый элемент массива был из первого канала?

Инициализация портов:
Код:
GPIO_InitTypeDef GPIO_InitStructure;
// Тактируем порт.
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Конфигурация ПВВ. PA. Вход АЦП.*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2
		| GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

	// Выход  ЦАП.
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
Настройка DMA:
Код:
DMA_InitTypeDef  DMA_InitStructure;
// Подаем тактовый сигнал на DMA.
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/*Конфигурация DMA*/
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)& ADC1-›DR;   /*источник данных. DR - регистр сохранения результатов преобразования*/
DMA_InitStructure.DMA_MemoryBaseAddr = ((uint32)MES_bufer); /*приёмник данных*/
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = sizeBufer;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
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);
/* Разрешить передачу DMA1 Channel1*/
DMA_Cmd(DMA1_Channel1, ENABLE);
Настройка ADC:
Код:
ADC_InitTypeDef ADC_InitStructure;
	/*тактирование АЦП.*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);  /*АЦП*/
	//RCC_ADCCLKConfig(RCC_PCLK2_Div8);
	/*Конфигурация АЦП*/
	/*Установка предварительного делителя*/
	RCC-›CFGR &= ~RCC_CFGR_ADCPRE;
	RCC-›CFGR |= RCC_CFGR_ADCPRE_DIV6; /*Работа на частоте 12MHz*/
	/*Инициализация АЦП*/
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_InitStructure.ADC_ScanConvMode=ENABLE; // Одноканальный режим.
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // Продолжительный режим.
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_Externa  lTrigConv_None;/*!!!!!!! таймер 1 по захвату-сравнению? Почитать*/
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Righ  t;
	ADC_InitStructure.ADC_NbrOfChannel = 2; /*кол-во каналов АЦП */
	ADC_Init(ADC1, &ADC_InitStructure);
	/*Разрешение DMA*/
	ADC_DMACmd(ADC1, ENABLE);
	/*Разрешение на преобразование от внешнего переключателя*/
	//ADC_ExternalTrigConvCmd(ADC1, ENABLE);
	/*Разрешение на прерывание по окончанию преобразования*/
	ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
	/*Режим компаратора*/
	//ADC_AnalogWatchdogThresholdsConfig(ADC1,0xFFFF,0x0  000);
	//ADC_ITConfig(ADC1, ADC_IT_AWD, ENABLE); /*Разрешение по прерыванию AWD*/
	/*Настройка каналов и порядок измерения*/
	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_239Cycles5);
	/*ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_239Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_239Cycles5);
	/*ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_239Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_239Cycles5);*/
	//ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_239Cycles5);
	//ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_239Cycles5);
	/* Enable ADC1 */
	ADC_Cmd(ADC1, ENABLE);
	// Разрешаем обработку прерываний.
	// NVIC_EnableIRQ(ADC1_IRQn);
	/*Калибровка АЦП*/
	ADC_ResetCalibration(ADC1);
	while (ADC_GetResetCalibrationStatus(ADC1));
	/* Start ADC1 calibration */
	ADC_StartCalibration(ADC1);
	/* Check the end of ADC1 calibration */
	while (ADC_GetCalibrationStatus(ADC1));
	/*Программный запуск преобразования регулирной группы*/
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
Повторно запускаю DMA так:
Код:
DMA_Cmd(DMA1_Channel1, DISABLE);
DMA_SetCurrDataCounter(DMA1_Channel1, sizeBufer);
DMA_Cmd(DMA1_Channel1, ENABLE);
Реклама:
Nik_UFO вне форума  
Непрочитано 13.03.2012, 20:43   #2
Alecsej
Вид на жительство
 
Регистрация: 10.08.2005
Сообщений: 385
Сказал спасибо: 0
Сказали Спасибо 161 раз(а) в 140 сообщении(ях)
Alecsej на пути к лучшему
По умолчанию Re: STM32F103 ADC+DMA

Думается, перед инициализацией дма надо останавливать преобразование.
Alecsej вне форума  
Сказали "Спасибо" Alecsej
Nik_UFO (14.03.2012)
Непрочитано 14.03.2012, 08:19   #3
Nik_UFO
Частый гость
 
Регистрация: 22.04.2007
Сообщений: 26
Сказал спасибо: 10
Сказали Спасибо 4 раз(а) в 4 сообщении(ях)
Nik_UFO на пути к лучшему
По умолчанию Re: STM32F103 ADC+DMA

Сообщение от Alecsej Посмотреть сообщение
Думается, перед инициализацией дма надо останавливать преобразование.
Так и оказалось.

Теперь, повторный запуск DMA выглядит так:
Код:
ADC_Cmd(ADC1, DISABLE);
DMA_Cmd(DMA1_Channel1, DISABLE);
DMA_SetCurrDataCounter(DMA1_Channel1, sizeBufer);
DMA_Cmd(DMA1_Channel1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
Nik_UFO вне форума  
Непрочитано 17.03.2012, 20:37   #4
spinach83
Временная регистрация
 
Аватар для spinach83
 
Регистрация: 30.03.2009
Сообщений: 71
Сказал спасибо: 23
Сказали Спасибо 26 раз(а) в 25 сообщении(ях)
spinach83 на пути к лучшему
По умолчанию Re: STM32F103 ADC+DMA

У меня задачка похожа на Вашу, однако проблема совсем с другим, может кто подскажет. У меня инициализация похожая (очень - выкладывать даже смысла не вижу пока), разница только что каналов пять штук - с десятого (нулевой пин порта GPIOC) по 14-й, и никаких прерываний, запрос значений там иначе формируется... не в этом суть, а в том, что у меня в структуру через DMA падают значения совершенно не соответствующие состояниям аналоговых входов - у меня сидит перемычка на землю скажем на всех каналах - а показания колеблются около среднего значения, тоесть половины опорного напряжения(опорное=питающему=3V3, электрически всё с соблюдением там всех правил шумоподавления, железо исключается, я не в одной железке это проверял).....они постоянно колбасят (для отладки у меня чтение циклическое сейчас), из чего я заключаю что DMA и АЦП у меня несомненно работают. Гдето сидит глупая ошибка а я её в упор не вижу... По всей видимости аналоговый вход недонастроен както получился... Вот кусок что отвечает за настройку порта под ацп:

Цитата:
void Config_RCC_IO(void)
{
RCC_ADCCLKConfig(RCC_PCLK2_Div8 );
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOE | RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO, ENABLE);

}

void Config_GPIO_IO(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

// Analog-In Pins [ADC]
GPIO_DeInit(GPIOC);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}

под отладкой захожу убеждаюсь что входы настроены и порт включен. Но преобразование не соответствует реальности... + абсолютно тоже самое не только с реальными входами но и внутренним термометром что сидит на канале ADC_Channel_16 - терморасчёт даёт температуру около минус 30 градусов (температура реально ессно комнатная)

самого АЦП инит я брал с образцовых примеров библиотечных... вотоно (время конвертации раздуто до упора):

Цитата:
ADC_DeInit(ADC1);

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE; // Multichannel enabled
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // Cyclic conversion enabled
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = ADC_Channel_10;
ADC_Init(IO_AI_ADC, &ADC_InitStructure);

ADC_InitStructure.ADC_NbrOfChannel = ADC_Channel_11;
ADC_Init(IO_AI_ADC, &ADC_InitStructure);

ADC_InitStructure.ADC_NbrOfChannel = ADC_Channel_12;
ADC_Init(IO_AI_ADC, &ADC_InitStructure);

ADC_InitStructure.ADC_NbrOfChannel = ADC_Channel_13;
ADC_Init(IO_AI_ADC, &ADC_InitStructure);

ADC_InitStructure.ADC_NbrOfChannel = ADC_Channel_14;
ADC_Init(IO_AI_ADC, &ADC_InitStructure);

ADC_InitStructure.ADC_NbrOfChannel = ADC_Channel_TempSensor;
ADC_Init(IO_AI_ADC, &ADC_InitStructure);

/* ADC regular channels configuration */
ADC_RegularChannelConfig(IO_AI_ADC, ADC_Channel_10, 1, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(IO_AI_ADC, ADC_Channel_11, 2, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(IO_AI_ADC, ADC_Channel_12, 3, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(IO_AI_ADC, ADC_Channel_13, 4, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(IO_AI_ADC, ADC_Channel_14, 5, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(IO_AI_ADC, ADC_Channel_TempSensor, 6, ADC_SampleTime_239Cycles5);

Следущий кусок:

Цитата:
DMA_InitTypeDef DMA_InitStructure;

DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(IO_AI_ADC-›DR));
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RESULTBASE;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 6; // число каналов = 6
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);

/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);

ADC_DMACmd(IO_AI_ADC, ENABLE);
ADC_Cmd(IO_AI_ADC, ENABLE);
ADC_ResetCalibration(IO_AI_ADC);
while(ADC_GetResetCalibrationStatus(IO_AI_ADC));
ADC_StartCalibration(IO_AI_ADC);
while(ADC_GetCalibrationStatus(IO_AI_ADC));
ну а дальше я просто мягкий старт делаю и получаю какую то фигню как было уже сказано. Где ошибка? Или вернее чего не хватает в коде...?
P.S.: IO_AI_ADC = ADC1

Последний раз редактировалось spinach83; 18.03.2012 в 01:21.
spinach83 вне форума  
Непрочитано 18.03.2012, 01:14   #5
spinach83
Временная регистрация
 
Аватар для spinach83
 
Регистрация: 30.03.2009
Сообщений: 71
Сказал спасибо: 23
Сказали Спасибо 26 раз(а) в 25 сообщении(ях)
spinach83 на пути к лучшему
По умолчанию Re: STM32F103 ADC+DMA


Усё. Кажись разобрался глядя на ваш код, надо было его кстати покурить а я тут со своими проблемами сразу...
У меня неверно было вот это:
ADC_InitStructure.ADC_NbrOfChannel = ADC_Channel_11;
ADC_Init(IO_AI_ADC, &ADC_InitStructure);
итд.

Там ж число каналов указывается а не номер каждого канала под инициализацию структуры как мне казалось... правильно в моём случае значит так:
/**/ ADC_InitStructure.ADC_NbrOfChannel = 6;
/**/ ADC_Init(IO_AI_ADC, &ADC_InitStructure);

так что мой вопрос более не актуален, сорри за беспокойство, спасибо за внимание
spinach83 вне форума  
Непрочитано 11.08.2016, 18:07   #6
zeon13
Частый гость
 
Регистрация: 10.08.2016
Сообщений: 12
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
zeon13 на пути к лучшему
По умолчанию Re: STM32F103 ADC+DMA

У меня та же задача. Поднимаю 6 АЦП. На первый взгляд все работает, но при подключении всех шести портов АЦП через резистивный делитель наблюдаю одинаковые значения в регистрах буфера, чего быть не должно. Подозреваю что неправильно настроил АЦП. Кто может помогите пожалуйста, покажите заковырку, глаза замылены уже. Фото схемы и значения регистров прилагаю.
Код Кокоса:

#include "stm32f10x_usart.h"
#include "misc.h"
#include‹stm32f10x_adc.h›
#include‹stm32f10x_rcc.h›
#include‹stm32f10x_gpio.h›
#include‹stm32f10x_dma.h›

GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;

uint16_t MES_bufer[] = {0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA};
int sizeBufer = 6;
uint16_t data_adc;




int main(void)
{
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Тактируем порт.
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Конфигурация ПВВ. PA. Вход АЦП.*/
GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);





/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Подаем тактовый сигнал на DMA.
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/*Конфигурация DMA*/
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)& ADC1-›DR; /*источник данных. DR - регистр сохранения результатов преобразования*/
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)MES_bufer; /*приёмник данных*/
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = sizeBufer;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
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);
/* Разрешить передачу DMA1 Channel1*/
DMA_Cmd(DMA1_Channel1, ENABLE);

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/*тактирование АЦП.*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); /*АЦП*/
//RCC_ADCCLKConfig(RCC_PCLK2_Div;
/*Конфигурация АЦП*/
/*Установка предварительного делителя*/
RCC-›CFGR &= ~RCC_CFGR_ADCPRE;
RCC-›CFGR |= RCC_CFGR_ADCPRE_DIV6; /*Работа на частоте 12MHz*/
/*Инициализация АЦП*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode=DISABLE; // Одноканальный режим.
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // Продолжительный режим.
ADC_InitStructure.ADC_ExternalTrigConv=ADC_Externa lTrigConv_None;/*!!!!!!! таймер 1 по захвату-сравнению? Почитать*/
ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Righ t;
ADC_InitStructure.ADC_NbrOfChannel = 6; /*кол-во каналов АЦП */
ADC_Init(ADC1, &ADC_InitStructure);
/*Разрешение DMA*/
ADC_DMACmd(ADC1, ENABLE);
/*Разрешение на преобразование от внешнего переключателя*/
//ADC_ExternalTrigConvCmd(ADC1, ENABLE);
/*Разрешение на прерывание по окончанию преобразования*/
ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
/*Режим компаратора*/
//ADC_AnalogWatchdogThresholdsConfig(ADC1,0xFFFF,0x0 000);
//ADC_ITConfig(ADC1, ADC_IT_AWD, ENABLE); /*Разрешение по прерыванию AWD*/
/*Настройка каналов и порядок измерения*/
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_28Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_28Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_28Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_28Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_28Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_28Cycles5);

/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
// Разрешаем обработку прерываний.
// NVIC_EnableIRQ(ADC1_IRQn);
/*Калибровка АЦП*/
ADC_ResetCalibration(ADC1);
while (ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while (ADC_GetCalibrationStatus(ADC1));
/*Программный запуск преобразования регулирной группы*/
//ADC_SoftwareStartConvCmd(ADC1,ENABLE);

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



while(1)
{
ADC_Cmd(ADC1, DISABLE);
DMA_Cmd(DMA1_Channel1, DISABLE);
DMA_SetCurrDataCounter(DMA1_Channel1, sizeBufer);
DMA_Cmd(DMA1_Channel1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while (ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while (ADC_GetCalibrationStatus(ADC1));
ADC_SoftwareStartConvCmd(ADC1,ENABLE);

}
}
Миниатюры:
Нажмите на изображение для увеличения
Название: 1.jpg
Просмотров: 0
Размер:	464.5 Кб
ID:	98981   Нажмите на изображение для увеличения
Название: 2.jpg
Просмотров: 0
Размер:	3.12 Мб
ID:	98982  
zeon13 вне форума  
Непрочитано 11.08.2016, 21:33   #7
swat24
Гражданин KAZUS.RU
 
Регистрация: 16.03.2009
Адрес: Украина, Харьков
Сообщений: 762
Сказал спасибо: 108
Сказали Спасибо 67 раз(а) в 67 сообщении(ях)
swat24 на пути к лучшему
По умолчанию Re: STM32F103 ADC+DMA

zeon13,
настрой следующим образом:

ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 2, ADC_SampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 3, ADC_SampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 4, ADC_SampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 5, ADC_SampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 6, ADC_SampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 7, ADC_SampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 8, ADC_SampleTime);
swat24 вне форума  
Непрочитано 12.08.2016, 09:05   #8
zeon13
Частый гость
 
Регистрация: 10.08.2016
Сообщений: 12
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
zeon13 на пути к лучшему
По умолчанию Re: STM32F103 ADC+DMA

Сообщение от swat24 Посмотреть сообщение
zeon13,
настрой следующим образом:

ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 2, ADC_SampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 3, ADC_SampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 4, ADC_SampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 5, ADC_SampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 6, ADC_SampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 7, ADC_SampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 8, ADC_SampleTime);

1. Можете объяснить почему именно такой порядок? (он чем то обусловлен или просто так запустилось?)
2. У меня всего 10 каналов (STM32F103C8T6), использовать необходимо 6. Как мне их лучше расставить?
zeon13 вне форума  
Непрочитано 13.08.2016, 03:47   #9
NewWriter
Заблокирован
 
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
NewWriter на пути к лучшему
По умолчанию Re: STM32F103 ADC+DMA

Оооххх черт возьми, чего тут только не собрано - и прерывания по завершению преобразования, и дма, и аналоговый компаратор, и чет знает еще чего... А сомого важного то и нет, оно вообще отключено. И правильно там в комментах написано: "Прочитать". Верно. Надо прочитать.

Преобразования можно запускать абсолютно в любом порядке на любых каналах.
За последовательность преобразований регулярных каналов отвечают регистры SQR1 - SQR3, в них содержится номер канала, поэтому можно выбирать совершенно любую последовательность, хоть три раза подряд один и тот же канал. Максимум в пачке 16 выборок любых каналов.

Запуск АЦП может производиться по любому событию из списка, в том числе, и непрерывно с настраиваемой скоростью.

Одинаковые результаты во всех измерениях получились из-за неправильных настроек подгрупп и количества каналов в подгруппе. Получилось, грубо говоря, "6 раз 1 канал", на надо было "1 раз 6 каналов".
Да и вообще, те проблемы, которые в начале темы вынесены и на них так никто и не дал ответа - эти проблемы в несоответствии числа каналов, числа подгрупп, числа передач дма. При циклическом опросе число подгрупп должно быть кратно числу каналов, а число передач дма должно быть равным суммарному объему передачи, который тоже должен быть кратным количеству каналов. Например, для усреднения результатов по 5 измерениям в каждом канале, количество дма-передач должно быть в 5 раз больше числа измеряемых каналов. Получим двухмерный массив [количество_выборок][количество_каналов].

Например, полное преобразование 6 каналов, запускаемое по таймеру с некоторым периодом, с сохранением результатов в 6 раздельных регистров через DMA, будет выглядеть вот так:
PHP код:
//----- Инициализация -----------------------------
    /* ............................
     * входы АЦП, IN0 - IN5 на PA0 - PA5
     */
    
RCC-›APB2ENR |= RCC_APB2Periph_GPIOA;
    
GPIOA-›CRL &= ~(GPIO_CRL_CNF0 GPIO_CRL_CNF1 GPIO_CRL_CNF2 GPIO_CRL_CNF3 |
                    
GPIO_CRL_CNF4 GPIO_CRL_CNF5);    //аналоговые каналы PA0-PA5
    
    /* .............................
     * настройка TIM3. Выход триггера при обновлении таймера
     */
    
RCC-›APB1ENR |= RCC_APB1ENR_TIM3EN;
    
TIM3-›PSC 80;
    
TIM3-›ARR 100-1;                                    //период обновления 1 мс
    
TIM3-›CR2 |= TIM_CR2_MMS_1;                         //выход триггера при обновлении таймера
    
    /* ............................
     * АЦП, регулярные каналы IN0 - IN5, запуск от TIM3 TRGO,
     * режим сканирования каналов, 
     * запрос DMA по получению результата канала
     */
    
RCC-›APB2ENR |= RCC_APB2Periph_ADC1;
    
ADC1-›CR2 |= ADC_CR2_ADON;                            //включение модуля АЦП
    
ADC1-›CR1 |= ADC_CR1_SCAN;                            //режим сканирования каналов
    
ADC1-›CR2 |= ADC_CR2_EXTSEL_2 |    ADC_CR2_EXTTRIG |     //триггер запуска от TIM3 TRGO,
                 
ADC_CR2_DMA;                            //разрешено использование DMA
    
ADC1-›SQR1 |= ADC_SQR1_L_0 ADC_SQR1_L_2;            //число каналов 6
    
ADC1-›SQR3 |                                    //последовательность
                 
ADC_SQR3_SQ2_0 |                        //каналов 0, 1, 2, 3, 4, 5
                 
ADC_SQR3_SQ3_1 |
                 
ADC_SQR3_SQ4_0 ADC_SQR3_SQ4_1 |
                 
ADC_SQR3_SQ5_2 |
                 
ADC_SQR3_SQ6_0 ADC_SQR3_SQ6_2;
    
    
/* ...........................
     * DMA1, Ch1, 16/16 bit, циклич.буфер, инкремент памяти
     * Запрос DMA от ADC1, результаты каналов АЦП в регистрах ADC_Res[]
     */
    
RCC-›AHBENR |= RCC_AHBENR_DMA1EN;                    //DMA1 затактирован
    
DMA1_Channel1-›CCR |= DMA_CCR1_MINC DMA_CCR1_MSIZE_0 //канал 1, 16/16 бит,
                          
DMA_CCR1_PSIZE_0 DMA_CCR1_CIRC;     //инкремент памяти, циклич.буфер
    
DMA1_Channel1-›CPAR = (uint32_t)&ADC1-›DR;            //адрес регистра АЦП
    
DMA1_Channel1-›CMAR = (uint32_t)&ADC_Res[0];        //начальный адрес буфера результатов
    
DMA1_Channel1-›CNDTR 6;                            //кол-во передач по DMA
    
DMA1_Channel1-›CCR |= DMA_CCR1_EN;                    //DMA канал 1 включен
    
//----- Запуск преобразований ------------------------
    
TIM3-›CR1 |= TIM_CR1_CEN;    //таймер запущен, АЦП запущен, преобразования выполняются 




И всё, никаких прерываний не нужно, в регистрах данные обновляются автоматически, их можно сразу брать и использовать в любом месте программы.
PHP код:
  if (ADC_Res[0] ‹ 1000)
      
GPIOC-›BSRR GPIO_Pin_2 | (GPIO_Pin_1 ‹‹ 16) | (GPIO_Pin_0 ‹‹ 16);

  if ((
ADC_Res[0] ›= 1000) & (ADC_Res[0] ‹ 2000))
      
GPIOC-›BSRR GPIO_Pin_1 | (GPIO_Pin_0 ‹‹ 16) | (GPIO_Pin_2 ‹‹ 16);

  if (
ADC_Res[0] ›= 2000)
      
GPIOC-›BSRR GPIO_Pin_0 | (GPIO_Pin_1 ‹‹ 16) | (GPIO_Pin_2 ‹‹ 16); 

Последний раз редактировалось NewWriter; 13.08.2016 в 04:57.
NewWriter вне форума  
Эти 2 пользователя(ей) сказали Спасибо NewWriter за это сообщение:
6ap6oc (23.05.2017), zeon13 (15.08.2016)
Непрочитано 15.08.2016, 14:22   #10
zeon13
Частый гость
 
Регистрация: 10.08.2016
Сообщений: 12
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
zeon13 на пути к лучшему
По умолчанию Re: STM32F103 ADC+DMA

NewWriter Огромное спасибо за науку, за код! Код практически 1 в 1 подошел на С в Кейле за малыми правками. Все заработало с первого раза!
zeon13 вне форума  
Закрытая тема

Закладки


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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
STM32 Повторный запуск DMA Nik_UFO Микроконтроллеры, АЦП, память и т.д 2 07.03.2012 17:38
STM32 ADC + DMA в циклическом режиме Nik_UFO Микроконтроллеры, АЦП, память и т.д 4 24.02.2012 18:49
IWDG stm32F103 Wind_ Микроконтроллеры, АЦП, память и т.д 0 31.10.2011 17:59
DMA в ATxmega vav618 Микроконтроллеры, АЦП, память и т.д 1 03.04.2010 10:57


Часовой пояс GMT +4, время: 02:49.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot