В отладочной плате STM32F4 discovery микроконтроллер оснащенный 12битным АЦП со встроенным датчиком температуры и напряжения.
В этой статье займёмся датчиком температуры, заодно рассмотрим принципы работы с АЦП в stm32 spl (стандартной периферийной библиотеке).
Напишем приложение, которое зажигает 4 диода в зависимости от уровня получаемого с АЦП1.
Необходимые инклуды:
#include <stm32f4xx.h> #include <stm32f4xx_rcc.h> #include <stm32f4xx_gpio.h> #include <stm32f4xx_adc.h>
Инициализируем диоды:
void leds_init() { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); GPIO_InitTypeDef gpio; GPIO_StructInit(&gpio); gpio.GPIO_OType = GPIO_OType_PP; gpio.GPIO_Mode = GPIO_Mode_OUT; gpio.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_Init(GPIOD, &gpio); }
Теперь настроим ADC1 (он же АЦП1) :
void adc_init() { ADC_InitTypeDef ADC_InitStructure; ADC_StructInit(&ADC_InitStructure); ADC_CommonInitTypeDef adc_init; ADC_CommonStructInit(&adc_init); /* разрешаем тактирование AЦП1 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); /* сбрасываем настройки АЦП */ ADC_DeInit(); /* АЦП1 и АЦП2 работают независимо */ adc_init.ADC_Mode = ADC_Mode_Independent; adc_init.ADC_Prescaler = ADC_Prescaler_Div2; /* выключаем scan conversion */ ADC_InitStructure.ADC_ScanConvMode = DISABLE; /* Не делать длительные преобразования */ ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; /* Начинать преобразование программно, а не по срабатыванию триггера */ ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None; /* 12 битное преобразование. результат в 12 младших разрядах результата */ ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; /* инициализация */ ADC_CommonInit(&adc_init); ADC_Init(ADC1, &ADC_InitStructure); /* Включаем АЦП1 */ 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); }
Эта функция принимает в качестве параметра номер канала АЦП. Для использования встроенного датчика температуры необходимо использовать 16 канал.
Задержка:
void Delay(unsigned int Val){ for( ; Val != 0; Val--) __NOP(); }
Теперь функция main :
int main(){ leds_init(); // инициализируем диоды adc_init(); // ацп ADC_TempSensorVrefintCmd(ENABLE); // разрешаем преобразование do { unsigned int Temperature = readADC1(16); /// читаем данные с датчика АЦП1 GPIO_ResetBits(GPIOD,GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15); // сбрасываем состояние диодов if (Temperature > 50) { /// если больше 20 зажигаем первый диод GPIO_SetBits(GPIOD, GPIO_Pin_12); } if (Temperature > 55) { // если больше 30 - второй. и т.д. GPIO_SetBits(GPIOD, GPIO_Pin_13); } if (Temperature > 60) { GPIO_SetBits(GPIOD, GPIO_Pin_14); } if (Temperature > 70) { GPIO_SetBits(GPIOD, GPIO_Pin_15); } Delay(5000000); // задержка }while (1); }
Встроенный датчик врядли поможет вам получить истинные значения температуры. Он предназначен для отслеживания её изменений.
Приведенная программа зажигает 3 диода при ~25 за окном. 2 после засовывания в холодильник.
Скачать проект.