单片机
返回首页

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上,温度在逐渐升高)



进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 家用电源无载自动断电装置的设计与制作

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 用NE555制作定时器

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 带有短路保护系统的5V直流稳压电源电路图

  • 如何调制IC555振荡器

    相关电子头条文章