Alex_Golubev 0 10 декабря, 2020 Опубликовано 10 декабря, 2020 · Жалоба Не могу запустить АЦП. В общем нужно делать измерения и складывать их в память. /*настройка ДМА для АЦП*/ 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. Но не заработало. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_Golubev 0 15 декабря, 2020 Опубликовано 15 декабря, 2020 · Жалоба Не могу найти ошибку вроде все правильно сделал: В буфере 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; // запуск приобразования АЦП Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 42 15 декабря, 2020 Опубликовано 15 декабря, 2020 · Жалоба 3 hours ago, Alex_Golubev said: Не могу найти ошибку вроде все правильно сделал: В буфере bufAdcData все нули. bufAdcData точно прописан в область памяти где есть доступ DMA. Попробуйте запустить для начала без DMA. Так вы убедитесь, что сам АЦП у вас настроен правильно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 35 15 декабря, 2020 Опубликовано 15 декабря, 2020 · Жалоба 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 она такая: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_Golubev 0 15 декабря, 2020 Опубликовано 15 декабря, 2020 (изменено) · Жалоба У stm32h7 есть DMAMUX DMAMUX1_Channel0->CCR = (9 << DMAMUX_CxCR_DMAREQ_ID_Pos); // подключение через MUXDMA DMA1_стрим_0 к ADC1 Изменено 15 декабря, 2020 пользователем Alex_Golubev Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_Golubev 0 17 декабря, 2020 Опубликовано 17 декабря, 2020 · Жалоба Никто помочь не может? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 17 декабря, 2020 Опубликовано 17 декабря, 2020 · Жалоба Я в Keil в отладчике смотрю, что в регистрах, что в памяти творится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 64 17 декабря, 2020 Опубликовано 17 декабря, 2020 · Жалоба 1 час назад, Alex_Golubev сказал: Никто помочь не может? У меня работал этот АЦП через DMA нормально, только была одна проблема - запускался 1 раз :) Второй раз приходилось делать сброс чипа, но мне хватало, поэтому глубоко не копал. Настраивал с помощью CubeMX. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LAS9891 0 9 января, 2021 Опубликовано 9 января, 2021 (изменено) · Жалоба On 12/17/2020 at 1:26 PM, Alex_Golubev said: Никто помочь не может? У меня работал этот АЦП через DMA нормально, и запускался столько раз сколько надо. Первоначально настраивал АЦП в Cube, затем настраивал регистрами то чего не хватало. Многие ошибки в настройке выяснил при отладке. В Вашем коде не нашел настройки Boost mode. Эта настройка "Must be used when ADC clock > 20 MHz". Еще помню, что после калибровки, некоторые регистры сбрасывались и приходилось делать инициализацию АЦП после калибровки, поэтому сначала делал минимальную настройку для проведения калибровки, затем калибровал, а потом всю инициализацию АЦП по полной. Проверяйте тактирование АЦП и контроллера DMA. Изменено 9 января, 2021 пользователем LAS9891 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться