CR2 — второй регистр настроек
· 0 бит: ADON (Analog/Digital converter On/off). Включает АЦП. · 1 бит: CONT (Continious coversion). Включает режим однократного (0) или зацикленных измерений (1). · 2 бит: CAL (Calibration). Установка в 1 включает калибровку; после окончания калибровки сбрасывается в 0. Сначала нужно сбросить регистры. · 3 бит: RSTCAL (Reset Calibration). Сброс регистров калибровки, точно так же устанавливаем в 1 и ждём сброса. · 8 бит: DMA. Включает DMA. · 11 бит: ALIGN. Выравнивает данные по правому (0) или левому (1) краю регистра. · 12..14 бит: JEXTSEL. · 15 бит: JEXTTRIG. · 17..19 бит: EXTSEL (External event Select). Назначает номер события для запуска (TIM1 CC1, TIM1 CC2, TIM1 CC3, TIM1 CC4, TIM3 TRGO, TIM4 CC4, EXTI_11, SWSTART). · 20 бит: EXTTRIG (External Trigger). Включает запуск преобразования по внешнему триггеру. · 21 бит: JSWSTART. · 22 бит: SWSTART (Start conversion). Запускает преобразование. После окончания сбрасывается. · 23 бит: TSVREFE (Temp sensor and V_REF Enabled). Включает температурный сенсор и внутренний ИОН. DR — регистр результата измерения SMPR1, SMPR2 — время преобразования Регистр настройки времени преобразования для каждого канала. HTR и LTR — пределы WatchDog Верхний и нижний пределы для аналогового watchdog, аналогичны регистру DR. SQR1, SQR2, SQR3 — список каналов для сканирования Режим SCAN (бит SCAN в регистре CR1)
Выводы STM32 могут работать в качестве входа АЦП, они обозначены символом ANx (x = 0..15, эта цифра — номер канала). #1 Пример программы. void adc_init() { RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // настройки ADC ADC_InitTypeDef ADC_InitStructure; ADC_StructInit(&ADC_InitStructure); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // режим работы - одиночный, независимый ADC_InitStructure.ADC_ScanConvMode = DISABLE; // не сканировать каналы, просто измерить один канал ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // однократное измерение ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // без внешнего триггера ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //выравнивание битов результат - прижать вправо ADC_InitStructure.ADC_NbrOfChannel = 1; //количество каналов - одна штука ADC_Init(ADC1, &ADC_InitStructure); ADC_Cmd(ADC1, ENABLE); // настройка канала ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5); // калибровка АЦП ADC_ResetCalibration(ADC1); while (ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while (ADC_GetCalibrationStatus(ADC1)); }
Эксперимент Включаем преобразование, проверяем флаг EOC = End Of Conversion. Записываем результат регистра DR
uint16_t get_adc_value() { ADC_SoftwareStartConvCmd(ADC1, ENABLE); while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); return ADC_GetConversionValue(ADC1); }
void main() { adc_init(); uint16_t value = 0; while(1) value = get_adc_value(); } Можно просто запустить программу, остановить её брейкпойнтом и прочитать в отладчике измеренное значение.
#2 Пример программы.
# include <stm32f4xx_rcc.h> #include <stm32f4xx_gpio.h>
#include <stm32f4xx_adc.h>
void leds_init() {
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_StructInit(&gpio); gpio.GPIO_Mode = GPIO_Mode_AN;
gpio.GPIO_Pin = GPIO_Pin_1; GPIO_Init(GPIOA, &gpio);
}
void adc_init() {
ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef adc_init;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); ADC_DeInit();
ADC_StructInit(&ADC_InitStructure);
adc_init.ADC_Mode = ADC_Mode_Independent; adc_init.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_CommonInit(&adc_init);
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Cmd(ADC1, ENABLE); }
u16 readADC1(u8 channel) {
ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_3Cycles); ADC_SoftwareStartConv(ADC1);
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) ==RESET); return ADC_GetConversionValue(ADC1);
}
void Delay(unsigned int Val) {
for (; Val != 0; Val--); }
int main(void) { leds_init();
adc_init();
do {
unsigned int bin_code = readADC1(ADC_Channel_1); double voltage = bin_code * 2.96 / 0xfff;
Delay(500000);
} while (1); } При инициализации порта мы задаем значение, которое нужно для его работы в аналоговом режиме с помощью значения GPIO_Mode_AN. Во-вторых, инициализация и считывание значений из АЦП. Мы настраиваем, АЦП таким образом, что преобразование производится программно и выполняем его с помощью вызова функции readADC1. # применение ADC в микроконтроллере для контроля работы светодиода.
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */ SystemClock_Config();
/* USER CODE BEGIN SysInit */
uint32_t adc = 0;
uint32_t adc_buf[8] = {0}; uint32_t adc_buf_size = sizeof(adc_buf)/sizeof(adc_buf[0]);
uint32_t adc_position = 0; uint32_t adc_avg = 0;
uint32_t adc_sum = 0;
int i=0;
/* USER CODE END SysInit */
/* Initialize all configured peripherals */ MX_GPIO_Init(); MX_I2C1_Init(); MX_I2S3_Init(); MX_SPI1_Init(); MX_USB_HOST_Init(); MX_DMA_Init(); MX_ADC1_Init(); /* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */
/* USER CODE BEGIN 3 */ HAL_ADC_Start(&hadc1); // запускаемпреобразованиесигнала АЦП HAL_ADC_PollForConversion(&hadc1, 100); // ожидаемокончанияпреобразования adc = HAL_ADC_GetValue(&hadc1); // читаемполученноезначение в переменнуюadc HAL_ADC_Stop(&hadc1); // останавливаем АЦП (необязательно) printf("ADC %ld\n", adc);
//складываем в буфердляусреднения if (adc_position > adc_buf_size) { adc_position = 0; } else { adc_position++; } adc_buf[adc_position] = adc;
//усреднение adc_sum = 0; for (i=0;i < adc_buf_size; i++) { adc_sum = adc_sum + adc_buf[i]; } adc_avg = adc_sum / adc_buf_size; printf("ADC %ld\n", adc_avg);
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15);
HAL_Delay(adc); } /* USER CODE END 3 */ }
/**
Порядок работы 1. На основе примера написать свой код в среде разработки и скомпилировать его. 2. Ознакомиться с работой программы. 3. Создать новый проект в среде CubeMX и Keil. 4. Скомпилировать код на плату и проверить работу на отладочной плате Discavery.
Популярное: Как построить свою речь (словесное оформление):
При подготовке публичного выступления перед оратором возникает вопрос, как лучше словесно оформить свою... Почему стероиды повышают давление?: Основных причин три... Модели организации как закрытой, открытой, частично открытой системы: Закрытая система имеет жесткие фиксированные границы, ее действия относительно независимы... Как вы ведете себя при стрессе?: Вы можете самостоятельно управлять стрессом! Каждый из нас имеет право и возможность уменьшить его воздействие на нас... ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (301)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |