24.08.2016, 14:54
|
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
stm32F030f4 + ADC + DMA
Добрый день. Настроил ДМА+АЦП. В отладке ДМА пишет данные в массив для АЦП данных и всё. Не заходит в прерывание по DMA1_Channel1_IRQHandler. Взял пример из интернета с гитхаба. Но наверно чтото не так скопипастил... https://github.com/pyrohaz/STM32F0-A.../master/main.c
В ISR биты GIF1, TCIF1,HTIF1 устанавливаются....
Неполучается разобраться почему в прерывание не заходит..... Подскажите плиз...
PHP код:
|
//Variable to store current conversion status volatile uint8_t Converted = 0;
//Variable to store conversions uint16_t Conversions[2];
void DMA1_Channel1_IRQHandler(void){ if(DMA_GetITStatus(DMA1_IT_TC1)){ DMA_ClearITPendingBit(DMA1_IT_TC1); Converted = 1; } }
void ADC_DMA_ini(void) {
GPIO_InitTypeDef Pin; DMA_InitTypeDef DMA_User; NVIC_InitTypeDef NVIC_User; ADC_InitTypeDef ADC_Init_user; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); Pin.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6; Pin.GPIO_Mode = GPIO_Mode_AN; Pin.GPIO_Speed = GPIO_Speed_2MHz; Pin.GPIO_OType = GPIO_OType_PP; Pin.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &Pin); /* ADC1 DeInit */ ADC_DeInit(ADC1); /* Initialize ADC structure */ ADC_StructInit(&ADC_Init_user); ADC_Init_user.ADC_Resolution = ADC_Resolution_12b; ADC_Init_user.ADC_ContinuousConvMode = DISABLE; ADC_Init_user.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //ADC_Init_user.ADC_ExternalTrigConv = ADC_Init_user.ADC_DataAlign = ADC_DataAlign_Right; ADC_Init_user.ADC_ScanDirection = ADC_ScanDirection_Upward; ADC_Init( ADC1, &ADC_Init_user); ADC_Cmd(ADC1, ENABLE); ADC_DMACmd(ADC1, ENABLE); //ADC_ChannelConfig(ADC1, ADC_Channel_3,ADC_SampleTime_1_5Cycles); //ADC1-›CHSELR = ADC_CHSELR_CHSEL3 | ADC_CHSELR_CHSEL4; //ADC_ChannelConfig(ADC1, ADC_Channel_4,ADC_SampleTime_71_5Cycles); //ADC_ContinuousModeCmd(ADC1, ENABLE); //Configure the corresponding DMA stream for the ADC DMA_User.DMA_BufferSize = 2; //Three variables DMA_User.DMA_DIR = DMA_DIR_PeripheralSRC; //ADC peripheral is the data source DMA_User.DMA_M2M = DMA_M2M_Disable; //Disable memory to memory mode DMA_User.DMA_MemoryBaseAddr = (uint32_t) &Conversions[0]; //Pointer to variables array DMA_User.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //'Conversions' is 16bits large (HWord) DMA_User.DMA_MemoryInc = DMA_MemoryInc_Enable; //Enable memory increment DMA_User.DMA_Mode = DMA_Mode_Normal; //Non circular DMA mode DMA_User.DMA_PeripheralBaseAddr = (uint32_t) &ADC1-›DR; //Pointer to ADC data register! DMA_User.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //ADC1-›DR is 16bits! DMA_User.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //Disable peripheral increment DMA_User.DMA_Priority = DMA_Priority_Low; //A low priority DMA stream, not a big deal here! DMA_Init(DMA1_Channel1, &DMA_User); //Enable transfer complete interrupt for DMA1 channel 1 DMA_ClearITPendingBit(DMA1_IT_TC1); DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); DMA_Cmd(DMA1_Channel1, ENABLE);
NVIC_User.NVIC_IRQChannel = DMA1_Channel1_IRQn; NVIC_User.NVIC_IRQChannelPriority = 1; NVIC_User.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_User);
//Configure channels to be converted ADC_ChannelConfig(ADC1, ADC_Channel_5, ADC_SampleTime_239_5Cycles); ADC_ChannelConfig(ADC1, ADC_Channel_6, ADC_SampleTime_239_5Cycles); //ADC_ChannelConfig(ADC1, ADC_Channel_2, ADC_SampleTime_239_5Cycles);
//Wait for ADC to be ready! while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY)); }
int main(void) { RCC_DeInit(); PLL52(); RCC_AdjustHSICalibrationValue(19); Init_PORT();
ADC_DMA_ini(); while (1) { //Disable the DMA channel DMA_Cmd(DMA1_Channel1, DISABLE);
//Re-initialize channel DMA_Init(DMA1_Channel1, &DMA_User);
//Enable the DMA channel DMA_Cmd(DMA1_Channel1, ENABLE); //Start conversion ADC_StartOfConversion(ADC1);
//Wait for conversion while(!Converted);
//Reset converted flag (placement of breakpoint! Converted = 0; } }
|
Последний раз редактировалось miwutka; 24.08.2016 в 15:13.
|
|
|
|
24.08.2016, 15:24
|
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: stm32F030f4 + ADC + DMA
Блин разобрался. Недобавил хидер misc.h Компилятор почемуто не показал ошибку. Как АЦП не добавил хидер так ругался.... Сорри за беспокойство.
|
|
|
|
24.08.2016, 16:35
|
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: stm32F030f4 + ADC + DMA
Решил посмотреть как быстро работает АЦП. Сделал вот такой код. АЦП по ДМА работает. Сканирует два канала.
PHP код:
|
void DMA1_Channel1_IRQHandler(void){
if(DMA_GetITStatus(DMA1_IT_TC1)){
DMA_ClearITPendingBit(DMA1_IT_TC1);
Converted = 1;
PA2(1);
SummValueADC[0]+=Conversions[0];
SummValueADC[1]+=Conversions[1];
PA2(0);
Num_Samples++;
}
}
|
Ножка РА2 настроена на выход. Получается 75.59 кГц. Получается максимальная скорость АЦП для 2-х каналов 75 000 измерений в секунду?? Или я чтото недонастроил? В даташите написано "ADC conversion time: 1.0 μs for 12-bit resolution (1 MHz)" Как это понимать, или при каких условиях этого можно достич? Я так понимаю что 1 канал конвертируется за 1 мкс. Значит два канала должно конвертировать за 2 мкс. Должна быть частота 500 кГц примерно, а у меня 75 кГц. Объясните плиз .....
|
|
|
|
24.08.2016, 17:54
|
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: stm32F030f4 + ADC + DMA
Перенастроил ДМА в DMA_User.DMA_Mode = DMA_Mode_Circular; Я так понимаю что он циклично по кругу теперь работает. И вынес строки
PHP код:
|
//Disable the DMA channel DMA_Cmd(DMA1_Channel1, DISABLE);
//Re-initialize channel DMA_Init(DMA1_Channel1, &DMA_User);
//Enable the DMA channel DMA_Cmd(DMA1_Channel1, ENABLE);
|
перед основным циклом.... Частота поднялась до 97кГц, сканирование 2-ух каналов. 123 кГц если 1 канал сканировать... Явно чтото еще не так настроено.....
Последний раз редактировалось miwutka; 24.08.2016 в 18:07.
|
|
|
|
24.08.2016, 18:27
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.03.2010
Сообщений: 2,897
Сказал спасибо: 498
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
|
Re: stm32F030f4 + ADC + DMA
Сообщение от miwutka
|
Объясните плиз .....
|
"ADC_SampleTime_239_5Cycles" - эта константа задает значение в регистре ADC_SMPR, время семплирования - 239,5 тактов ADC. Самый медленный режим.
|
|
|
|
24.08.2016, 18:34
|
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: stm32F030f4 + ADC + DMA
AR_Favorit, забыл в первом посту исправить. Семплирование выставлено самое быстрое сейчас - ADC_SampleTime_1_5Cycles.
|
|
|
|
24.08.2016, 18:35
|
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: stm32F030f4 + ADC + DMA
при ADC_SampleTime_239_5Cycles сканирование с частотой 35 кГц.....
|
|
|
|
24.08.2016, 18:48
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.03.2010
Сообщений: 2,897
Сказал спасибо: 498
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
|
Re: stm32F030f4 + ADC + DMA
Тратится время на перезапуск ADC.
ADC_Init_user.ADC_ContinuousConvMode = DISABLE; сменить на ENABLE (АЦП безостановочно шлепает преобразования), и ADC_StartOfConversion(ADC1); тоже вынести из цикла...
|
|
|
|
24.08.2016, 19:17
|
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: stm32F030f4 + ADC + DMA
Сообщение от AR_Favorit
|
Тратится время на перезапуск ADC.
ADC_Init_user.ADC_ContinuousConvMode = DISABLE; сменить на ENABLE (АЦП безостановочно шлепает преобразования), и ADC_StartOfConversion(ADC1); тоже вынести из цикла...
|
Так прерывание от ДМА 1 раз сработало и всё...
|
|
|
|
24.08.2016, 19:36
|
|
Почётный гражданин KAZUS.RU
Регистрация: 05.07.2009
Адрес: Запорожье
Сообщений: 1,531
Сказал спасибо: 309
Сказали Спасибо 53 раз(а) в 48 сообщении(ях)
|
Re: stm32F030f4 + ADC + DMA
Добавил эту строчку в функции инициализации АЦП и ДМА - ADC1-›CFGR1 |= ADC_CFGR1_DMACFG; - АЦП начал работать, но в прерывание DMA1_Channel1_IRQHandler не заходит. Видимо это максимум что может. В инете у людей 1 МГц дает непонятно как. Код один и тотже..... И всё что в основном цикле тоже не выполняется.
Последний раз редактировалось miwutka; 24.08.2016 в 19:43.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 19:22.
|
|