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

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> ADC+DMA в STM32F107, Глюк DMA??
akimych
сообщение Feb 13 2011, 11:26
Сообщение #16


Участник
*

Группа: Участник
Сообщений: 72
Регистрация: 7-01-11
Пользователь №: 62 073



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


Go to the top of the page
 
+Quote Post
pr0m
сообщение Feb 13 2011, 16:20
Сообщение #17


Частый гость
**

Группа: Участник
Сообщений: 183
Регистрация: 22-06-05
Из: Таганрог
Пользователь №: 6 233



Цитата(akimych @ Feb 13 2011, 14:26) *
Да не, я пока разбирался, вдруг заметил, что если мерить только vref, наблюдается тоже самое, что я вижу измеряя сигнал.

Это подтверждает мои слова о синфазности помехи. Тогда для эксперименту одновременно в DualMode измерять сигнал и vref, после приведения к vref (result = adc-vref) помеха уйдёт. А вообще, я бы начал с просмотра спектра помех на входе АЦП и в цепях питания.

Цитата(akimych @ Feb 13 2011, 14:26) *
Например, сам мк (влияет не меньше). Хорошо, если алгоритм позволяет засыпать на время измерений.

Я когда скоммутировал ADC2->Channel16(17) на внутреннюю GND, результаты получал 0x003...0x008, внешний аналоговый вход на землю - 0x000...0x002. После калибровки, конечно.
Моему алгоритму будет не до сна, так что ядро будет всегда шуметь. А в скольких битах шумы?

Сообщение отредактировал pr0m - Feb 13 2011, 16:21


--------------------
Правильно поставленный вопрос - половина ответа...
Go to the top of the page
 
+Quote Post
kan35
сообщение Feb 14 2011, 06:19
Сообщение #18


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Работа ADC1 через HT и FT прерывания. Оцифровка 3 каналов в непрерывном режиме
Код
#include "stm32f10x.h"

unsigned short dmaarray[66];


DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;



void Driver_init(void)
{
    GPIO_InitStructure.GPIO_Pin = PIN_ACCTESTON;
    GPIO_Init(PORT_ACCTESTON, &GPIO_InitStructure);
    
    // ADC Init
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

    GPIO_InitStructure.GPIO_Pin = PIN_ACCTESTIN;
    GPIO_Init(PORT_ACCTESTIN, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = PIN_POWERTESTIN;
    GPIO_Init(PORT_POWERTESTIN, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = PIN_CURRENTTESTIN;
    GPIO_Init(PORT_CURRENTTESTIN, &GPIO_InitStructure);
    
    // тактируем DMA    
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    /* DMA1 channel1 configuration ----------------------------------------------*/
    DMA_DeInit(DMA1_Channel1);
    DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
    DMA_InitStructure.DMA_MemoryBaseAddr = (unsigned long)dmaarray;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = sizeof(dmaarray)/sizeof(*dmaarray);
    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);

    DMA_ITConfig(DMA1_Channel1, DMA_IT_TC | DMA_IT_HT, ENABLE);
    
    DMA_Cmd(DMA1_Channel1, ENABLE);
    
    // тактируем ADC
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    RCC_ADCCLKConfig(RCC_PCLK2_Div2);

    // ADC SETUP-----------------------------------------------------------------    
    ADC_Cmd(ADC1, DISABLE);        

    ADC_DeInit(ADC1);
    /* ADCx Configuration (ADC1CLK = 14 MHz) -----------------------------------*/
    ADC_InitTypeDef ADC_InitStructure;
    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);

    /* Enable ADCx */
    ADC_Cmd(ADC1, ENABLE);
    
    ADC_ResetCalibration(ADC1);
    while(ADC_GetResetCalibrationStatus(ADC1) == SET);
    ADC_StartCalibration(ADC1);
    while (ADC_GetCalibrationStatus(ADC1) == SET);

    ADC_RegularChannelConfig(ADC1, PIN_ACCTESTADCCH, 1, ADC_SampleTime_239Cycles5);
    ADC_RegularChannelConfig(ADC1, PIN_POWERTESTADCCH, 2, ADC_SampleTime_239Cycles5);
    ADC_RegularChannelConfig(ADC1, PIN_CURRENTTESTADCCH, 3, ADC_SampleTime_239Cycles5);

    ADC_DMACmd(ADC1, ENABLE);
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);


    NVIC_InitTypeDef NVIC_InitStructure;
    /* Configure and enable ADC interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 15;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

void DMA_Irq_half(void)
{

}

void DMA_Irq_full(void)
{

}


В stm32f10x_it.c:
Код
void DMA_Irq_half(void);
void DMA_Irq_full(void);

void DMA1_Channel1_IRQHandler(void)
{
    if (DMA_GetITStatus(DMA1_IT_HT1) == SET)
    {
        DMA_ClearITPendingBit(DMA1_IT_HT1);
        DMA_Irq_half();
    }
    if (DMA_GetITStatus(DMA1_IT_TC1) == SET)
    {
        DMA_ClearITPendingBit(DMA1_IT_TC1);
        DMA_Irq_full();
    }
}

Go to the top of the page
 
+Quote Post
akimych
сообщение Feb 15 2011, 11:05
Сообщение #19


Участник
*

Группа: Участник
Сообщений: 72
Регистрация: 7-01-11
Пользователь №: 62 073



Цитата
Тогда для эксперименту одновременно в DualMode

Увы, в 100м нет 2х ацп. Иначе бы сразу попробовал.

Цитата
(result = adc-vref)

Не, там вроде надо делить. Если u = vdda/4096*X, то через vref u = 1.2/vref*X, т.е. колебания vdda из формулы убираются. И в принципе это работает, но если мерить одним ацп, то измерения должны быть как можно ближе друг к другу.

На счет ядра я поспешил с выводами, вчера еще раз посмотрел - оно почти не влияет, правда это F100 на 24МГц.

Про измерения Vrefint в даташите сказано, TS_vrefint: тип. 5.1мкс, макс. 17.1мкс
У меня получилось, что оптимально 28.5 тактов. Меньше - кривовато мерит (особенно 1.5), больше - разницы уже не вижу.
Но вообще это Vrefint - штука хитрая оказалось. Его вполне успешно можно мерить и за 1.5 такта, если мерить в составе группы.
Оно вообще как-то странно мерится за 1.5 такта. Хотя оно и не обязано.
Если мерить только его, то полная чушь. Если мерить группой 2 канала (опорное 1ым или 2м), то нормально. Если 3 канала, опорное - 1ое и 3е, то 1ое кривое, 3е нормальное.

Еще столкнулся с похожей проблемой ацп+дма, точнее это не проблема, а скажем так, особенность sm.gif
После переустановки счетчика дма и включения дма, счетчик может уменьшиться на 1. Происходит это видимо только в тому случае, если была попытка ацп что-то оправить в дма, когда буфер уже закончился.
Go to the top of the page
 
+Quote Post

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

 


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


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