最近研究了STM32内部温度传感器,终于把程序调通了!
/*STM32内部温度传感器实验,芯片温度通过上位机串口软件显示*/
#include"stm32f10x.h"
#include"sys.h"
#include"usart.h"
#include"adc_temp.h"
void SysTick_Init(u8 SYSCLK);//SysTick初始化函数声明
void delay_ms(u16 nms);//自定义的延时毫秒函数声明
u8 fac_us=0;
u16 fac_ms=0;
void RCC_Configuration(void);//时钟配置函数声明
void GPIO_Configuration(void);//GPIO端口初始化函数声明
void USART_Configuration(void);//串口初始化函数声明
int main(void)
{
float temp=0;
SysTick_Init(72);//调用SysTick初始化函数
RCC_Configuration();
GPIO_Configuration();
USART_Configuration();
ADC_Temp_Init();
while(1)
{
temp=Get_Temperture();
printf ("温度值 %.6f °C\r\n",((float)temp/100));
delay_ms(1000);
}
}
void SysTick_Init(u8 SYSCLK)//SysTick初始化函数
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
fac_us=SYSCLK/8;//SYSCLK的8分频 保存1us所需的计数次数
fac_ms=(u16)fac_us*1000;//1ms 需要计数的次数
}
void delay_ms(u16 nms)//利用SysTick自定义的延时毫秒函数
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms;//nms毫秒需要装载的寄存器值 最大1864ms
SysTick->VAL =0x00;//清空计数器
SysTick->CTRL=0x01;//开始倒数
do
{
temp=SysTick->CTRL;
}while ((temp&0x01)&&!(temp&(1<<16)));//等待时间到达
SysTick->CTRL&=~0x01;//关闭计数器
SysTick->VAL =0X00;//清空计数器
}
void RCC_Configuration(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能PA端口时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能串口USART1时钟
}
void GPIO_Configuration(void)//USART1对应的引脚PA9 PA10初始化配置
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//配置PA9为USART1_TX
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速度为50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//配置PA10为USART1_RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA.10
}
void USART_Configuration(void)//USART1初始化配置
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;//串口波特率 9600
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
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(USART1, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接收中断
USART_Cmd(USART1, ENABLE);//使能串口1
USART_ClearFlag(USART1,USART_FLAG_TC);//清空发送完成中断标志位
}
adc_temp.c
#include "adc_temp.h"
extern void delay_ms(u16 nms);
void ADC_Temp_Init()
{
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//使能ADC1时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC时钟为12M 72/6
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//ADC工作模式:ADC1工作在独立模式
ADC_InitStructure.ADC_ScanConvMode=DISABLE;//模数转换工作在单通道模式
ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;//模数转换工作在单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//转换由软件触发启动
ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel=1;//顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1,&ADC_InitStructure);//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
ADC_TempSensorVrefintCmd(ENABLE);
ADC_Cmd(ADC1,ENABLE);//使能ADC1
ADC_ResetCalibration(ADC1);//复位ADC1的校准寄存器
while(ADC_GetResetCalibrationStatus(ADC1));//等待ADC1的校准寄存器复位
ADC_StartCalibration(ADC1);//开始ADC1自校准
while(ADC_GetCalibrationStatus(ADC1));//等待ADC1自校准完成
}
u16 Get_ADC_Temp_Value(u8 ch,u8 times)
{
u8 t;
u32 temp_val=0;
ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_239Cycles5);
for(t=0;t<times;t++)
{
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件方式启动ADC1转换
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)) ;//等待转换结束
temp_val+=ADC_GetConversionValue(ADC1);
delay_ms(20);
}
return temp_val/times;//返回AD转换的平均值
}
float Get_Temperture(void)
{
u16 adc_value;
double temperture;
float temp;
adc_value=Get_ADC_Temp_Value(ADC_Channel_16,10);
temperture=(double)(adc_value*(3.3/4096));
temperture=(double)((1.43-temperture)/0.0043+25);
temp=(float)(temperture*100);
return temp;
}
我要赚赏金
