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

 
 
> Постоянное считывание 3 каналов АЦП без прерываний, на Cortex. Реально ли сделать?
Halfback
сообщение Feb 20 2010, 08:37
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512



Задача проста: имеются три переменные u16 a,b,c и есть 3 канала ацп ADC1, ADC2 и ADC3. Как сделать так, чтобы эти три канала постонно сканировались и значения записывались в 3 переменные без использования прерываний и ресурсов ядра. Т.е. чтобы фактически система жила своей жизнью... Тут понятно, нужно DMA но вот как обойтись без переинициализаций - ведь на каждый АЦП своя переменная для хранения результата. Есть у кого идеи как это сделать?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 7)
one_man_show
сообщение Feb 20 2010, 12:22
Сообщение #2


Помогу, чем смогу
******

Группа: Админы
Сообщений: 2 786
Регистрация: 28-05-04
Из: Москва
Пользователь №: 25



В постановке задачи непонятно, почему нужно исключить прерывания? Используется ли ОС? Какова периодичность опроса?


--------------------
С уважением,
Ваган Саруханов
Проекты|Форум|Facebook|Linkedin
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 20 2010, 14:05
Сообщение #3


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Что за Cortex-то? Ежели STM32, то без проблем вроде (и без DMA).


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Halfback
сообщение Feb 20 2010, 19:06
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512



Спасибо что откликнулись! smile.gif

AHTOXA Да, Cortex STM32F103RE

Если без проблем то как? Читал про ADC но пока не догнал. Пока сделал циклический постоянный опрос Датчика температуры и запись значения в переменную, но я использую DMA с автоматической переинициализацией.


Цитата
В постановке задачи непонятно, почему нужно исключить прерывания? Используется ли ОС? Какова периодичность опроса?

ОС не используется, периодичность определяется аппаратными функциями АЦП (т.е. без тамеров и т.п.) ну и вообще каких-то жестких критериев нет - если будет мерить хотя бы 10 раз в секунду и то вполне устроит. Сейчас вообще стоит максимальное время семплирования канала.
Прерывания хочу исключить т.к. есть прерывания, которые надо сразу обрабатывать без всяких очередей. Заморачиваться в приоритетах пока нет желания.

Сообщение отредактировал Halfback - Feb 20 2010, 19:08
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 20 2010, 22:07
Сообщение #5


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Halfback @ Feb 21 2010, 00:06) *
Если без проблем то как?

Посмотрите примеры от их FWLib. В частности, examples\ADC\3ADCs_DMA.
Насчёт того, что легко без DMA я похоже погорячилсяsmile.gif - либо поллинг, либо DMA.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Halfback
сообщение Feb 21 2010, 08:49
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512



AHTOXA
Пример давно еще изучен и не катит - там ДВА РАЗНЫХ АЦП1 и АЦП3 и на них работает свой канал DMA. Третий АЦП2 висит на NVIC где в обработчике считывается значение из регистра в переменную. ТАк что не канает.
Go to the top of the page
 
+Quote Post
Halfback
сообщение Feb 23 2010, 20:22
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512



Проблема решена. Как всегда самим.

Вот так:
в переменную u16 ADC_ConvertedValue[3] = {0,0,0}; надо складывать преобразования 0,1 и 16 каналов АЦП и чтобы всё на автомате и без прерываний.

Инициализация ADC:
Код
void ADC_Configuration(void) {

    ADC_InitTypeDef ADC_InitStructure;     

    ADC_TempSensorVrefintCmd(ENABLE);    
    
      /* ADC1 configuration ------------------------------------------------------*/
      ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
      ADC_InitStructure.ADC_ScanConvMode = ENABLE;
      ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
      ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
      ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
      ADC_InitStructure.ADC_NbrOfChannel = 3;
      ADC_Init(ADC1, &ADC_InitStructure);    
      
    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_16, 3, ADC_SampleTime_239Cycles5);

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


Инициализация DMA:
Код
    // Настраиваем канал 1 DMA_1 на передачу из АЦП значения датчика температуры
    /* DMA1 channel1 configuration ----------------------------------------------*/
      DMA_DeInit(DMA1_Channel1);
      DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;  //(u32)0x4001244C;
      DMA_InitStructure.DMA_MemoryBaseAddr = (u32) ADC_ConvertedValue;
      DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
      DMA_InitStructure.DMA_BufferSize = 3;
      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_High;
      DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
      DMA_Init(DMA1_Channel1, &DMA_InitStructure);


Проверено - работает. Из примера вроде всё понятно что к чему и почему.

Сообщение отредактировал Halfback - Feb 23 2010, 20:23
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 23 2010, 20:33
Сообщение #8


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Halfback @ Feb 24 2010, 01:22) *
Проблема решена. Как всегда самим.


Ага, я же говорил что элементарно!
Шутка, шуткаsmile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

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

 


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


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