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

 
 
 
Reply to this topicStart new topic
> Проблема с АЦП STM32F100, Проблема при измерении инжектированного и регулярного канала
drum1987
сообщение Feb 27 2013, 18:36
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 255
Регистрация: 3-02-09
Из: Омск
Пользователь №: 44 323



Задача мониторить ток и напряжения.
Камень самый простой f100c4. Соответственно АЦП только 1. Использую 2 канала (0 и 8). 0 канал мерит напряжения (их 8 подаются с мультиплексора). Сигнал на вход АЦП подается с ОУ, поэтому сопротивление источника мало + RC фильтр 100 Ом + 10нФ.

Схема измерения напряжения такая: Дергаю ножкой(подключая этим источник ко входу ОУ), запускаю 2(4, 8, 16) раза регулярное преобразование в прерывании по окончанию (флаг EOC) считываю результат преобразования, вычисляю среднее и ногу опускаю назад. Повторяю для всех ног. Пачка измерений раз в секунду.
Схема измерения тока: Источник подключен всегда, инжектированный канал связан с таймером необходимо 100 измерений в секунду (хочу считать А*ч).

Вроде все ясно и понятно, но есть проблема: когда инжектированный канал прерывается инжектированным, то преобразование регулярного канала не возобновляется при завершении преобразования в инжектированном канале. Изза этого образубтся "провалы" при измерениях.



Как видно из рисунка, значение измеренное при вытеснении инжектированным каналом близко к 0,4 В. (4+0,4)/2=2,2 В. То, что с напряжением на ноге все в порядке говорит осциллограмма:



Тут желтая эпюра - напряжение на входе АЦП, синяя - "отладочный светодиод" зажигаемый в момент начала преобразования и тушащийся в момент срабатывания прерывания по событию EOC.
Хорошо виден момент когда срабатывает инжектированный канал (импульс малой длительности по сравнению с остальными) прерванное преобразование не возобновляется.

Прилагаю код:
Настройка АЦП:
CODE
/* Enable ADC1 and RCC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div2);

/* 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 = 1;
ADC_Init(ADC1, &ADC_InitStructure);


/* ADC1 regular channel0 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);

/* Set injected sequencer length */
ADC_InjectedSequencerLengthConfig(ADC1, 1);

/* ADC1 injected channel Configuration */
ADC_InjectedChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5);

/* ADC1 injected external trigger configuration */
ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_T2_TRGO);

/* Enable JEOC interrupt on ADC1 */
ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE);

/* Enable ADC1 EOC interupt */
ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);

NVIC_SetPriority (ADC1_IRQn, 1);

/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);

/* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1);

/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));

/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);

/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));


/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
ADC_ExternalTrigInjectedConvCmd(ADC1, ENABLE);



Прерывания по АЦП:
Код
void ADC1_IRQHandler(void)
{
  if (ADC_GetFlagStatus(ADC1, ADC_FLAG_JEOC))
  {
        // Get injected channel8 converted value
        int curr = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_2);
        curr = curr * VCC/0xfff;
    
ADC_ClearITPendingBit(ADC1, ADC_IT_JEOC);
  }

  else if (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC))
  {
ADC1ConvertedValue = ADC_GetConversionValue(ADC1);
/* Clear ADC1 EOC pending interrupt bit */
ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);
converted = 1;
  LED_OFF;
    }
}


Вызов преобразования:
Код
long cell_mesure(unsigned int cell_num)
{

    GPIO_HIGH(Mes[cell_num - 1]->port, Mes[cell_num - 1]->pin); // включение измерителя
    converted = 0;    
    LED_ON;
    ADC1->SQR3 = 0;                //загрузить номер канала
              ADC1->CR2 |= ADC_CR2_SWSTART;     //запустить преобразование в регулярном канале  
    while(!converted);
    long voltage = ADC1ConvertedValue;  // измерение №1

    return (voltage);
}


Куда копать?

Сообщение отредактировал IgorKossak - Mar 1 2013, 08:31
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
koyodza
сообщение Feb 27 2013, 20:27
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 213
Регистрация: 28-02-07
Из: Киев
Пользователь №: 25 744



Ранее Вы, видимо, работали с AVR sm.gif
Попробуйте сделать не так, а как более удобно делать на таких МК
То, что Вы делаете сейчас - это чесание пяткой за ухом.
Раз хотите измерять 100 раз в секунду ток, то настройте regular channel на преобразование по таймеру 100 раз в секунду, и пусть по DMA данные складываются в буфер, прерывания от АЦП не нужны, нужны прерывания по половине буфера и по полному буферу.
А когда хотите измерить напряжение, дёргайте ножкой и запускайте программно преобразование для injected channel, полученные данные после преобразования можете обрабатывать по поллингу готовности или по прерыванию от АЦП
Кстати, если измерение напряжения хотите повторять несколько раз, можно настроить цепочку injected каналов (до 4), при этом канал на самом деле может опрашиваться один, но в JDR1..JDR4 будут результаты отдельных преобразований, и готовность АЦП и прерывание получите в конце
Go to the top of the page
 
+Quote Post
drum1987
сообщение Feb 28 2013, 05:56
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 255
Регистрация: 3-02-09
Из: Омск
Пользователь №: 44 323



C AVR имел дело 2 раза на курсовых в универе...изучать их сейчас это удел старожилов.
ДМА не хочется заводить ибо памяти не так много...но если без этого никак, то сделаю.

Спасибо вам за ответ, сегодня реализую ваше предложение, мой вопрос был скорее: Почему не работает так, как расписано в доках на stm?
Go to the top of the page
 
+Quote Post
koyodza
сообщение Feb 28 2013, 07:52
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 213
Регистрация: 28-02-07
Из: Киев
Пользователь №: 25 744



Цитата(drum1987 @ Feb 28 2013, 07:56) *
C AVR имел дело 2 раза на курсовых в универе...изучать их сейчас это удел старожилов.

Т.е. это всё-таки изучение, но до этого даже AVR не было. Тогда Вам должно быть легче отказаться от приёмов работы, используемых там, но неэффективных здесь.

Цитата(drum1987 @ Feb 28 2013, 07:56) *
мой вопрос был скорее: Почему не работает так, как расписано в доках на stm?

Укажите место "в доках на stm", где описано то, что Вы пытались сделать sm.gif

Вообще использование DMA не обязательно, можно и по прерываниям, частота 100 Гц совсем не высокая, но с буфером даже на 10 значений и DMA может оказаться удобнее, особенно если в конечном итоге Вас интересует только площадь, произведение значения на время. Хотя если Вы так ещё не делали, то по началу может показаться неудобно.
Основной тезис: делайте запуск преобразований по таймеру для regular, а редкие преобразования с софтварным стартом или от другого, более медленного источника для injected, а не наоборот, и будет вам счастье sm.gif
Go to the top of the page
 
+Quote Post
drum1987
сообщение Feb 28 2013, 09:27
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 255
Регистрация: 3-02-09
Из: Омск
Пользователь №: 44 323



Цитата(koyodza @ Feb 28 2013, 14:52) *
Т.е. это всё-таки изучение, но до этого даже AVR не было. Тогда Вам должно быть легче отказаться от приёмов работы, используемых там, но неэффективных здесь.

Век живи - век учись...я даже не знаю когда наступит момент когда я скажу что изучил тот или иной проц. Про приемы работы с AVR понятия не имею, поэтому уже отказался от них.

Цитата(koyodza @ Feb 28 2013, 14:52) *
Укажите место "в доках на stm", где описано то, что Вы пытались сделать sm.gif

AN3116 STM32™’s ADC modes and their applications (http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/CD00258017.pdf)
стр.8 рис.6 это то, что я пытаюсь реализовать.

Цитата(koyodza @ Feb 28 2013, 14:52) *
Основной тезис: делайте запуск преобразований по таймеру для regular, а редкие преобразования с софтварным стартом или от другого, более медленного источника для injected, а не наоборот, и будет вам счастье sm.gif

Уже пробую сделать. Спасибо.
Go to the top of the page
 
+Quote Post

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

 


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


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