Salamander 2 30 мая, 2015 Опубликовано 30 мая, 2015 (изменено) · Жалоба Господа, настроил я в STM32F103C8 2 регулярных канала ADC и пустил данные через DMA В результате от одного и того же источника напряжения получаю разные, сильно отличающиеся значения. Где ошибка? #define ADC1_DR_Address ((uint32_t)0x4001244C) //ADC1µÄÊý¾Ý¼Ä´æÆ÷µØÖ· /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ vu16 ADCConvertedValue[2]; uint8_t AsciiBuff[5]; /* Private function prototypes -----------------------------------------------*/ ADC_InitTypeDef ADC_InitStructure; DMA_InitTypeDef DMA_InitStructure; ...................... void adc_Init() { RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // ʹÄÜ MDA ÖØÒª£¡£¡£¡ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);// ʹÄÜ ADC1 ÖØÒª£¡£¡£¡ /*DMA1 channel1 configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel1); //½«DMAµÄͨµÀ1¼Ä´æÆ÷ÖØÉèΪȱʡֵ DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //¶¨ÒåDMAÍâÉè»ùµØַΪADC1 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue; //¶¨ÒåDMAÄÚ´æ»ùµØÖ· DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //ÍâÉè×÷ΪÊý¾Ý´«ÊäµÄÀ´Ô´ DMA_InitStructure.DMA_BufferSize = 2; //¶¨ÒåÖ¸¶¨DMAͨµÀµÄDMA»º´æµÄ´óС DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //ÍâÉèµØÖ·¼Ä´æÆ÷²»±ä DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //ÄÚ´æµØÖ·¼Ä´æÆ÷²»±ä DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //Êý¾Ý¿í¶ÈΪ16λ DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //Êý¾Ý¿í¶ÈΪ16λ DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //¹¤×÷ÔÚÑ»·»º´æģʽ DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMAͨµÀ1ÓµÓиßÓÅÏȼ¶ DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMAͨµÀ1ûÓÐÉèÖÃΪÄÚ´æµ½ÄÚ´æ´«Êä DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable DMA1 channel1 */ DMA_Cmd(DMA1_Channel1, 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 = 2; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channel_8,configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5); //ת»»Ê±¼äΪ17.1US ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2, ADC_SampleTime_55Cycles5); //ת»»Ê±¼äΪ17.1US /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* 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); } А дальше добавляю ADCConvertedValue в окно watch отладчика и мониторю. В результате разные данные на канала 8 и 9. Добавлю - в случае нулевого напряжение - данные правильные. ГДе косяк? И еще вопрос - код не мой, но везде, где я натыкался на подобный код, - DMA_MemoryBaseAddr 32 битный, а переменная ADCConvertedValue - 16-ти битная. Почему так? Изменено 30 мая, 2015 пользователем Salamander Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 31 мая, 2015 Опубликовано 31 мая, 2015 · Жалоба Так может проблема не в коде а в наводках на канал ADC и потому ваши показания прыгают. Попробуйте перемычку на vref+ Показания стабилизируются? На нуле у вас все стабильно как я понимаю. 16ти битная переменная потому что результат 12ти битного АЦП нет смысла хранить в 32бит переменной. А base addr наверно от того что DMA работает только с выровненными данными. DMA ориентирован на работу с большими массивами данных оптом, поэтому никого не волнует что вы теряете место впустую - лес рубят, щепки летят:) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 68 31 мая, 2015 Опубликовано 31 мая, 2015 · Жалоба И еще вопрос - код не мой, но везде, где я натыкался на подобный код, - DMA_MemoryBaseAddr 32 битный, а переменная ADCConvertedValue - 16-ти битная. Почему так? потому что DMA_MemoryBaseAddr это абсолютный адрес в памяти(а память в STM32 может адресовать до 4Гб, отсюда 32 разряда), а ADCConvertedValue - это переменная которая располагается по этому адресу и содержит максимум 12-тиразрядное значение . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dart191 0 5 июня, 2015 Опубликовано 5 июня, 2015 · Жалоба Попробуйте настроить DMA так, чтобы он опрашивал не в циклическом режиме и посмотрите на результаты, т.е. Время от времени его запускайте его таймером например и если все в порядке значит, скорей всего АЦП не успевает выдавать верные результаты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться