Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

stm32f4 cmsis ADC прерывание

Вс дек 29, 2019 14:59:22

void inits_adc(void)
{
RCC->AHB1ENR|=RCC_AHB1ENR_GPIOAEN;
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
GPIOA->MODER |= GPIO_MODER_MODER0_1;
GPIOA->MODER |= GPIO_MODER_MODER0_0;
GPIOA->PUPDR &=~GPIO_PUPDR_PUPDR0_1;
GPIOA->PUPDR &=~ GPIO_PUPDR_PUPDR0_0;


ADC->CCR&= ~ ADC_CCR_ADCPRE;
// ADC1->CR1|= ADC_CR1_EOCIE;

// ADC1->CR2 |=ADC_CR2_CONT;
ADC1->CR2 |=ADC_CR2_EXTEN;

ADC1->CR2|=ADC_CR2_EXTSEL;
ADC1->SMPR2 &= ~(ADC_SMPR2_SMP1_2 | ADC_SMPR2_SMP1_1 | ADC_SMPR2_SMP1_0);

/* номер канал */
ADC1->SQR3 &=~ ADC_SQR3_SQ1_0; //1 IN0
ADC1->SQR3 &= ~ ADC_SQR3_SQ3_1; //0
ADC1->SQR3 &= ~ADC_SQR3_SQ1_2; //0
ADC1->SQR3 &=~ ADC_SQR3_SQ1_3; //0
ADC1->SQR3 &= ~ADC_SQR3_SQ1_4;//0
// ADC1->CR2 |=ADC_CR2_CONT;
ADC1->CR1|= ADC_CR1_EOCIE;
//ADC1->SR=0;


//NVIC_EnableIRQ (ADC_IRQn);
ADC1->CR2 |= ADC_CR2_ADON;
NVIC_EnableIRQ (ADC_IRQn);

}


void inits_adc2(void)
{

}
void inits_GPIOC(void)
{
RCC->AHB1ENR|=RCC_AHB1ENR_GPIOCEN;


GPIOC->MODER &=~ GPIO_MODER_MODER13_1;
GPIOC->MODER |= GPIO_MODER_MODER13_0;
GPIOC ->OTYPER &=~GPIO_OTYPER_OT13;
//бит0 определяет скорость работы GPIO
GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR13_1; //бит1
GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR13_0;
GPIOC->PUPDR |=GPIO_PUPDR_PUPDR13_1;
GPIOC->PUPDR &=~ GPIO_PUPDR_PUPDR13_0;
/* настройка на вход */

// RCC->AHB1ENR|=RCC_AHB1ENR_GPIOCEN;

GPIOC->MODER &=~ GPIO_MODER_MODER0_1;
GPIOC->MODER &=~ GPIO_MODER_MODER0_0;
GPIOC ->OTYPER &=~GPIO_OTYPER_OT0;
//бит0 определяет скорость работы GPIO
GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR0_1; //бит1
GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR0_0;
GPIOC->PUPDR &=~ GPIO_PUPDR_PUPDR0_1;
GPIOC->PUPDR |= GPIO_PUPDR_PUPDR0_0;

GPIOC->MODER &=~ GPIO_MODER_MODER1_1;
GPIOC->MODER |= GPIO_MODER_MODER1_0;
GPIOC ->OTYPER &=~GPIO_OTYPER_OT1;
//бит0 определяет скорость работы GPIO
GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR1_1; //бит1
GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR1_0;
GPIOC->PUPDR |=GPIO_PUPDR_PUPDR1_1;
GPIOC->PUPDR &=~ GPIO_PUPDR_PUPDR1_0;
}

int main(void)
{
inits_GPIOC();
//inits_adc();


//ADC1->CR2 |= ADC_CR2_SWSTART;
//inits_timer1();
// inits_timer3();
// inits_timer5();
//inits_timer3();
inits_adc();

ADC1->CR2|= ADC_CR2_SWSTART;

while(1)
{


//ADC1->CR2 |= ADC_CR2_SWSTART; //Запуск преобразований
// while (!(ADC1->SR & ADC_SR_EOC)); //ждем пока первое преобразование завершится
//ADC1->SR &=~ADC_SR_EOC ;
// ADC1->SR = 0;
//adc_data = ADC1->DR;

// if(adc_data > 2024)
// {
// GPIOC->ODR|=1<<13;
// GPIOC->BSRR |= GPIO_BSRR_BS13;
// }
// else
// {
// // GPIOC->ODR&=~1<<13;
// GPIOC->BSRR |= GPIO_BSRR_BR13;
// }
}
}
void adc_IRQhanler(void)
{
if(ADC1->SR & ADC_SR_EOC)
{
ADC1->SR &=~ ADC_SR_EOC;
// ADC1->SR = 0;
adc_data = ADC1->DR;
if(adc_data>2045)
{
GPIOC-> BSRR |=GPIO_BSRR_BS13;
}
else
{
GPIOC-> BSRR |=GPIO_BSRR_BR13;
}
}
}
работает в основном цикле не работает в прерывании в чём дело не понимаю

Re: stm32f4 cmsis ADC прерывание

Пн дек 30, 2019 14:48:50

ivan dimir писал(а):работает в основном цикле не работает в прерывании в чём дело не понимаю
казнить нельзя помиловать __enable_irq ();

Re: stm32f4 cmsis ADC прерывание

Пн дек 30, 2019 17:48:22

и так тоже не работает ни ацп ни таймер

Re: stm32f4 cmsis ADC прерывание

Пн дек 30, 2019 18:20:51

казнить нельзя помиловать __enable_irq ();
У Cortex-M они включены по умолчанию при включении.

и так тоже не работает ни ацп ни таймер
Информацию из вас клещами тянуть? Какая среда разработки, какой стартап, какой режим компилятора? Я то может там банальный extern "C"...

Re: stm32f4 cmsis ADC прерывание

Пн дек 30, 2019 19:09:19

ivan dimir, сброс флага неверный.
Код:
ADC1->SR &=~ ADC_SR_EOC;
исправте на
Код:
ADC1->SR  =~ ADC_SR_EOC;
Это конечно не решит Вашу проблему, но убережет от новых.

Re: stm32f4 cmsis ADC прерывание

Пн дек 30, 2019 19:15:30

extern "C"... отключён среда компиляции atolic truestudio проект создаю с нуля.включаю прерывание по ацп и отключается таймер.Вместе таймера работают как часики.Когда включаешь ацп не в прерывании всё хорошо работает.Проект создавал в С не в С++.startap_stm32f407xx.s. режим компилятора?оптимизация?

Добавлено after 1 minute 59 seconds:
ADC1->SR &=~ ADC_SR_EOC; а почему в Hal это работает?

Re: stm32f4 cmsis ADC прерывание

Пн дек 30, 2019 19:34:07

ivan dimir писал(а):а почему в Hal это работает?
Во вторых, &= это чтение, побитовое И, запись, т.е. лишние команды без необходимости (запись 1 в регистр статуса никак не влияет на содержимое).
А во первых, если между чтением и записью установится другой флаг в данном регистре, вы его сбросите, так и не узнав, что он был установлен. Заколебешься потом искать, почему, в редких случаях не вызывается прерывание.

Если в ХАЛе так, значит там косяк.

Добавлено after 1 minute 20 seconds:
Отладчик работает? Тормознитесь где-нибудь и поглядите, что в регистрах SR. От этого уже можно сделать какой-либо вывод.

Re: stm32f4 cmsis ADC прерывание

Пн дек 30, 2019 20:05:59

/*
* main.c
*
* Created on: 29 жовт. 2019 р.
* Author: Ivan
*/

#include"main.h"
//#include "stm32f103xb.h"
//#include "stm32f1xx.h"
volatile unsigned int flag=0;
volatile unsigned int adc_data=0;
void ADC1_2_IRQHandler()
{
while (!(ADC1->SR & ADC_SR_EOC)); //ждем пока первое преобразование завершится
ADC1->SR &=~ ADC_SR_EOC;
adc_data = ADC1->DR;

if(adc_data > 2024)
{

GPIOC->BSRR |= GPIO_BSRR_BS13;
}
else
{

GPIOC->BSRR |= GPIO_BSRR_BR13;
}
}


void init_ADC1(void)
{

RCC->APB2ENR|=RCC_APB2ENR_IOPCEN;
GPIOC->CRH&=~GPIO_CRH_CNF13;
GPIOC->CRH|= GPIO_CRH_MODE13_1;
RCC->CFGR &=~ RCC_CFGR_ADCPRE;

RCC->APB2ENR|=RCC_APB2ENR_IOPAEN;

GPIOA->CRL&=~GPIO_CRL_CNF1;
GPIOA->CRL&=~ GPIO_CRL_MODE1;

RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
RCC->CFGR |= RCC_CFGR_ADCPRE_DIV2;

//подаем тактирование АЦП
ADC1->CR2 |= ADC_CR2_RSTCAL;
while (!(ADC1->CR2 & ADC_CR2_RSTCAL))
{
}
ADC1->CR2 |= ADC_CR2_CAL;
while (!(ADC1->CR2 & ADC_CR2_RSTCAL))
{
}

ADC1->CR2 |=ADC_CR2_CONT;//включить АЦП
ADC1->CR2 |= ADC_CR2_EXTSEL;

ADC1->CR2 |= ADC_CR2_EXTTRIG;


ADC1->SQR3 |= ADC_SQR3_SQ1_0; //1 IN1
ADC1->SQR3 &= ~ ADC_SQR3_SQ1_1; //0
ADC1->SQR3 &= ~ADC_SQR3_SQ1_2; //0
ADC1->SQR3 &=~ ADC_SQR3_SQ1_3; //0
ADC1->SQR3 &= ~ADC_SQR3_SQ1_4;

ADC1->SMPR2 &=~ ADC_SMPR2_SMP1_0; //1
ADC1->SMPR2&=~ADC_SMPR2_SMP1_1; //1
ADC1->SMPR2 &=~ ADC_SMPR2_SMP1_2; //1
}

int main(void)
{

//inits_GPIO();

init_ADC1();
ADC1->CR1|= ADC_CR1_EOCIE;
ADC1->CR2 |= ADC_CR2_ADON;
NVIC_EnableIRQ ( ADC1_2_IRQn);
ADC1->CR2 |= ADC_CR2_SWSTART;
while(1)
{


}
}
вот работающий код в stm32f103

Добавлено after 1 minute 2 seconds:
Я думаю никаких косяков нет.Ваш вариант не работает

Re: stm32f4 cmsis ADC прерывание

Пн дек 30, 2019 20:10:31

ivan dimir писал(а):Я думаю никаких косяков нет.Ваш вариант не работает
Я объяснил почему. Что значит не работает? Сброса флага нет или что?

З.Ы. Для кода есть специальные тэги и спрячьте его под спойлер. Нечитаемо же.

Re: stm32f4 cmsis ADC прерывание

Пн дек 30, 2019 20:28:10

/*
* main.c
*
* Created on: 2 лист. 2019 р.
* Author: Ivan
*/


#include "main.h"

volatile unsigned char flag=0;
volatile unsigned char program=0;
//uint32_t adc_data = 0;
volatile unsigned int adc_data=0;
volatile unsigned int pauza1=0;
volatile unsigned int pauza2=0;
void pauza (int T)//ввод самой паузы(программы) она написана отдельно и введеннием #include "paua.h"можно писать в основном цыкле pauza()с вводом целой переменной T
{
int i=0;//введение целойперемменой i
char t=0;// введение вещественной переменной t считает такты микроконтролера
for(i=0;i<T;t++) //програмама в цыкле
{
if(t==255)i=i+1;// условия одного цыкла счёта пределитель i определяется регистром TCCR2 определяется 0.1.2 битами это делителем частоты работы таймера
}
}

void TIM3_IRQHandler(void)
{
// TIM1->DIER&=~TIM_DIER_UIE;
TIM3->SR &= ~ TIM_SR_UIF;
pauza1++;
if(pauza1>10)
{
GPIOC->ODR|=GPIO_ODR_OD1;
// GPIOC-> BSRR |=GPIO_BSRR_BS1;
}
if(pauza1>20)
{
GPIOC->ODR&=~GPIO_ODR_OD1;
// GPIOC-> BSRR |=GPIO_BSRR_BR1;
pauza1=0;
}

// GPIOC->ODR ^= GPIO_ODR_OD1;
}
void TIM5_IRQHandler(void)
{
//TIM2->DIER&=~TIM_DIER_UIE;
if(TIM5->SR& TIM_SR_UIF)
{
TIM5->SR &= ~ TIM_SR_UIF;
pauza2++;
//if(!(GPIOC->IDR& GPIO_IDR_ID0))
//{
// pauza(20);
if(pauza2>10)
{
// GPIOC-> BSRR |=GPIO_BSRR_BS13;
}
if(pauza2>20)
{
// GPIOC-> BSRR |=GPIO_BSRR_BR13;
pauza2=0;
}
//TIM3->SR &= ~ TIM_SR_UIF;
}
}

//void adc_IRQhanler(void)
//{
// uint16_t adc_data = 0;
//adc_data = ADC1->DR;
// if(ADC1->SR & ADC_SR_EOC)
// {
// ADC1->SR&=~ ADC_SR_EOC;
// ADC1->SR = 0;
// adc_data = ADC1->DR;
// if(adc_data > 2024)
// {
// GPIOC->ODR|=(1<<13);
// GPIOC->BSRR |= GPIO_BSRR_BS13;
// }
// else
// {
// GPIOC->ODR&=~(1<<13);
// GPIOC->BSRR |= GPIO_BSRR_BR13;
// }



//ADC1->SR &=~ ADC_SR_EOC;
// }
//}
void PROGRAM(void)
{
//GPIOC-> BSRR |=GPIO_BSRR_BS1;
// pauza(2000);
// GPIOC-> BSRR |=GPIO_BSRR_BR1;
// pauza(2000);
}
void inits_timer1(void)
{
RCC->APB2ENR |=RCC_APB2ENR_TIM1EN;

TIM1->PSC = 2000-1;//24000 - 1; // Настраиваем делитель что таймер тикал 1000 раз в секунду
TIM1->ARR = 10 ;

TIM1->DIER |= TIM_DIER_UIE;//устанавливаем флаг 1по таймеру
TIM1->EGR = TIM_EGR_UG;
TIM1->CR1|= TIM_CR1_CEN;//разрешаем работу таймера
NVIC_EnableIRQ (TIM1_UP_TIM10_IRQn );
}
void inits_timer5(void)
{
RCC->APB1ENR |=RCC_APB1ENR_TIM5EN;

TIM5->PSC = 3500 - 1; // Настраиваем делитель что таймер тикал 1000 раз в секунду

TIM5->ARR = 100 ;


TIM5->DIER = TIM_DIER_UIE;//устанавливаем флаг 1по таймеру
TIM5->EGR = TIM_EGR_UG;
TIM3->SR =0;
TIM5->CR1|= TIM_CR1_CEN;//разрешаем работу таймера
// NVIC_SetPriority(TIM5_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ ( TIM5_IRQn );

}
void inits_timer3(void)
{




RCC->APB1ENR |=RCC_APB1ENR_TIM3EN;

TIM3->PSC=3500-1; // Настраиваем делитель что таймер тикал 1000 раз в секунду

TIM3->ARR=100;

TIM3->DIER = TIM_DIER_UIE;
TIM3->EGR=TIM_EGR_UG;
TIM3->SR =0;



TIM3->CR1|= TIM_CR1_CEN;
// NVIC_SetPriority(TIM3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(TIM3_IRQn);
}

void inits_adc(void)
{


RCC->AHB1ENR|=RCC_AHB1ENR_GPIOAEN;

GPIOA->MODER |= GPIO_MODER_MODER0_1;
GPIOA->MODER |= GPIO_MODER_MODER0_0;
GPIOA->PUPDR &=~GPIO_PUPDR_PUPDR0_1;
GPIOA->PUPDR &=~ GPIO_PUPDR_PUPDR0_0;

RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
ADC->CCR|= ADC_CCR_ADCPRE;

ADC1->CR2 |=ADC_CR2_CONT;

ADC1->CR2|=ADC_CR2_EXTSEL;
ADC1->CR2 |=ADC_CR2_EXTEN;
ADC1->SMPR2 &= ~(ADC_SMPR2_SMP1_2 | ADC_SMPR2_SMP1_1 | ADC_SMPR2_SMP1_0);

/* номер канал */
ADC1->SQR3 &=~ ADC_SQR3_SQ1_0; //1 IN0
ADC1->SQR3 &= ~ ADC_SQR3_SQ3_1; //0
ADC1->SQR3 &= ~ADC_SQR3_SQ1_2; //0
ADC1->SQR3 &=~ ADC_SQR3_SQ1_3; //0
ADC1->SQR3 &= ~ADC_SQR3_SQ1_4;//0
// ADC1->CR2 |=ADC_CR2_CONT;
// ADC1->CR1 = ADC_CR1_EOCIE;
//ADC1->SR=0;
// ADC1->SMPR2 &= ~(ADC_SMPR2_SMP1_2 | ADC_SMPR2_SMP1_1 | ADC_SMPR2_SMP1_0);
// NVIC_SetPriority(ADC_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
//NVIC_EnableIRQ (ADC_IRQn);


//NVIC_EnableIRQ (ADC_IRQn);
ADC1->CR2 |= ADC_CR2_ADON;
// NVIC_SetPriority(ADC_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
// NVIC_EnableIRQ (ADC_IRQn);
}


void inits_adc2(void)
{

}
void inits_GPIOC(void)
{
RCC->AHB1ENR|=RCC_AHB1ENR_GPIOCEN;


GPIOC->MODER &=~ GPIO_MODER_MODER13_1;
GPIOC->MODER |= GPIO_MODER_MODER13_0;
GPIOC ->OTYPER &=~GPIO_OTYPER_OT13;
//бит0 определяет скорость работы GPIO
GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR13_1; //бит1
GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR13_0;
GPIOC->PUPDR |=GPIO_PUPDR_PUPDR13_1;
GPIOC->PUPDR &=~ GPIO_PUPDR_PUPDR13_0;
/* настройка на вход */

// RCC->AHB1ENR|=RCC_AHB1ENR_GPIOCEN;

GPIOC->MODER &=~ GPIO_MODER_MODER0_1;
GPIOC->MODER &=~ GPIO_MODER_MODER0_0;
GPIOC ->OTYPER &=~GPIO_OTYPER_OT0;
//бит0 определяет скорость работы GPIO
GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR0_1; //бит1
GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR0_0;
GPIOC->PUPDR &=~ GPIO_PUPDR_PUPDR0_1;
GPIOC->PUPDR |= GPIO_PUPDR_PUPDR0_0;

GPIOC->MODER &=~ GPIO_MODER_MODER1_1;
GPIOC->MODER |= GPIO_MODER_MODER1_0;
GPIOC ->OTYPER &=~GPIO_OTYPER_OT1;
//бит0 определяет скорость работы GPIO
GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR1_1; //бит1
GPIOC->OSPEEDR &=~ GPIO_OSPEEDER_OSPEEDR1_0;
GPIOC->PUPDR |=GPIO_PUPDR_PUPDR1_1;
GPIOC->PUPDR &=~ GPIO_PUPDR_PUPDR1_0;
}

int main(void)
{
// int adc_data=0;
inits_GPIOC();
//inits_adc();


//ADC1->CR2 |= ADC_CR2_SWSTART;
//inits_timer1();
inits_timer3();
inits_timer5();
//inits_timer3();
inits_adc();
//ADC1->CR1 |= ADC_CR1_EOCIE;
// ADC1->CR2 |= ADC_CR2_ADON;
// NVIC_EnableIRQ (ADC_IRQn);
//ADC1->CR2|= ADC_CR2_SWSTART;

// __enable_irq ();

while(1)
{
ADC1->CR2 |= ADC_CR2_SWSTART;

//ADC1->CR2 |= ADC_CR2_SWSTART; //Запуск преобразований
while (!(ADC1->SR & ADC_SR_EOC)); //ждем пока первое преобразование завершится
ADC1->SR &=~ADC_SR_EOC ;
// ADC1->SR = 0;
adc_data = ADC1->DR;

if(adc_data > 2024)
{
// GPIOC->ODR|=1<<13;
GPIOC->BSRR |= GPIO_BSRR_BS13;
}
else
{
// GPIOC->ODR&=~1<<13;
GPIOC->BSRR |= GPIO_BSRR_BR13;
}
}
}
вот рабочий код правда ацп работает не в прерывании.

Добавлено after 6 minutes 2 seconds:
что такое теги я нерусский и не понимаю учител.Я вам показал три кода один неработает вы специалисты что можете сказать.Ваши аргумент не убедителен.Ну вообщем спасибо.Наверное в HAL прийдётся ещё посидеть.

Re: stm32f4 cmsis ADC прерывание

Чт янв 02, 2020 19:26:09

Ау коты где вы?.С Новым Годом!

Re: stm32f4 cmsis ADC прерывание

Пт янв 10, 2020 04:52:35

Код в сообщениях под спойлер прятать нужно.

Re: stm32f4 cmsis ADC прерывание

Вс янв 12, 2020 22:02:40

...я нерусский ...

:))) улыбнуло
кто же ты Ванюша?
(? риторический, отвечать не надо)

"... void adc_IRQhanler(void)..." - здесь все правильно?

Re: stm32f4 cmsis ADC прерывание

Вс мар 29, 2020 22:02:45

гагаузский

Re: stm32f4 cmsis ADC прерывание

Пн мар 30, 2020 12:25:39

Вот пример с живого проекта
Спойлер
Код:
/*----------
* файл adc.c
* работа с АЦП
*----------*/

#include   "stm32f4xx.h"
#include   "stm32f446_it.h"
#include   "adc.h"
#include   "messages.h"
#include   "button.h"
#include   "global.h"



#define   ADC_START_PERIOD          (100)   // период запуска АЦП
#define   BATTERY_WAIT_TO_START     (1000)   // время между включением питания и включением делителя напряжения батареи
#define   BATTERY_WAIT_TO_MEASURE   (1000)   // время между включением делителя и началом слежения за батареей
#define   BATTERY_PERIOD             (1000)   // период запуска программы напряжения батареи
#define   V_REF                         (322)   // напряжение питания 3,20В
#define   N_MAX                         (0x0FFF)   // максимальное число от АЦП


// определения портов контроллера
#define      V_ACC_ON_0      (GPIOB->BSRR = GPIO_BSRR_BR_2)
#define      V_ACC_ON_1      (GPIOB->BSRR = GPIO_BSRR_BS_2)
#define      V_ACC_ON(a)      (a ?  V_ACC_ON_1 : V_ACC_ON_0)


int16_t         adc_buttons;   // значение АЦП кнопок
static int16_t   adc_battery;   // значение АЦП батареи




/*******************************************************************************
* Инициализация АЦП
* Подключение:
* PB0 - SW (ADC1_IN8)
* PB1 - V_ACC (ADC1_IN9)
* Режим: два инжектированных канала
*******************************************************************************/
void adc_init (void)
{
   ADC1->CR1 = ADC_CR1_AWDCH_0      * 0   /*!<AWDCH[4:0] bits (Analog watchdog channel select bits) */
            | ADC_CR1_AWDCH_1   * 0
            | ADC_CR1_AWDCH_2   * 0
            | ADC_CR1_AWDCH_3   * 0
            | ADC_CR1_AWDCH_4   * 0
            | ADC_CR1_EOCIE      * 0   /*!<Interrupt enable for EOC                              */
            | ADC_CR1_AWDIE      * 0   /*!<AAnalog Watchdog interrupt enable                     */
            | ADC_CR1_JEOCIE   * 1   /*!<Interrupt enable for injected channels                */
            | ADC_CR1_SCAN      * 1   /*!<Scan mode                                             */
            | ADC_CR1_AWDSGL   * 0   /*!<Enable the watchdog on a single channel in scan mode  */
            | ADC_CR1_JAUTO      * 1   /*!<Automatic injected group conversion                   */
            | ADC_CR1_DISCEN   * 0   /*!<Discontinuous mode on regular channels                */
            | ADC_CR1_JDISCEN   * 1   /*!<Discontinuous mode on injected channels               */
            | ADC_CR1_DISCNUM_0   * 1   /*!<Bit 0 *//*!<DISCNUM[2:0] bits (Discontinuous mode channel count)  */
            | ADC_CR1_DISCNUM_1   * 0   /*!<Bit 1 */
            | ADC_CR1_DISCNUM_2   * 0   /*!<Bit 2 */   // 001 - 2 канала
            | ADC_CR1_JAWDEN   * 0   /*!<Analog watchdog enable on injected channels           */
            | ADC_CR1_AWDEN      * 0   /*!<Analog watchdog enable on regular channels            */
            | ADC_CR1_RES_0      * 0   /*!<Bit 0 */ /*!<RES[2:0] bits (Resolution)               */   
            | ADC_CR1_RES_1      * 0   /*!<Bit 1 */   // 00-12 бит
            | ADC_CR1_OVRIE      * 0; /*!<overrun interrupt enable                             */
   
   ADC1->CR2 = ADC_CR2_ADON      * 1 /*!<A/D Converter ON / OFF             */
            | ADC_CR2_CONT      * 0 /*!<Continuous Conversion              */
            | ADC_CR2_DMA      * 0 /*!<Direct Memory access mode          */
            | ADC_CR2_DDS      * 0 /*!<DMA disable selection (Single ADC) */
            | ADC_CR2_EOCS      * 0 /*!<End of conversion selection        */
            | ADC_CR2_ALIGN      * 0 /*!<Data Alignment 0: Right alignment      */
            | ADC_CR2_JEXTSEL_0   * 0 /*!<Bit 0 */
            | ADC_CR2_JEXTSEL_1   * 0 /*!<Bit 1 */
            | ADC_CR2_JEXTSEL_2   * 0 /*!<Bit 2 */
            | ADC_CR2_JEXTSEL_3   * 0 /*!<Bit 3 */
            | ADC_CR2_JEXTEN_0   * 0 /*!<Bit 0 */
            | ADC_CR2_JEXTEN_1   * 0 /*!<Bit 1 */
            | ADC_CR2_JSWSTART   * 1 /*!<Start Conversion of injected channels */
            | ADC_CR2_EXTSEL_0   * 0 /*!<Bit 0 */
            | ADC_CR2_EXTSEL_1   * 0 /*!<Bit 1 */
            | ADC_CR2_EXTSEL_2   * 0 /*!<Bit 2 */
            | ADC_CR2_EXTSEL_3   * 0 /*!<Bit 3 */
            | ADC_CR2_EXTEN_0   * 0 /*!<Bit 0 */
            | ADC_CR2_EXTEN_1   * 0 /*!<Bit 1 */
            | ADC_CR2_SWSTART   * 0; /*!<Start Conversion of regular channels */
   ADC1->SMPR1 = 0;
   ADC1->SMPR2 = ADC_SMPR2_SMP8_0   * 0 /*!<Bit 0 */
            | ADC_SMPR2_SMP8_1   * 0 /*!<Bit 1 */
            | ADC_SMPR2_SMP8_2   * 1 /*!<Bit 2    100: 84 cycles */
            | ADC_SMPR2_SMP9_0   * 0 /*!<Bit 0 */
            | ADC_SMPR2_SMP9_1   * 0 /*!<Bit 1 */
            | ADC_SMPR2_SMP9_2   * 1; /*!<Bit 2 */
   
   ADC1->SQR1 = ADC_SQR1_L_0      * 0 /*!<Bit 0 *//*!<L[3:0] bits (Regular channel sequence length) */
            | ADC_SQR1_L_1      * 0 /*!<Bit 1 */
            | ADC_SQR1_L_2      * 0 /*!<Bit 2 */
            | ADC_SQR1_L_3      * 0; /*!<Bit 3 */ // 0000 - 1 канал
   ADC1->SQR2 = 0;
   ADC1->SQR3 = 0;
   ADC1->JSQR = ADC_JSQR_JSQ3_0   * 0 /*!<Bit 0 */ /*!<JSQ1[4:0] bits (1st conversion in injected sequence) */
            | ADC_JSQR_JSQ3_1   * 0 /*!<Bit 1 */
            | ADC_JSQR_JSQ3_2   * 0 /*!<Bit 2 */
            | ADC_JSQR_JSQ3_3   * 1 /*!<Bit 3 */ // 3-й канал номер 8
            | ADC_JSQR_JSQ3_4   * 0 /*!<Bit 4 */
            | ADC_JSQR_JSQ4_0   * 1 /*!<Bit 0 */ /*!<JSQ2[4:0] bits (2nd conversion in injected sequence) */
            | ADC_JSQR_JSQ4_1   * 0 /*!<Bit 1 */
            | ADC_JSQR_JSQ4_2   * 0 /*!<Bit 2 */
            | ADC_JSQR_JSQ4_3   * 1 /*!<Bit 3 */ // 4-й канал номер 9
            | ADC_JSQR_JSQ4_4   * 0 /*!<Bit 4 */
            | ADC_JSQR_JL_0      * 1 /*!<Bit 0 */ /*!<JL[1:0] bits (Injected Sequence length) */
            | ADC_JSQR_JL_1      * 0; /*!<Bit 1 */ // 01 - 2 измерения
   
   ADC->CCR = ADC_CCR_MULTI_0      * 0 /*!<Bit 0 */ /*!<MULTI[4:0] bits (Multi-ADC mode selection) */
            | ADC_CCR_MULTI_1   * 0 /*!<Bit 1 */
            | ADC_CCR_MULTI_2   * 0 /*!<Bit 2 */
            | ADC_CCR_MULTI_3   * 0 /*!<Bit 3 */
            | ADC_CCR_MULTI_4   * 0 /*!<Bit 4 */ // 00000 - Independent mode
            | ADC_CCR_DDS        * 0 /*!<DMA disable selection (Multi-ADC mode) */
            | ADC_CCR_ADCPRE_0   * 1 /*!<Bit 0 */ /*!<ADCPRE[1:0] bits (ADC prescaler) */ 
            | ADC_CCR_ADCPRE_1   * 1 /*!<Bit 1 */ // 11 - делитель на 8 APB2(90МГЦ)/8= 11,25МГц
            | ADC_CCR_VBATE      * 0 /*!<VBAT Enable */
            | ADC_CCR_TSVREFE   * 0; /*!<Temperature Sensor and VREFINT Enable */
      
// разрешение прерываний в контроллере прерываний
   
}


/*******************************************************************************
* прерывание АЦП
*
*******************************************************************************/
#pragma call_graph_root = "interrupt"         // interrupt category
void ADC_IRQHandler (void)
{
   if (ADC1->SR & ADC_SR_JEOC)
   {
      ADC1->SR = 0;   //~ADC_SR_JEOC;         // сброс флага
      adc_buttons = (int16_t)ADC1->JDR1;      // запись значений АЦП
      adc_battery = (int16_t)ADC1->JDR2;
      send_message (M_ADC_READY);            // обработать данные
   }
}



/*******************************************************************************
* функция работы АЦП
* Период запуска - 100 мс
* После окончания измерения запускается функция обработки кнопок
* Выход - сообщения
*******************************************************************************/
void adc_func (void)
{
   typedef enum _adc_func_states
   {
      ADC_FUNC_INIT = 0,
      ADC_FUNC_WORK
   } adc_func_states;
   
   static adc_func_states   adc_func_state = ADC_FUNC_INIT;
   static uint32_t   adc_timer = 0;
   
   switch (adc_func_state)
   {
   case ADC_FUNC_INIT:
      adc_init ();
      adc_func_state = ADC_FUNC_WORK;
      V_ACC_ON (1);
      break;
      
   case ADC_FUNC_WORK:
      if ((system_time () - adc_timer) >= ADC_START_PERIOD)
      {
         adc_timer = system_time ();
         ADC1->CR2 |= ADC_CR2_JSWSTART;   // раз в 100 мс запустить АЦП
      }

      if (get_message (M_ADC_READY))
      {
         button_func ();               // после измерения обработать кнопки
         g.v_battery = (adc_battery * V_REF * 2) / N_MAX;   // вычислить напряжение батареи      
      }
      break;
      
   default:
      adc_func_state = ADC_FUNC_INIT;
      break;
   }
}

/*******************************************************************************
* Измерение напряжения батареи
* Вход - данные adc_battery
* один раз в секунду запускается функция слежения за напряжением питания.
* Выход - сообщение M_OFF и уровень заряда батареи в g.battery
*******************************************************************************/
void battery_func (void)
{

}


/*----------
* Конфигурация RCC кварц 12288000Гц Частота процессора 179.931МГц
* Частота SysTick 179.931МГц Частота периферии 45МГц
*----------*/

#include   "stm32f4xx.h"
#include   "system_stm32f4xx.h"
#include   "stm32f446_it.h"
#include   "global.h"
#include   "pll_modes.h"
#include   "init.h"
#include    "messages.h"
#include   "adc.h"
#include   "test.h"







int main()
{
   RCC_ClocksTypeDef   RCC_Clocks;

   SystemInit ();                  // from startup files startup_stm32f429_439xx.s, refer to system_stm32f4xx.c
   SystemCoreClockUpdate ();         // установка тактирования
   RCC_GetClocksFreq (&RCC_Clocks);   // получить текущие значения частот и тактирования

   GPIO_init ();                  // конфигурация выводов процессора

   RCC_ClockSecuritySystemCmd(ENABLE);   // Enable Clock Security System(CSS): this will generate an NMI exception when HSE clock fails

   init_irq ();

   SysTick_Config ((RCC_Clocks.HCLK_Frequency / 1000) - 1);   // конфигурация системного таймера 1000 Гц (1 мс)
   init_midi ();
   uart_ext_init (115200);
   esp8266_uart_init (115200);
   init_messages ();
   init_variables ();

   while (1)
   {
      adc_func ();         // работа с АЦП. Кнопки
      test_func ();         // тесты системы
      process_messages ();
   }
}



/*******************************************************************************
* Инициализация переменных
*******************************************************************************/
void init_variables (void)
{

}








                  
                  

Re: stm32f4 cmsis ADC прерывание

Пн мар 30, 2020 17:22:49

Спасибо конечно .Но когда вы коты спали.Я ловил мышей.Я решил вопрос частично.

Re: stm32f4 cmsis ADC прерывание

Ср апр 08, 2020 02:03:31

Вот пример с живого проекта
Спойлер
Код:
/*----------
* файл adc.c
* работа с АЦП
*----------*/

#include   "stm32f4xx.h"
#include   "stm32f446_it.h"
#include   "adc.h"
#include   "messages.h"
#include   "button.h"
#include   "global.h"



#define   ADC_START_PERIOD          (100)   // период запуска АЦП
#define   BATTERY_WAIT_TO_START     (1000)   // время между включением питания и включением делителя напряжения батареи
#define   BATTERY_WAIT_TO_MEASURE   (1000)   // время между включением делителя и началом слежения за батареей
#define   BATTERY_PERIOD             (1000)   // период запуска программы напряжения батареи
#define   V_REF                         (322)   // напряжение питания 3,20В
#define   N_MAX                         (0x0FFF)   // максимальное число от АЦП


// определения портов контроллера
#define      V_ACC_ON_0      (GPIOB->BSRR = GPIO_BSRR_BR_2)
#define      V_ACC_ON_1      (GPIOB->BSRR = GPIO_BSRR_BS_2)
#define      V_ACC_ON(a)      (a ?  V_ACC_ON_1 : V_ACC_ON_0)


int16_t         adc_buttons;   // значение АЦП кнопок
static int16_t   adc_battery;   // значение АЦП батареи




/*******************************************************************************
* Инициализация АЦП
* Подключение:
* PB0 - SW (ADC1_IN8)
* PB1 - V_ACC (ADC1_IN9)
* Режим: два инжектированных канала
*******************************************************************************/
void adc_init (void)
{
   ADC1->CR1 = ADC_CR1_AWDCH_0      * 0   /*!<AWDCH[4:0] bits (Analog watchdog channel select bits) */
            | ADC_CR1_AWDCH_1   * 0
            | ADC_CR1_AWDCH_2   * 0
            | ADC_CR1_AWDCH_3   * 0
            | ADC_CR1_AWDCH_4   * 0
            | ADC_CR1_EOCIE      * 0   /*!<Interrupt enable for EOC                              */
            | ADC_CR1_AWDIE      * 0   /*!<AAnalog Watchdog interrupt enable                     */
            | ADC_CR1_JEOCIE   * 1   /*!<Interrupt enable for injected channels                */
            | ADC_CR1_SCAN      * 1   /*!<Scan mode                                             */
            | ADC_CR1_AWDSGL   * 0   /*!<Enable the watchdog on a single channel in scan mode  */
            | ADC_CR1_JAUTO      * 1   /*!<Automatic injected group conversion                   */
            | ADC_CR1_DISCEN   * 0   /*!<Discontinuous mode on regular channels                */
            | ADC_CR1_JDISCEN   * 1   /*!<Discontinuous mode on injected channels               */
            | ADC_CR1_DISCNUM_0   * 1   /*!<Bit 0 *//*!<DISCNUM[2:0] bits (Discontinuous mode channel count)  */
            | ADC_CR1_DISCNUM_1   * 0   /*!<Bit 1 */
            | ADC_CR1_DISCNUM_2   * 0   /*!<Bit 2 */   // 001 - 2 канала
            | ADC_CR1_JAWDEN   * 0   /*!<Analog watchdog enable on injected channels           */
            | ADC_CR1_AWDEN      * 0   /*!<Analog watchdog enable on regular channels            */
            | ADC_CR1_RES_0      * 0   /*!<Bit 0 */ /*!<RES[2:0] bits (Resolution)               */   
            | ADC_CR1_RES_1      * 0   /*!<Bit 1 */   // 00-12 бит
            | ADC_CR1_OVRIE      * 0; /*!<overrun interrupt enable                             */
   
   ADC1->CR2 = ADC_CR2_ADON      * 1 /*!<A/D Converter ON / OFF             */
            | ADC_CR2_CONT      * 0 /*!<Continuous Conversion              */
            | ADC_CR2_DMA      * 0 /*!<Direct Memory access mode          */
            | ADC_CR2_DDS      * 0 /*!<DMA disable selection (Single ADC) */
            | ADC_CR2_EOCS      * 0 /*!<End of conversion selection        */
            | ADC_CR2_ALIGN      * 0 /*!<Data Alignment 0: Right alignment      */
            | ADC_CR2_JEXTSEL_0   * 0 /*!<Bit 0 */
            | ADC_CR2_JEXTSEL_1   * 0 /*!<Bit 1 */
            | ADC_CR2_JEXTSEL_2   * 0 /*!<Bit 2 */
            | ADC_CR2_JEXTSEL_3   * 0 /*!<Bit 3 */
            | ADC_CR2_JEXTEN_0   * 0 /*!<Bit 0 */
            | ADC_CR2_JEXTEN_1   * 0 /*!<Bit 1 */
            | ADC_CR2_JSWSTART   * 1 /*!<Start Conversion of injected channels */
            | ADC_CR2_EXTSEL_0   * 0 /*!<Bit 0 */
            | ADC_CR2_EXTSEL_1   * 0 /*!<Bit 1 */
            | ADC_CR2_EXTSEL_2   * 0 /*!<Bit 2 */
            | ADC_CR2_EXTSEL_3   * 0 /*!<Bit 3 */
            | ADC_CR2_EXTEN_0   * 0 /*!<Bit 0 */
            | ADC_CR2_EXTEN_1   * 0 /*!<Bit 1 */
            | ADC_CR2_SWSTART   * 0; /*!<Start Conversion of regular channels */
   ADC1->SMPR1 = 0;
   ADC1->SMPR2 = ADC_SMPR2_SMP8_0   * 0 /*!<Bit 0 */
            | ADC_SMPR2_SMP8_1   * 0 /*!<Bit 1 */
            | ADC_SMPR2_SMP8_2   * 1 /*!<Bit 2    100: 84 cycles */
            | ADC_SMPR2_SMP9_0   * 0 /*!<Bit 0 */
            | ADC_SMPR2_SMP9_1   * 0 /*!<Bit 1 */
            | ADC_SMPR2_SMP9_2   * 1; /*!<Bit 2 */
   
   ADC1->SQR1 = ADC_SQR1_L_0      * 0 /*!<Bit 0 *//*!<L[3:0] bits (Regular channel sequence length) */
            | ADC_SQR1_L_1      * 0 /*!<Bit 1 */
            | ADC_SQR1_L_2      * 0 /*!<Bit 2 */
            | ADC_SQR1_L_3      * 0; /*!<Bit 3 */ // 0000 - 1 канал
   ADC1->SQR2 = 0;
   ADC1->SQR3 = 0;
   ADC1->JSQR = ADC_JSQR_JSQ3_0   * 0 /*!<Bit 0 */ /*!<JSQ1[4:0] bits (1st conversion in injected sequence) */
            | ADC_JSQR_JSQ3_1   * 0 /*!<Bit 1 */
            | ADC_JSQR_JSQ3_2   * 0 /*!<Bit 2 */
            | ADC_JSQR_JSQ3_3   * 1 /*!<Bit 3 */ // 3-й канал номер 8
            | ADC_JSQR_JSQ3_4   * 0 /*!<Bit 4 */
            | ADC_JSQR_JSQ4_0   * 1 /*!<Bit 0 */ /*!<JSQ2[4:0] bits (2nd conversion in injected sequence) */
            | ADC_JSQR_JSQ4_1   * 0 /*!<Bit 1 */
            | ADC_JSQR_JSQ4_2   * 0 /*!<Bit 2 */
            | ADC_JSQR_JSQ4_3   * 1 /*!<Bit 3 */ // 4-й канал номер 9
            | ADC_JSQR_JSQ4_4   * 0 /*!<Bit 4 */
            | ADC_JSQR_JL_0      * 1 /*!<Bit 0 */ /*!<JL[1:0] bits (Injected Sequence length) */
            | ADC_JSQR_JL_1      * 0; /*!<Bit 1 */ // 01 - 2 измерения
   
   ADC->CCR = ADC_CCR_MULTI_0      * 0 /*!<Bit 0 */ /*!<MULTI[4:0] bits (Multi-ADC mode selection) */
            | ADC_CCR_MULTI_1   * 0 /*!<Bit 1 */
            | ADC_CCR_MULTI_2   * 0 /*!<Bit 2 */
            | ADC_CCR_MULTI_3   * 0 /*!<Bit 3 */
            | ADC_CCR_MULTI_4   * 0 /*!<Bit 4 */ // 00000 - Independent mode
            | ADC_CCR_DDS        * 0 /*!<DMA disable selection (Multi-ADC mode) */
            | ADC_CCR_ADCPRE_0   * 1 /*!<Bit 0 */ /*!<ADCPRE[1:0] bits (ADC prescaler) */ 
            | ADC_CCR_ADCPRE_1   * 1 /*!<Bit 1 */ // 11 - делитель на 8 APB2(90МГЦ)/8= 11,25МГц
            | ADC_CCR_VBATE      * 0 /*!<VBAT Enable */
            | ADC_CCR_TSVREFE   * 0; /*!<Temperature Sensor and VREFINT Enable */
      
// разрешение прерываний в контроллере прерываний
   
}


/*******************************************************************************
* прерывание АЦП
*
*******************************************************************************/
#pragma call_graph_root = "interrupt"         // interrupt category
void ADC_IRQHandler (void)
{
   if (ADC1->SR & ADC_SR_JEOC)
   {
      ADC1->SR = 0;   //~ADC_SR_JEOC;         // сброс флага
      adc_buttons = (int16_t)ADC1->JDR1;      // запись значений АЦП
      adc_battery = (int16_t)ADC1->JDR2;
      send_message (M_ADC_READY);            // обработать данные
   }
}



/*******************************************************************************
* функция работы АЦП
* Период запуска - 100 мс
* После окончания измерения запускается функция обработки кнопок
* Выход - сообщения
*******************************************************************************/
void adc_func (void)
{
   typedef enum _adc_func_states
   {
      ADC_FUNC_INIT = 0,
      ADC_FUNC_WORK
   } adc_func_states;
   
   static adc_func_states   adc_func_state = ADC_FUNC_INIT;
   static uint32_t   adc_timer = 0;
   
   switch (adc_func_state)
   {
   case ADC_FUNC_INIT:
      adc_init ();
      adc_func_state = ADC_FUNC_WORK;
      V_ACC_ON (1);
      break;
      
   case ADC_FUNC_WORK:
      if ((system_time () - adc_timer) >= ADC_START_PERIOD)
      {
         adc_timer = system_time ();
         ADC1->CR2 |= ADC_CR2_JSWSTART;   // раз в 100 мс запустить АЦП
      }

      if (get_message (M_ADC_READY))
      {
         button_func ();               // после измерения обработать кнопки
         g.v_battery = (adc_battery * V_REF * 2) / N_MAX;   // вычислить напряжение батареи      
      }
      break;
      
   default:
      adc_func_state = ADC_FUNC_INIT;
      break;
   }
}

/*******************************************************************************
* Измерение напряжения батареи
* Вход - данные adc_battery
* один раз в секунду запускается функция слежения за напряжением питания.
* Выход - сообщение M_OFF и уровень заряда батареи в g.battery
*******************************************************************************/
void battery_func (void)
{

}


/*----------
* Конфигурация RCC кварц 12288000Гц Частота процессора 179.931МГц
* Частота SysTick 179.931МГц Частота периферии 45МГц
*----------*/

#include   "stm32f4xx.h"
#include   "system_stm32f4xx.h"
#include   "stm32f446_it.h"
#include   "global.h"
#include   "pll_modes.h"
#include   "init.h"
#include    "messages.h"
#include   "adc.h"
#include   "test.h"







int main()
{
   RCC_ClocksTypeDef   RCC_Clocks;

   SystemInit ();                  // from startup files startup_stm32f429_439xx.s, refer to system_stm32f4xx.c
   SystemCoreClockUpdate ();         // установка тактирования
   RCC_GetClocksFreq (&RCC_Clocks);   // получить текущие значения частот и тактирования

   GPIO_init ();                  // конфигурация выводов процессора

   RCC_ClockSecuritySystemCmd(ENABLE);   // Enable Clock Security System(CSS): this will generate an NMI exception when HSE clock fails

   init_irq ();

   SysTick_Config ((RCC_Clocks.HCLK_Frequency / 1000) - 1);   // конфигурация системного таймера 1000 Гц (1 мс)
   init_midi ();
   uart_ext_init (115200);
   esp8266_uart_init (115200);
   init_messages ();
   init_variables ();

   while (1)
   {
      adc_func ();         // работа с АЦП. Кнопки
      test_func ();         // тесты системы
      process_messages ();
   }
}



/*******************************************************************************
* Инициализация переменных
*******************************************************************************/
void init_variables (void)
{

}




Как то у  вас всё вместе.И настройка регулярных каналов и инжекторных?



                  
                  

Re: stm32f4 cmsis ADC прерывание

Чт апр 09, 2020 10:25:29

Используются и запускаются только инжекторные каналы.

Re: stm32f4 cmsis ADC прерывание

Вт апр 14, 2020 13:18:35

Вобщето да извините.
Ответить