嵌入式笔记9

本次实验:
Stm32f10x系列微控制器内置有温度传感器可以用来测量器件周围的温度(T)。温度传感器在内部和ADC1_IN16输入通道相连接,此通道把传感器输出的电压转换成数字值。温度传感器模拟输入的采样时间必须大于2.2 µs。
主要特征
 支持的温度范围:-40到125度
 精确度:+/- 1.5° C
读温度
为使用传感器:

  1. 选择ADC1_IN16输入通道
  2. 选择采样时间大于2.2 µs
  3. 设置ADC控制寄存器2(ADC_CR2)的TSVREFE位,以唤醒关电模式下的温度传感器
  4. 通过设置ADON位启动ADC转换(或用外部触发)
  5. 读ADC数据寄存器上的V SENSE 数据结果
  6. 利用下列公式得出温度
    温度(°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.
    嵌入式笔记9
    要求: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 

代码运行结果:
嵌入式笔记9

上一篇:STM32CubeMX ADC多通道DMA(循环传输Circular,单次Normal)


下一篇:基于STM32的DMA&Usart_TIM_ADC功能