本次实验:
Stm32f10x系列微控制器内置有温度传感器可以用来测量器件周围的温度(T)。温度传感器在内部和ADC1_IN16输入通道相连接,此通道把传感器输出的电压转换成数字值。温度传感器模拟输入的采样时间必须大于2.2 µs。
主要特征
支持的温度范围:-40到125度
精确度:+/- 1.5° C
读温度
为使用传感器:
- 选择ADC1_IN16输入通道
- 选择采样时间大于2.2 µs
- 设置ADC控制寄存器2(ADC_CR2)的TSVREFE位,以唤醒关电模式下的温度传感器
- 通过设置ADON位启动ADC转换(或用外部触发)
- 读ADC数据寄存器上的V SENSE 数据结果
- 利用下列公式得出温度
温度(°C) = {(V 25 - V SENSE ) / Avg_Slope} + 25
这里:
V 25 = V SENSE 在25 °C时的数值,取V25=1.43V
Avg_Slope = 温度/V SENSE 曲线的平均斜率(单位为mV/° C 或 µV/ °C),
取4.3mv/° C.
要求:DMA存放ADC采集的样本利用计算公式求得温度值通过usart1输出(注:串口助手显示温度输出);代码如下:
main.c
#include "stm32f10x.h"
#include "ADC.h"
#include "usart.h"
void Delay(__IO uint32_t nCount);
/* ADC1转换的电压值通过DMA方式传到sram*/
extern __IO u16 ADC_ConvertedValue;
/*计算后的温度值*/
u16 Current_Temp;
int main(void)
{
USART_Config();
Temp_ADC1_Init();
printf("\r\n 这是个内部温度传感器实验 \r\n");
while (1)
{
Delay(0xffffee); // 延时
//计算方法
Current_Temp=(V25-ADC_ConvertedValue)/AVG_SLOPE+25;
//10进制显示
printf("\r\n The IC current tem= %3d ℃\r\n", Current_Temp);
}
}
void Delay(__IO uint32_t nCount)
{
for( ; nCount !=0;nCount--);
}
ADC.c
#include "ADC.h"
#define ADC1_DR_Address ((u32)ADC1_BASE+0x4c)
vu16 ADC_ConvertedValue;
static void ADC1_GPIO_Config(void)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
}
/* 配置ADC1的工作模式为MDA模式*/
static void ADC1_Mode_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel1, ENABLE);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/*配置ADC时钟,为PCLK的8分频,即9Hz*/
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
//设置采样通道IN16,设置采样时间
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_239Cycles5);
//使能温度传感器和内部参考电压
ADC_TempSensorVrefintCmd(ENABLE);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
void Temp_ADC1_Init(void)
{
ADC1_GPIO_Config();
ADC1_Mode_Config();
}
ADC.h
#ifndef _ADC_H
#define _ADC_H
#include "stm32f10x.h"
//对于12位的ADC,3.3v的ADC值为0xfff,温度为25度是对应的电压值为1.43v
#define V25 0x6EE
//斜率,每摄氏度4.3mV对应每摄氏度0x05
#define AVG_SLOPE 0x05
void Temp_ADC1_Init(void);
#endif
usart.c
#include "usart.h"
void USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(DEBUG_USARTx, &USART_InitStructure);
USART_Cmd(DEBUG_USARTx, ENABLE);
}
int fputc(int ch, FILE *f)
{
//发送一个字节数据到串口
USART_SendData(DEBUG_USARTx, (uint8_t) ch);
//等待发送完毕
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
return (ch);
}
int fgetc(FILE *f)
{
//等待串口输入数据
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);
return (int)USART_ReceiveData(DEBUG_USARTx);
}
usart.h
#ifndef __USART_H
#define __USART_H
#include "stm32f10x.h"
#include <stdio.h>
#define DEBUG_USARTx USART1
#define DEBUG_USART_CLK RCC_APB2Periph_USART1
#define DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd
#define DEBUG_USART_BAUDRATE 115200
// USART GPIO 引脚宏定义
#define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA)
#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
#define DEBUG_USART_TX_GPIO_PORT GPIOA
#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9
#define DEBUG_USART_RX_GPIO_PORT GPIOA
#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10
#define DEBUG_USART_IRQ USART1_IRQn
#define DEBUG_USART_IRQHandler USART1_IRQHandler
void USART_Config(void);
#endif
代码运行结果: