Перейти к содержанию
    

Не могу запустить АЦП на stm32h743

Не могу запустить АЦП. В общем нужно делать измерения и складывать их в память. 

  /*настройка ДМА для АЦП*/
    DMAMUX1_Channel0->CCR = (9 << DMAMUX_CxCR_DMAREQ_ID_Pos); // подключение через MUXDMA DMA к ADC
    DMA1_Stream0->CR &= ~DMA_SxCR_EN; // выключаем DMA
    while(DMA1_Stream0->CR & DMA_SxCR_EN); // ждем гарантированого выключения DMA на всякий случай
    DMA1_Stream0->CR = DMA_SxCR_MINC | DMA_SxCR_TRBUFF | DMA_SxCR_DIR_0 | DMA_SxCR_CIRC; // настройка ДМА для АЦП
    DMA1_Stream0->NDTR = 5; // количество данных для передачи с АЦП в ОЗУ буфер
    DMA1_Stream0->PAR = (uint32_t)&ADC1->DR; // адрес от куда брать данные (АЦП)
    DMA1_Stream0->M0AR = (uint32_t)&bufAdcData; // указываем адрес масива куда писать
    ADC12_COMMON->CCR = ADC_CCR_PRESC_0 | ADC_CCR_PRESC_1 | ADC_CCR_PRESC_2; // делитель у АЦП1_2 на 16 включаем ДМА для цеклической передачи данных максимальная входная частота 36 МГц.
    ADC1->CR |= ADC_CR_ADVREGEN; // включаем LDO
    while(ADC1->ISR & (1<<12)); // ждем сигнала готовности LDORDY
    ADC1->CR |= ADC_CR_ADEN;
    while(ADC1->IER & ADC_ISR_ADRDY); // ждем когда АЦП станет готов к работе
    ADC1->CR |= ADC_CR_ADCAL;
    while (!(ADC1->CR & ADC_CR_ADCAL)); // калибровка АЦП
    ADC1->CFGR = (ADC_CFGR_DISCNUM_2 | ADC_CFGR_DISCNUM_0) | ADC_CFGR_DISCEN | ADC_CFGR_CONT | ADC_CFGR_DMNGT_1 | ADC_CFGR_DMNGT_0;
    ADC1->CFGR2 = 0
            | 0*ADC_CFGR2_LSHIFT
            | 0*ADC_CFGR2_OVSR;
    ADC1->SMPR1 = 0x00;
    ADC1->SMPR2 = ADC_SMPR2_SMP18_2; // задержка комутационого ключа на 32,5 такта тактироемой частоты
    ADC1->PCSEL = ADC_PCSEL_PCSEL_19 | ADC_PCSEL_PCSEL_18 | ADC_PCSEL_PCSEL_15 | ADC_PCSEL_PCSEL_9 | ADC_PCSEL_PCSEL_3; // 19,18,15,9,3
    ADC1->LTR1 = 0x00; // установка нижнего уровня аналогового компаратора
    ADC1->LTR2 = 0x00; // установка нижнего уровня аналогового компаратора
    ADC1->LTR3 = 0x00; // установка нижнего уровня аналогового компаратора
    ADC1->HTR1 = 0x00; // установка верхнего уровня аналогового компаратора
    ADC1->HTR2 = 0x00; // установка верхнего уровня аналогового компаратора
    ADC1->HTR3 = 0x00; // установка верхнего уровня аналогового компаратора
    ADC1->SQR1 = ADC_SQR1_SQ1_1 | ADC_SQR1_SQ1_0; // как понял для шагов опроса каналов АЦП опрос идет 3 --> 9 ---> 15 ---> 18 ---> 19
    DMA1_Stream0->CR |= DMA_SxCR_EN; // включаем DMA для АЦП
    ADC1->CR |= ADC_CR_ADSTART; // запуск приобразования АЦП
    MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODE3, 0x3 << GPIO_MODER_MODE3_Pos); // перевод порта на аналоговый режим функцию ADC1-15
    MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODE4, 0x3 << GPIO_MODER_MODE4_Pos); // перевод порта на аналоговый режим функцию ADC1-18
    MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODE5, 0x3 << GPIO_MODER_MODE5_Pos); // перевод порта на аналоговый режим функцию ADC1-19
    MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODE6, 0x3 << GPIO_MODER_MODE6_Pos); // перевод порта на аналоговый режим функцию ADC1-3
    MODIFY_REG(GPIOB->MODER, GPIO_MODER_MODE0, 0x3 << GPIO_MODER_MODE0_Pos); // перевод порта на аналоговый режим функцию ADC1-9
    MODIFY_REG(GPIOA->OSPEEDR, GPIO_OSPEEDR_OSPEED3,0x0 << GPIO_OSPEEDR_OSPEED3_Pos); // настройка скорости фронта
    MODIFY_REG(GPIOA->OSPEEDR, GPIO_OSPEEDR_OSPEED4,0x0 << GPIO_OSPEEDR_OSPEED4_Pos); // настройка скорости фронта
    MODIFY_REG(GPIOA->OSPEEDR, GPIO_OSPEEDR_OSPEED5,0x0 << GPIO_OSPEEDR_OSPEED5_Pos); // настройка скорости фронта
    MODIFY_REG(GPIOA->OSPEEDR, GPIO_OSPEEDR_OSPEED6,0x0 << GPIO_OSPEEDR_OSPEED6_Pos); // настройка скорости фронта
    MODIFY_REG(GPIOB->OSPEEDR, GPIO_OSPEEDR_OSPEED0,0x0 << GPIO_OSPEEDR_OSPEED0_Pos); // настройка скорости фронта
    MODIFY_REG(GPIOA->PUPDR, GPIO_PUPDR_PUPD3, 0x00 << GPIO_PUPDR_PUPD3_Pos); // отключение подтяжки
    MODIFY_REG(GPIOA->PUPDR, GPIO_PUPDR_PUPD4, 0x00 << GPIO_PUPDR_PUPD4_Pos); // отключение подтяжки
    MODIFY_REG(GPIOA->PUPDR, GPIO_PUPDR_PUPD5, 0x00 << GPIO_PUPDR_PUPD5_Pos); // отключение подтяжки
    MODIFY_REG(GPIOA->PUPDR, GPIO_PUPDR_PUPD6, 0x00 << GPIO_PUPDR_PUPD6_Pos); // отключение подтяжки
    MODIFY_REG(GPIOB->PUPDR, GPIO_PUPDR_PUPD0, 0x00 << GPIO_PUPDR_PUPD0_Pos); // отключение подтяжки
    MODIFY_REG(GPIOA->AFR[0], GPIO_AFRL_AFSEL3, 0x0 << GPIO_AFRL_AFSEL3_Pos); // переключение на альтернативный режим AF0
    MODIFY_REG(GPIOA->AFR[0], GPIO_AFRL_AFSEL4, 0x0 << GPIO_AFRL_AFSEL4_Pos); // переключение на альтернативный режим AF0
    MODIFY_REG(GPIOA->AFR[0], GPIO_AFRL_AFSEL5, 0x0 << GPIO_AFRL_AFSEL5_Pos); // переключение на альтернативный режим AF0
    MODIFY_REG(GPIOA->AFR[0], GPIO_AFRL_AFSEL6, 0x0 << GPIO_AFRL_AFSEL6_Pos); // переключение на альтернативный режим AF0
    MODIFY_REG(GPIOB->AFR[0], GPIO_AFRL_AFSEL0, 0x0 << GPIO_AFRL_AFSEL0_Pos); // переключение на альтернативный режим AF0
    // АЦП не заработал. Хочу получить в циклическом режиме данные через DMA. Но не заработало.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не могу найти ошибку вроде все правильно сделал: В буфере bufAdcData все нули. bufAdcData точно прописан в область памяти где есть доступ DMA.

Скрытый текст

	MODIFY_REG(RCC->D2CCIP2R, RCC_D2CCIP2R_USART16SEL, 0 << RCC_D2CCIP2R_USART16SEL_Pos);// подключаем тактирование USART1 к линии "rcc_pclk2"
	RCC->AHB1ENR |= RCC_AHB1ENR_ADC12EN; // подключаем АЦП1_2 к 32-разрядной шине AHB1 для обмена данными  

/*настройка портов для работы АЦП1
     * задействаны порты:
     * PA3 ADC1-15 делитель 24 В
     * PA4 ADC1-18 шунт 24В
     * PA5 ADC1-19 делитель 5В
     * PA6 ADC1-3 шунт 5В
     * PB0 ADC1-9 напряжения на резервном питании кондесатор 100 мкФ.
     * */

	/*настройка ДМА для АЦП*/
	DMAMUX1_Channel0->CCR = (9 << DMAMUX_CxCR_DMAREQ_ID_Pos); // подключение через MUXDMA DMA1_стрим_0 к ADC1

	DMA1_Stream0->CR &= ~DMA_SxCR_EN; // выключаем DMA
	while(DMA1_Stream0->CR & DMA_SxCR_EN); // ждем гарантированого выключения DMA на всякий случай
	DMA1_Stream0->CR = DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_CIRC | DMA_SxCR_DIR_0; // настройка ДМА для АЦП
	DMA1_Stream0->NDTR = 5; // количество данных для передачи с АЦП в ОЗУ буфер
	DMA1_Stream0->PAR = (uint32_t)&ADC1->DR; // адрес от куда брать данные (АЦП)
	DMA1_Stream0->M0AR = (uint32_t)&bufAdcData; // указываем адрес масива куда писать

	ADC12_COMMON->CCR = ADC_CCR_VBATEN
			| ADC_CCR_TSEN
			| ADC_CCR_VREFEN
			| ADC_CCR_PRESC_0 | ADC_CCR_PRESC_1 | ADC_CCR_PRESC_2 | ADC_CCR_PRESC_3
			| ADC_CCR_CKMODE_0; // делитель у АЦП1_2 на 16 подключения питания датчика температуры, включение опоры напряжения, делитель ckmode/1.

	ADC1->CR &= ~ADC_CR_DEEPPWD; // отключение низкого элетропотребления АЦП

	ADC1->CR |= ADC_CR_ADVREGEN; // включаем LDO
	while(!(ADC1->ISR & (1<<12))); // ждем сигнала готовности LDORDY

	ADC1->CR |= ADC_CR_ADEN; // включаем АЦП
	while(ADC1->IER & ADC_ISR_ADRDY); // ждем когда АЦП станет готов к работе

	ADC1->CR |= ADC_CR_ADCAL;
	while(!(ADC1->CR & ADC_CR_ADCAL)); // калибровка АЦП

    ADC1->CFGR = ADC_CFGR_JQDIS | (ADC_CFGR_DISCNUM_2 | ADC_CFGR_DISCNUM_0) | ADC_CFGR_DISCEN | ADC_CFGR_CONT | ADC_CFGR_DMNGT_1 | ADC_CFGR_DMNGT_0; // циклическая передача через DMA

	ADC1->CFGR2 = 0;
	
	ADC1->SMPR1 = ADC_SMPR1_SMP9_2 | ADC_SMPR1_SMP3_2; // задержка комутационого ключа на 32,5 такта тактироемой частоты
	ADC1->SMPR2 = ADC_SMPR2_SMP19_2 | ADC_SMPR2_SMP18_2 | ADC_SMPR2_SMP15_2; // задержка комутационого ключа на 32,5 такта тактироемой частоты
	ADC1->PCSEL = ADC_PCSEL_PCSEL_19 | ADC_PCSEL_PCSEL_18 | ADC_PCSEL_PCSEL_15 | ADC_PCSEL_PCSEL_9 | ADC_PCSEL_PCSEL_3; // 19,18,15,9,3

	ADC1->LTR1 = 0x00; // установка нижнего уровня аналогового компаратора
	ADC1->LTR2 = 0x00; // установка нижнего уровня аналогового компаратора
	ADC1->LTR3 = 0x00; // установка нижнего уровня аналогового компаратора
	ADC1->HTR1 = 0x00; // установка верхнего уровня аналогового компаратора
	ADC1->HTR2 = 0x00; // установка верхнего уровня аналогового компаратора
	ADC1->HTR3 = 0x00; // установка верхнего уровня аналогового компаратора

	ADC1->SQR1 = (ADC_SQR1_SQ1_1 | ADC_SQR1_SQ1_0)
			| (ADC_SQR1_SQ2_3 |  ADC_SQR1_SQ2_0)
			| (ADC_SQR1_SQ3_3 | ADC_SQR1_SQ3_2 | ADC_SQR1_SQ3_1 | ADC_SQR1_SQ3_0)
			| (ADC_SQR1_SQ4_4 | ADC_SQR1_SQ4_1); // шаги опроса каналов АЦП 3 --> 9 ---> 15 ---> 18 ---> 19

	ADC1->SQR2 = (ADC_SQR2_SQ5_4 | ADC_SQR2_SQ5_1 | ADC_SQR2_SQ5_0); // 19 канал АЦП
	ADC1->SQR3 = 0; // остальных каналов как бы нет
	ADC1->SQR4 = 0; // остальных каналов как бы нет

	DMA1_Stream0->CR |= DMA_SxCR_EN; // включаем DMA для АЦП
	while(!(DMA1_Stream0->CR & DMA_SxCR_EN)); // ждем когда включиться dma

	MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODE3, 0x3 << GPIO_MODER_MODE3_Pos); // перевод порта на аналоговый режим функцию ADC1-15
	MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODE4, 0x3 << GPIO_MODER_MODE4_Pos); // перевод порта на аналоговый режим функцию ADC1-18
	MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODE5, 0x3 << GPIO_MODER_MODE5_Pos); // перевод порта на аналоговый режим функцию ADC1-19
	MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODE6, 0x3 << GPIO_MODER_MODE6_Pos); // перевод порта на аналоговый режим функцию ADC1-3
	MODIFY_REG(GPIOB->MODER, GPIO_MODER_MODE0, 0x3 << GPIO_MODER_MODE0_Pos); // перевод порта на аналоговый режим функцию ADC1-9

	MODIFY_REG(GPIOA->OSPEEDR, GPIO_OSPEEDR_OSPEED3,0x0 << GPIO_OSPEEDR_OSPEED3_Pos); // настройка скорости фронта
	MODIFY_REG(GPIOA->OSPEEDR, GPIO_OSPEEDR_OSPEED4,0x0 << GPIO_OSPEEDR_OSPEED4_Pos); // настройка скорости фронта
	MODIFY_REG(GPIOA->OSPEEDR, GPIO_OSPEEDR_OSPEED5,0x0 << GPIO_OSPEEDR_OSPEED5_Pos); // настройка скорости фронта
	MODIFY_REG(GPIOA->OSPEEDR, GPIO_OSPEEDR_OSPEED6,0x0 << GPIO_OSPEEDR_OSPEED6_Pos); // настройка скорости фронта
	MODIFY_REG(GPIOB->OSPEEDR, GPIO_OSPEEDR_OSPEED0,0x0 << GPIO_OSPEEDR_OSPEED0_Pos); // настройка скорости фронта

	MODIFY_REG(GPIOA->PUPDR, GPIO_PUPDR_PUPD3, 0x00 << GPIO_PUPDR_PUPD3_Pos); // отключение подтяжки
	MODIFY_REG(GPIOA->PUPDR, GPIO_PUPDR_PUPD4, 0x00 << GPIO_PUPDR_PUPD4_Pos); // отключение подтяжки
	MODIFY_REG(GPIOA->PUPDR, GPIO_PUPDR_PUPD5, 0x00 << GPIO_PUPDR_PUPD5_Pos); // отключение подтяжки
	MODIFY_REG(GPIOA->PUPDR, GPIO_PUPDR_PUPD6, 0x00 << GPIO_PUPDR_PUPD6_Pos); // отключение подтяжки
	MODIFY_REG(GPIOB->PUPDR, GPIO_PUPDR_PUPD0, 0x00 << GPIO_PUPDR_PUPD0_Pos); // отключение подтяжки

	MODIFY_REG(GPIOA->AFR[0], GPIO_AFRL_AFSEL3, 0x0 << GPIO_AFRL_AFSEL3_Pos); // переключение на альтернативный режим AF0
	MODIFY_REG(GPIOA->AFR[0], GPIO_AFRL_AFSEL4, 0x0 << GPIO_AFRL_AFSEL4_Pos); // переключение на альтернативный режим AF0
	MODIFY_REG(GPIOA->AFR[0], GPIO_AFRL_AFSEL5, 0x0 << GPIO_AFRL_AFSEL5_Pos); // переключение на альтернативный режим AF0
	MODIFY_REG(GPIOA->AFR[0], GPIO_AFRL_AFSEL6, 0x0 << GPIO_AFRL_AFSEL6_Pos); // переключение на альтернативный режим AF0
	MODIFY_REG(GPIOB->AFR[0], GPIO_AFRL_AFSEL0, 0x0 << GPIO_AFRL_AFSEL0_Pos); // переключение на альтернативный режим AF0

	ADC1->CR |= ADC_CR_ADSTART; // запуск приобразования АЦП

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, Alex_Golubev said:

Не могу найти ошибку вроде все правильно сделал: В буфере bufAdcData все нули. bufAdcData точно прописан в область памяти где есть доступ DMA.

Попробуйте запустить для начала без DMA. Так вы убедитесь, что сам АЦП у вас настроен правильно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10.12.2020 в 14:36, Alex_Golubev сказал:

DMA1_Stream0->CR |= DMA_SxCR_EN; // включаем DMA для АЦП

ADC1->CR |= ADC_CR_ADSTART; // запуск преобразования АЦП

Вы твердо уверены, что у STM32H7-го Stream0 1-ого DMA обслуживает ADC1? А то я на этот момент уже спотыкалась на STM32F4, когда выяснила, что для обслуживания ADC1 нужен не DMA1, а DMA2. Для STM32H7 такой таблицы не нашла, но для STM32F4 она такая:

image.thumb.png.0f4d367783b28d3ae7efcfb077bf9d03.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У stm32h7 есть DMAMUX 

DMAMUX1_Channel0->CCR = (9 << DMAMUX_CxCR_DMAREQ_ID_Pos); // подключение через MUXDMA DMA1_стрим_0 к ADC1

 

Изменено пользователем Alex_Golubev

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я в Keil в отладчике смотрю, что в регистрах, что в памяти творится.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Alex_Golubev сказал:

Никто помочь не может?

У меня работал этот АЦП через DMA нормально, только была одна проблема - запускался 1 раз :) Второй раз приходилось делать сброс чипа, но мне хватало, поэтому глубоко не копал. Настраивал с помощью CubeMX.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 12/17/2020 at 1:26 PM, Alex_Golubev said:

Никто помочь не может?

У меня работал этот АЦП через DMA нормально, и запускался столько раз сколько надо. Первоначально настраивал АЦП в Cube, затем настраивал регистрами то чего не хватало. Многие ошибки в настройке выяснил при отладке. В Вашем коде не нашел настройки Boost mode. Эта настройка "Must be used when ADC clock > 20 MHz". Еще помню, что после калибровки, некоторые регистры сбрасывались и приходилось делать инициализацию АЦП после калибровки, поэтому сначала делал минимальную настройку для проведения калибровки, затем калибровал, а потом всю инициализацию АЦП по полной. Проверяйте тактирование АЦП и контроллера DMA.

Изменено пользователем LAS9891

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...