STM32中ADC的使用/printf函数重定向串口显示内部温度传感器测量值

发布者:BlossomWhisper最新更新时间:2022-04-21 来源: eefocus关键字:STM32  ADC  printf函数  重定向 手机看文章 扫描二维码
随时随地手机看文章

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



关键字:STM32  ADC  printf函数  重定向 引用地址:STM32中ADC的使用/printf函数重定向串口显示内部温度传感器测量值

上一篇:STM32非对称PWM模式实现动态移相(Asymmetric PWM mode的用法)
下一篇:ADC多通道+DMA采样求均值

推荐阅读最新更新时间:2024-11-12 20:20

STM32移植lwip之建立tcp客户端
本篇目标:在之前能ping通pc机的工程基础上搭建tcp客户端,并可以主动发数据给pc机,同时也能与pc机收发数据,并在网络调试工具上显示 材料准备: 基础工程:修改后能ping通pc机的工程( STM32官方移植lwip修改代码 ) 调试工具:用来调试tcp连接下的数据接收( 网络调试助手 ) 搭建工程:最终搭建好tcp客户端数据接收的工程( tcp客户端建立工程 ) 搭建TCP客户端 搭建TCP客户端的过程与上一章TCP服务器也相似,所以尽量把重点的地方加粗显示来区别 在搭建TCP客户端之前可以先理一下概念,客户端与服务器的区别: 客户端:主动建立tcp去连接目标IP 服务器:拥有静态IP,能让其他设备被动连接
[单片机]
STM32 Cubemax(四) —— STM32利用DMA空闲中断与Openmv通信
前言 因为之前电赛使用到了Openmv作为摄像头,处理完数据后将数据传回STM32主控来进行后续的操作,也看了很多论坛上的文章,但总感觉代码结构都不是自己的风格,以此记录一下。 本文章STM32的配置,按照我之前的风格,都为从Cubemax配置生成。 零、连线 一、OpenMv代码 首先介绍一下OpenMv这边的代码 主要使用的是ustruct这个库来作为串口的发送,注意,如果是直接用OpenMv的串口write发送,单片机这边收到的数据是不好处理的。 首先OpenMv也是单片机,要对其串口进行配置。 from pyb import UART uart = UART(3,115200) #定义串口3变量 ua
[单片机]
<font color='red'>STM32</font> Cubemax(四) —— <font color='red'>STM32</font>利用DMA空闲中断与Openmv通信
STM32的NVIC和中断的总结
前言: 1.要想学习STM32中断,要先掌握STM32对优先级的定义; 2.有51单片机开发经验会比较容易理解中断优先级; 3.本篇博文基于STM32F103ZET6芯片和3.5.0标准库编写; 4.本篇博文从寄存器入手,最终实现编程的步骤;如有不足之处,还请前辈多多指教; 一 基础知识 1. cortex-m3支持256个中断,其中包含了16个内核中断,240个外部中断。(本博文只介绍60个外部可屏蔽中断) 2. stm32只有84个中断,包括16个内核中断和68个可屏蔽中断 3. stm32f103上只有60个可屏蔽中断,f107上才有68个中断 4. 先占优先级也就是抢占优先级,概念等同于51单片机中的中断。假设有两中断先后
[单片机]
<font color='red'>STM32</font>的NVIC和中断的总结
STM32串口中断接收数据
数据帧满足下面格式: 帧头部(Head) 类型(Type) 长度(Length) 值(Value) CRC校验 2字节 1字节 1字节 X字节 2字节 0xaa 0x55 X void USART6_Init (void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6,ENABLE); RCC
[单片机]
STM32缺陷之一:串口中断标志位缺陷
根据小道消息,M3内核是有缺陷的,但是这种缺陷不会在大会上想广大群众透露的。我用的是M3内核的stm32,我来寻找一些缺陷。 今天找到的是串口中断标志位缺陷。 我是做四轴飞行器的,没有买遥控器,而是用的无线串口,一开始的想法是stm32接收到串口来的数据后,进入串口中断服务函数,再比对发来的数据进行接下来的动作。 一开始的程序是没有问题的,简单点吧,串口接收到数据后,让LED转换状态。 void USART2_IRQHandler(void) { if(USART_GetITStatus(USART2, USART_IT_RXNE) ==SET) { USART_ClearFlag (USART2
[单片机]
STM32 f103搭配LM386声音传感器实现简单音乐识别
1.前言 2019年12月初,有一个中国机器人技能大赛中的双足机器人比赛项目,意思是机器人识别音乐跳对应节奏的舞蹈,五首音乐随机抽三首歌曲,音乐停,机器人停。 新比赛,新项目,难度自然有,坑也不少。希望这篇文章能给大家带来一点帮助。废话不多说,进入正题。 2.效果 (健康歌)每100ms采样一次,歌曲前5秒内共测50次数据,重复12组 (卡路里) 重复7组 可以看出一首歌经过多次测值,其采样值数组呈现出有规律的特征;不同的歌曲的特征也有较好的区分度。达到了区分歌曲的效果。下面讲讲具体实现步骤。 3.思路 href= 做什么:识别不同音乐,识别声音有无。 href= 怎么做:a.利用传感器判断出音乐或声音
[单片机]
<font color='red'>STM32</font> f103搭配LM386声音传感器实现简单音乐识别
printf()函数重定向STM32串口输出
最近遇到需要MCU输出数字的问题,而STM32的串口输出的是字符型,最先想到的方法是将整型数据转换为字符型输出,C库函数中提供了相关的函数 参考:http://www.cnblogs.com/processakai/archive/2011/06/24/2089348.html http://c.biancheng.net/cpp/html/1573.html C语言中使用printf()函数输出是非常方便功能非常强大的,如果能将printf()函数使用到串口上,能实现非常多的强大输出功能,极大方便我们使用串口输出功能。 printf()函数是输出到显示器,而MCU是没有显示器的,要使他输出到串口,需要重定向该函数 pri
[单片机]
STM32下uIP移植问题
就我个人认为在uIP的移植中除了驱动之处有以下几点需要注意: 1.uip_timer 时钟要加入到中断中去。 2.各种appcall实现。如在tcp_client_demo.c 有如下语句 if(uip_len 199) { ((u8*)uip_appdata) =0; } strcpy((char*)tcp_client_databuf,uip_appdata); 这样在处理数据长时都是以tcp_client_databuf 数组的长来处理,这样不灵活,client从网络中接收到的数据长本来就是用一个全局变量uip_len来存储的。
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved