TmYAG 0 23 декабря, 2014 Опубликовано 23 декабря, 2014 (изменено) · Жалоба Я начал разбираться с АЦП на STM32F4Discovery. Вычитал, что у АЦП существуют два метода опроса: регулярные каналы и инжектированные каналы. Разницу между ними я более менее понял. Первая группа запись данных в один регистр, вторая группа результат можно записать в один из 4-х регистров. Я стараюсь писать код используя CMSIS. К порту PA1 прикрутил переменный резистор, и по изменению значения должны зажигаться диоды на PD12, 13, 14, 15 но почему-то не работает, подскажите пожалуйста что не так. Код: #include "stm32f4xx.h" uint32_t LED_STATE = 0xF000; uint32_t res; int main() { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN|RCC_AHB1ENR_GPIODEN; RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; //GPIOA->MODER |= 0x0000000C; GPIOD->MODER |= 0x55000000; GPIOD->OTYPER |= 0; GPIOD->OSPEEDR |= 0; ADC1->SMPR2 |= (ADC_SMPR2_SMP1_2 | ADC_SMPR2_SMP1_1 | ADC_SMPR2_SMP1_0); //Задаем время выборки ADC1->CR2 |= ADC_CR2_JEXTSEL; //Преобразование инжектированной группы ADC1->CR2 |= ADC_CR2_JEXTEN; //Разрешаем внешний запуск инжектированной группы ADC1->CR2 |= ADC_CR2_CONT; //Преобразования запускаются одно за другим ADC1->CR1 |= ADC_CR1_JAUTO; ADC1->JSQR |= (1<<15); //Задаем номер канала - ADC1 ADC1->CR2 |= ADC_CR2_ADON;//Теперь включаем АЦП ADC1->CR2 |= ADC_CR2_JSWSTART; //Запуск преобразований while (!(ADC1->SR & ADC_SR_JEOC)); //ждем пока первое преобразование завершится while(1) { res = ADC1->JDR1; if (res > 1024) { GPIOD->ODR=LED_STATE; } } } Поскольку я разбираюсь в режимах преобразования, то я так же пробовал написать код и для регулярных каналов: Код: #include "stm32f4xx.h" uint32_t LED_STATE = 0xF000; int main() { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN|RCC_AHB1ENR_GPIODEN; RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; GPIOA->MODER |= 0x0000000C; GPIOD->MODER |= 0x55000000; GPIOD->OTYPER |= 0; GPIOD->OSPEEDR |= 0; ADC1->SMPR2 |= (ADC_SMPR2_SMP1_2 | ADC_SMPR2_SMP1_1 | ADC_SMPR2_SMP1_0); ADC1->CR2 |= ADC_CR2_EXTSEL; ADC1->CR2 |= ADC_CR2_EXTEN; ADC1->CR2 |= ADC_CR2_CONT; ADC1->SQR1 |= (1<<15); //Задаем номер канала - ADC1 ADC1->CR2 |= ADC_CR2_ADON;//Теперь включаем АЦП ADC1->CR2 |= ADC_CR2_SWSTART; //Запуск преобразований while (!(ADC1->SR & ADC_SR_EOC)); //ждем пока первое преобразование завершится uint32_t res; while(1) { res = ADC1->DR; if (res > 1024) { GPIOD->ODR=LED_STATE; } } } Но он тоже не работает((( Если честно то я ковырял пример отсюда: http://blog.radiotech.kz/blog/52.html И еще ну совсем нубский вопрос. Не могу понять связь между каналом АЦП и пином с которого я хочу снять сигнал. Объясните пожалуйста. Мануал читал. Из него я понял, что на некоторых пинах висит АЦП, так кажется на PA1 висит ADC1, а что с каналами? Спасибо! Изменено 14 августа, 2015 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vovanse 0 23 декабря, 2014 Опубликовано 23 декабря, 2014 · Жалоба Мануал читал. Из него я понял, что на некоторых пинах висит АЦП, так кажется на PA1 висит ADC1, а что с каналами? Так там же и написано, какие каналы. Например "ADC123_IN1". Канал 1 для АЦП 1,2 и 3. Или "АDC12_IN7" - канал 7 для АЦП 1 и 2. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
glags 0 23 декабря, 2014 Опубликовано 23 декабря, 2014 · Жалоба Я начал разбираться с АЦП на STM32F4Discovery. Во первых в первой проге заремарен GPIOA->MODER |= 0x0000000C; во вторых RCC->APB2ENR |= RCC_APB2ENR_ADC1EN | RCC_APB2ENR_SYSCFGEN; надо ещё включить тактирование на SYSCFG в третьих перед каждым забором данных из АЦП его надо запускать как я написал ниже. :) ADC1->CR2 |= ADC_CR2_JSWSTART; while (!(ADC1->SR & ADC_SR_JEOC)); ADC1->SR =0; // Очищаем флаг «преобразование завершено» res = ADC1->JDR1; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TmYAG 0 23 декабря, 2014 Опубликовано 23 декабря, 2014 · Жалоба Во первых в первой проге заремарен GPIOA->MODER |= 0x0000000C; А я пытался сконфигурировать PA1 как альтернативную функцию. в третьих перед каждым забором данных из АЦП его надо запускать как я написал ниже. sm.gif ADC1->CR2 |= ADC_CR2_JSWSTART; while (!(ADC1->SR & ADC_SR_JEOC)); ADC1->SR =0; // Очищаем флаг «преобразование завершено» res = ADC1->JDR1; Изменил код, но проблема не исчезла=( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
glags 0 23 декабря, 2014 Опубликовано 23 декабря, 2014 · Жалоба А я пытался сконфигурировать PA1 как альтернативную функцию. Изменил код, но проблема не исчезла=( Полностью рабочий код инициализации ЦАП: ADC1->CR2 |= ADC_CR2_CONT; //Преобразования запускаются одно за другим ADC1->CR1 |= ADC_CR1_JAUTO | ADC_CR1_SCAN; //Разрешить автопреобразование инжектированной группы и SCAN означает брать номера каналов для сканирования из JSQR. ADC1->JSQR |= (ADC_JSQR_JSQ4_0 ); //Задаем номер канала (выбран ADC1) ADC1->CR2 |= ADC_CR2_ADON;//Теперь включаем АЦП Здесь получаем данные: ADC1->CR2 |= ADC_CR2_JSWSTART; while (!(ADC1->SR & ADC_SR_JEOC)); ADC1->SR =0; // Очищаем флаг «преобразование завершено» res = ADC1->JDR1; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TmYAG 0 23 декабря, 2014 Опубликовано 23 декабря, 2014 · Жалоба Полностью рабочий код инициализации ЦАП: ADC1->CR2 |= ADC_CR2_CONT; //Преобразования запускаются одно за другим ADC1->CR1 |= ADC_CR1_JAUTO | ADC_CR1_SCAN; //Разрешить автопреобразование инжектированной группы и SCAN означает брать номера каналов для сканирования из JSQR. ADC1->JSQR |= (ADC_JSQR_JSQ4_0 ); //Задаем номер канала (выбран ADC1) ADC1->CR2 |= ADC_CR2_ADON;//Теперь включаем АЦП Здесь получаем данные: ADC1->CR2 |= ADC_CR2_JSWSTART; while (!(ADC1->SR & ADC_SR_JEOC)); ADC1->SR =0; // Очищаем флаг «преобразование завершено» res = ADC1->JDR1; Спасибо, большое, завтра попробую в камне. А что насчет регулярных каналов? По идее те же яйца только в профиль. ADC1->CR2 |= ADC_CR2_CONT; //Преобразования запускаются одно за другим ADC1->CR1 |= ADC_CR1_AUTO | ADC_CR1_SCAN; //Разрешить автопреобразование инжектированной группы и SCAN означает брать номера каналов для сканирования из JSQR. ADC1->JSQR |= (ADC_SQR_SQ4_0 ); //Задаем номер канала (выбран ADC1) ADC1->CR2 |= ADC_CR2_ADON;//Теперь включаем АЦП Здесь получаем данные: ADC1->CR2 |= ADC_CR2_SWSTART; while (!(ADC1->SR & ADC_SR_EOC)); ADC1->SR =0; // Очищаем флаг «преобразование завершено» res = ADC1->DR; Наверно так, да? И что на счет конфигурации пина PA1? надо его на альтернативную функцию настраивать? Ведь SYSCFG мы для тактирования альтернативных функций и включали. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
glags 0 23 декабря, 2014 Опубликовано 23 декабря, 2014 (изменено) · Жалоба Там целая наука. Дело в том что инжектированных каналов может быть максимум 4 и каждый имеет свой регистр данных, а регулярных 16 и у них один регистр данных на всех. По этому данные из них можно читать либо по прерыванию (окончание преобразования) либо DMA. Здесь если всё писать то целая статья выйдет. Дело в том что АЦП не сложный, но навороченный. Например он может вызывать прерывания при достижении определённого уровня сигнала на входе и т.д. Скажу только про один момент с инжектированными каналами. В инжектированных каналах есть одно неудобство, когда конфигуришь один канал, то в регистр ADC1->JSQR надо заполнять его как четвёртый. Это многих сбивает с толку. Да SYSCFG мы для тактирования альтернативных функций и включали. Но для конфигурации порта мы их не используем. Просто в модере включаем аналоговый режим. Альтернативные функции касаются таймеров уартсов и прочего что конфигурится в GPIOA->AFR. Здесь на всякий случай :). Просьба, если всё запашет, то отпишитесь. Изменено 24 декабря, 2014 пользователем glags Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TmYAG 0 25 декабря, 2014 Опубликовано 25 декабря, 2014 (изменено) · Жалоба Просьба, если всё запашет, то отпишитесь. #include "stm32f4xx.h" uint32_t LED_STATE = 0xF000; uint32_t res; int main() { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN|RCC_AHB1ENR_GPIODEN; RCC->APB2ENR |= RCC_APB2ENR_ADC1EN|RCC_APB2ENR_SYSCFGEN; GPIOA->MODER |= 0x0000000C; GPIOD->MODER |= 0x55000000; GPIOD->OTYPER |= 0; GPIOD->OSPEEDR |= 0; ADC1->SMPR2 |= (ADC_SMPR2_SMP1_2 | ADC_SMPR2_SMP1_1 | ADC_SMPR2_SMP1_0); //Задаем время выборки ADC1->CR2 |= ADC_CR2_JEXTSEL; //Преобразование инжектированной группы ADC1->CR2 |= ADC_CR2_JEXTEN; //Разрешаем внешний запуск инжектированной группы ADC1->CR2 |= ADC_CR2_CONT; //Преобразования запускаются одно за другим ADC1->CR1 |= ADC_CR1_JAUTO; //ADC1->CR1 |= 0x00000020; ADC1->JSQR |= ADC_JSQR_JSQ4_0; //Задаем номер канала - ADC1 ADC1->CR2 |= ADC_CR2_ADON;//Теперь включаем АЦП while(1) { ADC1->CR2 |= ADC_CR2_JSWSTART; //Запуск преобразований while (!(ADC1->SR & ADC_SR_JEOC)); //ждем пока первое преобразование завершится ADC1->SR = 0; res = ADC1->JDR1; if (res > 1024) { GPIOD->ODR = LED_STATE; } else { GPIOD->ODR ^= LED_STATE; } } } Ну эта бредятина работает в режиме отладки. Проблема была в JSQR. С регулярными каналами пока бьюсь. Потом планирую перейти на прерывания по EOC Вот не могу понять связь между JSQR и PA1 по какому принципу я должен выставлять биты в регистре, чтобы читать именно из этого пина? Ну эта бредятина работает в режиме отладки. Проблема была в JSQR. И не только) GPIOD->ODR ^= LED_STATE; - неправильно) У меня всегда диоды будут вкл))) В общем инжектированные каналы работают) буду ковырять регулярные и прерывания затем. буду ковырять регулярные и прерывания затем. #include "stm32f4xx.h" uint32_t LED_STATE = 0xF000; uint32_t res; int main() { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN|RCC_AHB1ENR_GPIODEN; RCC->APB2ENR |= RCC_APB2ENR_ADC1EN|RCC_APB2ENR_SYSCFGEN; GPIOA->MODER |= 0x0000000C; GPIOD->MODER |= 0x55000000; GPIOD->OTYPER |= 0; GPIOD->OSPEEDR |= 0; ADC1->SMPR2 |= (ADC_SMPR2_SMP1_2 | ADC_SMPR2_SMP1_1 | ADC_SMPR2_SMP1_0); //Задаем время выборки ADC1->CR2 |= ADC_CR2_EXTSEL; //Преобразование инжектированной группы ADC1->CR2 |= ADC_CR2_EXTEN; //Разрешаем внешний запуск инжектированной группы ADC1->CR2 |= ADC_CR2_CONT; //Преобразования запускаются одно за другим ADC1->SQR3 |= ADC_SQR3_SQ1_0; //Задаем номер канала - ADC1 ADC1->CR2 |= ADC_CR2_ADON;//Теперь включаем АЦП while(1) { ADC1->CR2 |= ADC_CR2_SWSTART; //Запуск преобразований while (!(ADC1->SR & ADC_SR_EOC)); //ждем пока первое преобразование завершится ADC1->SR = 0; res = ADC1->DR; if (res > 1024) { GPIOD->ODR = LED_STATE; } else { GPIOD->BSRRH |= (1 << 15)|(1 << 14)|(1 << 13)|(1 << 12); } } } Собственно методом тыка заработали и регулярные каналы))) Изменено 14 августа, 2015 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
glags 0 25 декабря, 2014 Опубликовано 25 декабря, 2014 (изменено) · Жалоба Вот не могу понять связь между JSQR и PA1 по какому принципу я должен выставлять биты в регистре, чтобы читать именно из этого пина? Привожу таблицу зависимости между ADC_JDR1 и JSQR Кол-во каналов (JL) ADC_JDR1 ADC_JDR2 ADC_JDR3 ADC_JDR4 4.................................JSQ1........JSQ2...........JSQ3........JSQ4 3.................................JSQ2........JSQ3...........JSQ4 2.................................JSQ3........JSQ4 1.................................JSQ4 Например если один канал, то заполняем биты JSQ4 и данные будут при этом читатся из ADC1->JDR1 В регистре JSQR 4 бита для JSQ4, если их заполнить 0011 это будет третий канал ADC что соответствует РА3. Изменено 25 декабря, 2014 пользователем glags Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KARLSON 1 14 августа, 2015 Опубликовано 14 августа, 2015 (изменено) · Жалоба Здравствуйте. Я только осваиваю АЦП у STM32. Поставил задачу. Имеем 2 канала IN0 и IN1 ADC1. Сделать регулярными каналами. Значения забирать из регистра данных через прерывания. Когда пробовал с одним каналом, то всё хорошо. Для интереса замерил частоту преобразования ~27 кГц. Когда стал пробовать уже два канала, то по идее частота не должна уменьшиться в 2 раза (если прерывание будет после преобразования каждого канала)? А она уже 14 кГц. Что меня наводит на мысль, что прерывание происходит после 2-х преобразований. Как надо настроить ADC для правильного прерывания? RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // ноги PA0 и PA1 по умолчанию настроены на вход ADC_StructInit(&ADC_InitStructure); ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; //Режим Регулярный Одновременный 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); ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); // прерывание от окончании преобразования ADC_Cmd(ADC1, ENABLE); // включение ADC // настройка канала ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5); // калибровка АЦП ADC_ResetCalibration(ADC1); while (ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while (ADC_GetCalibrationStatus(ADC1)); /* NVIC configuration */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); ADC_SoftwareStartConvCmd(ADC1, ENABLE); прерывание void ADC1_2_IRQHandler (void) { ADC_ClearITPendingBit(ADC1, ADC_IT_EOC); switch(cnt_number_channel_ADC1++) { case 0: ADC1_IN0_Value = ADC1->DR; break; case 1: cnt_number_channel_ADC1 = 0; ADC1_IN1_Value = ADC1->DR; break; default: break; } // передаем FlagADC1 = 1; } Изменено 14 августа, 2015 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 14 августа, 2015 Опубликовано 14 августа, 2015 · Жалоба Что меня наводит на мысль, что прерывание происходит после 2-х преобразований. Как надо настроить ADC для правильного прерывания? Почитать мануал: The EOC bit is set in the ADC_SR register: • At the end of each regular group sequence if the EOCS bit is cleared to 0 • At the end of each regular channel conversion if the EOCS bit is set to 1 PS. В линейке STM32 очень много семейств с совершенно различными АЦП. Лучше указывать конкретный камень. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
uriy 4 14 августа, 2015 Опубликовано 14 августа, 2015 · Жалоба Если хотите читать несколько регулярных каналов то только по DMA. Если не хотите DMA можно использовать инжектированные каналы. Там до 4 каналов можно читать из разных регистров. Вот из моих проектов два канала по DMA. АЦП тактируется от TIM3. Прерывание по DMA по заполнению половины буферы и всего буфера. void InitADC(void) { ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOC, &GPIO_InitStructure); /* DMA1 channel1 configuration ----------------------------------------------*/ //DMA_DeInit(DMA1_Channel1); //DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1->DR; DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; #warning check it DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)adc_buf; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = ADC_BUF_SIZE; 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_ClearITPendingBit(DMA1_IT_HT1); DMA_ClearITPendingBit(DMA1_IT_TC1); DMA_ITConfig(DMA1_Channel1, (DMA_IT_TC | DMA_IT_HT), ENABLE); //DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, ENABLE); /* Enable DMA1 channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_EnableIRQ(DMA1_Channel1_IRQn); /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 2; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channel Configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_239Cycles5); ADC_ExternalTrigConvCmd(ADC1, ENABLE); /* 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)); } void InitTimer3(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; /* TIM3 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* Time base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 23999; /// 1 khz clock required nned to check core frequency TIM_TimeBaseStructure.TIM_Prescaler = 2; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* TIM3 TRGO selection */ TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update); /* TIM3 enable counter */ TIM_Cmd(TIM3, ENABLE); } void DMA1_Channel1_IRQHandler(void) { portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; if (DMA_GetITStatus(DMA1_IT_HT1)) { DMA_ClearITPendingBit(DMA1_IT_HT1); xSemaphoreGiveFromISR(xSemaphoreADC_DMA_HT, &xHigherPriorityTaskWoken ); } if (DMA_GetITStatus(DMA1_IT_TC1)) { DMA_ClearITPendingBit(DMA1_IT_TC1); xSemaphoreGiveFromISR(xSemaphoreADC_DMA_TC, &xHigherPriorityTaskWoken ); } DMA_ClearITPendingBit(DMA1_IT_GL1); portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KARLSON 1 15 августа, 2015 Опубликовано 15 августа, 2015 · Жалоба Камень 103VG То что лучше с DMA и по таймеру это понятно. Просто хотелось бы узнать есть такая возможность (регулярные и по прерыванию) или нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 15 августа, 2015 Опубликовано 15 августа, 2015 · Жалоба Камень 103VG То что лучше с DMA и по таймеру это понятно. Просто хотелось бы узнать есть такая возможность (регулярные и по прерыванию) или нет. В 103 бита EOCS нет. Поэтому EOC только после обработки всех регулярных каналов. Но это не страшно: просто в прерывании настраивайте следующий канал и запускайте одиночное преобразование. А потом переходите на DMA (если кГц преобразований важны). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KARLSON 1 15 августа, 2015 Опубликовано 15 августа, 2015 · Жалоба Теперь всё ясно. Благодарю. Буду переходить на DMA. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться