最近研究了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; }