STM32F4 ADC режимы работы. Помогите разобраться

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
TmYAG
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

STM32F4 ADC режимы работы. Помогите разобраться

Сообщение TmYAG »

Здравствуйте!
Я начал разбираться с АЦП на STM32F4Discovery.
Вычитал, что у АЦП существуют два метода опроса: регулярные каналы и инжектированные каналы.
Разницу между ними я более менее понял. Первая группа запись данных в один регистр, вторая группа результат можно записать в один из 4-х регистров.
Я стараюсь писать код использую CMSIS. Но я столкнулся с проблемой инициализации. Я начал инициализировать но столкнулся с проблемой:
1. Включаю тактирование АЦП и портов;
2. Настройка модуля АЦП;
3. Включение модуля АЦП;
4. Настройка входа;
5. Калибровка;
(с)http://catethysis.ru/stm32-adc/
Для регулярной группы так должна выглядеть инициализация?

Код: Выделить всё

ADC1->SMPR2 |= (ADC_SMPR2_SMP1_2 | ADC_SMPR2_SMP1_1 | ADC_SMPR2_SMP1_0); //Задаем время выборки                                                                                             
        ADC1->CR2 |= ADC_CR2_EXTSEL; //Преобразование регулярной группы                                                         
        ADC1->CR2 |= ADC_CR2_EXTTRIG; //Разрешаем внешний запуск регулярной группы
        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)); //ждем пока первое преобразование завершится
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: STM32F4 ADC режимы работы. Помогите разобраться

Сообщение BCluster »

Так а собсна в чем состоит проблема? Ничего не работает?
Где включение тактирования модуля?
Не надо ли настроить мультиплексирование входа для работы в режиме АЦП? Не знаю как на F4 с этим
Вообще можно взять SPL для начала, и запустить на нем. Посмотреть как устроены функции и потом поэтапно переделать на CMSIS если не нравится SPL.
TmYAG
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

Re: STM32F4 ADC режимы работы. Помогите разобраться

Сообщение TmYAG »

Ну тактирование я само собой разумеющимся считаю) Тактируем АЦП, тактируем порт.
А вообще непонятка с калибровкой. Описания подобных регистров я не нашел.
И собственно я загружал код в камень, при исполнении он виснет(((
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: STM32F4 ADC режимы работы. Помогите разобраться

Сообщение BCluster »

Выкидывает в Hardware Fault или где зависает?
TmYAG
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

Re: STM32F4 ADC режимы работы. Помогите разобраться

Сообщение TmYAG »

Так, как появится у меня новая плата я потестирую и скажу точно)
TmYAG
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

Re: STM32F4 ADC режимы работы. Помогите разобраться

Сообщение TmYAG »

Код: Выделить всё

#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 ;
     }
        }
}

Вот написал код, сильно не пинайте только учусь)
На порт PA1 повесил переменный резистор, по идее кручтя его я должен увидеть изменение состояния светодиодов
Но не вижу((
TmYAG
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн окт 14, 2013 21:39:47

Re: STM32F4 ADC режимы работы. Помогите разобраться

Сообщение TmYAG »

Вроде как разобрался!
Проблема была в том, чо я неправильно задал соответсвие между каналом АЦП и пином с которого снимаю сигнал(((
В итоге для регулярных каналов:

Код: Выделить всё

#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);
         }
}
}

Для инжектированных:

Код: Выделить всё

#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->BSRRH |= (1 << 15)|(1 << 14)|(1 << 13)|(1 << 12);
         }
}
}


Еще попробую разобраться с прерываниями по EOC
Ответить

Вернуться в «ARM»