STM32中ADC的使用/printf函数重定向串口显示内部温度传感器测量值
2022-04-21 来源:eefocus
STM32F334C8T6这款MCU中有两个12位ADC(模数转换器),ADC1的通道16连接到内置的一个温度传感器,本文使用该温度传感器测量MCU和周围的环境温度,并且通过串口发送到PC的串口助手进行显示。
1. ADC的使用
1. select the ADC clock using the function RCC_ADCCLKConfig()
2. Enable the ADC interface clock using RCC_AHBPeriphClockCmd();
3. ADC pins configuration
Enable the clock for the ADC GPIOs using the following function: RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOx, ENABLE);
Configure these ADC pins in analog mode using GPIO_Init();
4. Configure the ADC conversion resolution, data alignment, external trigger and edge,
sequencer lenght and Enable/Disable the continuous mode using the ADC_Init() function.
5. Activate the ADC peripheral using ADC_Cmd() function.
To configure the ADC channels features, use ADC_Init(), ADC_InjectedInit() and ADC_RegularChannelConfig() functions or/and ADC_InjectedChannelConfig()
2. 内部温度传感器的使用
To use the sensor:
1. Select the ADC1_IN16 input channel.
2. Select a sample time of 2.2 μs.
3. Set the TSEN bit in the ADC1_CCR register to wake up the temperature sensor from power-down mode.
4. Start the ADC conversion.
5. Read the resulting VTS data in the ADC data register.
6. Calculate the temperature using the following formula:
Temperature (in °C) = {(V25 – VTS) / Avg_Slope} + 25
Where:
– V25 = VTS value for 25° C
– Avg_Slope = average slope of the temperature vs. VTS curve (given in mV/°C or μV/°C)
Refer to the datasheet electrical characteristics section for the actual values of V25 and Avg_Slope.
(截图自 STM32F334 datasheet)
所以取 Avg_Slope=4.3, , V25=1.43 ,此处注意单位的不同
则有
Temperature (in °C) = {(1430 – VTS) /4.3 } + 25
3. printf()函数重定向
printf()函数是向显示器输出数据的函数,功能非常强大,使用非常方便,为了能方便的使用printf()函数,对该函数进行重定向,使其能向串口打印数据,则可以直接使用printf()函数将数据发到串口,极大方便了信息的输出。
通过重新实现int fputc(int ch,FILE *f)函数来实现这些功能。
4. 部分代码:
//在主函数中调用ADC,USART配置函数,实现延时函数,再调用下面的测试函数#include 'ADConverter.h'
void ADC_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
//select ADC colock
RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div6);
//enable peripheral colock
RCC_AHBPeriphClockCmd(ADC_PORT_CLK,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12,ENABLE);
//配置GPIO为模拟输入模式
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
//GPIO_InitStructure其他成员初始化
//GPIO_Init(GPIO_TypeDef * GPIOx, GPIO_InitTypeDef * GPIO_InitStruct);
ADC_StructInit(&ADC_InitStructure);
ADC_VoltageRegulatorCmd(ADC1, ENABLE);
delay_us(10);
//添加Calibration
//Common Init
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
//ADC_CommonInitStructure其他成员初始化
ADC_CommonInit(ADC1,&ADC_CommonInitStructure);
//ADC Init
ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Enable;
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfRegChannel = 1;
//ADC_InitStructure其他成员初始化
ADC_Init(ADC1,&ADC_InitStructure);
//配置ADC的通道,采样周期等
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_19Cycles5);
//打开温度传感器
ADC_TempSensorCmd(ADC1, ENABLE);
//打开ADC
ADC_Cmd(ADC1,ENABLE);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY));
//开始转换
ADC_StartConversion(ADC1);
}
//获取温度值函数
uint16_t GetTemperature(void)
{
u16 t,temp,Temperature;
t=ADC_GetConversionValue(USING_ADC);//读取ADC数值
temp = t*3300/0xFFF;//将读取的数值转换为电压值
Temperature = (1430-temp)*10/43+25;//将电压值转换为温度值(℃)
return Temperature;
}
//测试函数,每隔0.5秒读取一次测试值
//并把测试到的温度通过串口打印到PC的串口助手显示出来
void TempSensortest(void)
{
u16 tmp=0;
while(1)
{
delay_ms(500);
tmp = GetTemperature();
printf('The Temperature = %d ℃n',tmp);
}
}
//printf()函数的重定向,使其能向串口打印数据
int fputc(int ch,FILE *f)
{
USART_SendData(USART2, ch);
while(USART_GetFlagStatus(USART2, USART_FLAG_TC)==RESET) ;
return(ch);
}
实际效果如下:
(将手指按在MCU上,温度在逐渐升高)