В отладочной плате 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 после засовывания в холодильник.
Скачать проект.






