stm32开发3D打印机(三)——ADC热敏电阻测温、PWM控制(已完成)

3D打印机温度读取

ADC3初始化

主控芯片为stm32f407ZG,对ADC3初始化,精度设定为12位
在这里插入图片描述
在这里插入图片描述

ADC3代码部分

void init_adc3()		/ADC3初始化
{
    
    
	GPIO_InitTypeDef  GPIO_InitStructure;
	ADC_CommonInitTypeDef ADC_CommonInitStructure;
	ADC_InitTypeDef       ADC_InitStructure;
	
  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE); //使能

	RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,ENABLE);	  //ADC3复位
	RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,DISABLE);		 
 
	/ADC通用寄存器CCR
  	ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
  	ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样阶段延迟5个时钟
  	ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能
  	ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//四分频ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟不能超过36Mhz 
  	ADC_CommonInit(&ADC_CommonInitStructure);
	/初始化ADC3参数
  	ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
	ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发
  	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐	
  	ADC_InitStructure.ADC_NbrOfConversion = 1;//1¸
  	ADC_Init(ADC3, &ADC_InitStructure);
 
	ADC_Cmd(ADC3, ENABLE);
		
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//不带上下拉
	
	#ifdef TEMP_0_PIN 							/定义TEMP_0_PIN 或删除
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
		GPIO_Init(GPIOF, &GPIO_InitStructure);	 
	#endif
	#ifdef TEMP_1_PIN 
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
		GPIO_Init(GPIOF, &GPIO_InitStructure);	 
	#endif
	#ifdef TEMP_2_PIN 
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
		GPIO_Init(GPIOF, &GPIO_InitStructure);	 
	#endif
	#ifdef TEMP_BED_PIN 
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
		GPIO_Init(GPIOF, &GPIO_InitStructure);	 
	#endif
}
u16 get_adc(u8 ch)//ch为通道
{
    
    	 
	ADC_RegularChannelConfig(ADC3, ch, 1, ADC_SampleTime_480Cycles );		    
	ADC_SoftwareStartConv(ADC3);			 
	while(!ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC ));
	return ADC_GetConversionValue(ADC3);
}
u16 get_adc_average(u8 ch,u8 times)//ch为通道、Times为连续读取的次数
{
    
    
	u32 temp_val=0;
	u8 t;
	get_adc(ch);//首次读取ADC存在误差,跳过即可
	for(t=0;t<times;t++)
	{
    
    
		temp_val+=get_adc(ch);
      	//delay_ms(5);省略后对精度影响不大
	}
  		//printf("ch:%d,V:%d\n\r\n\r",ch,temp_val/times);
	return temp_val/times;
}


计数转换

首先使用的是NTC 100K热敏电阻
型号:B2-100-3950±1%
于25摄氏度下测量,电阻为100K 误差为1%
于25或50摄氏度测量,温度系数为3950 误差为1%
由公式在这里插入图片描述
即B=(ln(Rt1/Rt2))/(1/T1-1/T2)
而B=3950
令T2=25摄氏度=273.15+25华氏度=298.15K,则Rt2=100K欧
计数过程保留2位有效数字
3950*(1/T1-1/298.15)=lnR1-ln100K
ln100k=11.51
3950/298.15=13.25

化简T=3950/(lnR+1.74)
检验当R=100K欧时,得到温度T=24.963,误差0.037摄氏度

ADC为12位精度
电路图如下图所示
在这里插入图片描述

首先令热敏电阻为R1、电压为U1
串联的电阻为R2=4700欧
热敏电阻电压U1=get_adc()3.3/4096
由电流相等得U1/R1=(3.3-U1)/4700
化简得热敏电阻R1=(4700
get_adc())/(4096-get_adc())

综上
获取温度代码为

float get_temp(u8 ch)
{
    
    
	u16 volt;
	float R,T;
	volt=get_adc_average(ch,5);
	R=(4700*volt)/(4096-volt);
	T=(3950/(log(R)+1.74))-273.15;
	printf("ch:%d,Temp:%f\n\r\n\r",ch,T);
	return T;
}

注意,不可在定时器内读取温度,否则会导致接收或读取的数据错乱

PWM控制部分

电路部分如下图所示

在这里插入图片描述
在这里插入图片描述
对端口PWM初始化

//注意EXTRUDERS为定义的喷头数,在相应的头文件加入:
#define EXTRUDERS 1//为定义一个喷头
void heater_pwm_init()
{
    
    
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	GPIO_PinAFConfig(GPIOD,GPIO_PinSource12,GPIO_AF_TIM4);//热床PWM复用TIM4
	//									BED		 /TIM4_CH1								
	if(EXTRUDERS >0)//HEATEER 0 /TIM3_CH4///TIM8_CH3
		GPIO_PinAFConfig(GPIOB,GPIO_PinSource1,GPIO_AF_TIM3);//加热喷头0
	if(EXTRUDERS >1)//HEATEER 1 /TIM4_CH3
		GPIO_PinAFConfig(GPIOD,GPIO_PinSource14,GPIO_AF_TIM4);//加热喷头1
	if(EXTRUDERS >2)//HEATEER 2 /TIM3_CH3///TIM8_CH2
		GPIO_PinAFConfig(GPIOB,GPIO_PinSource0,GPIO_AF_TIM3);//	加热喷头2	

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;  //复用
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_14;
	GPIO_Init(GPIOD, &GPIO_InitStructure);	                                                                                                                          
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;				
	GPIO_Init(GPIOB, &GPIO_InitStructure);	
	
	TIM_TimeBaseStructure.TIM_Prescaler=83;  
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; 
	TIM_TimeBaseStructure.TIM_Period=499;   
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);
	
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 
	

	#ifdef HEATER_0_PIN  	     
		TIM_OC4Init(TIM3, &TIM_OCInitStructure);  
		TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable); 
	 #endif 
	TIM_ARRPreloadConfig(TIM3,ENABLE);//ARPE ??  
	#ifdef HEATER_1_PIN    
		TIM_OC3Init(TIM4, &TIM_OCInitStructure);  
		TIM_OC3PreloadConfig(TIM4,TIM_OCPreload_Enable);
  	#endif 
	#ifdef HEATER_2_PIN  	         
		TIM_OC3Init(TIM3, &TIM_OCInitStructure);  
		TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable);  
  	#endif 
	#ifdef HEATER_BED_PIN  	        
		TIM_OC1Init(TIM4, &TIM_OCInitStructure); 
		TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable); 
  	#endif 

	TIM_ARRPreloadConfig(TIM3,ENABLE);//ARPE ?? 
	TIM_ARRPreloadConfig(TIM4,ENABLE);//ARPE 使能

	TIM_Cmd(TIM3, ENABLE);
	TIM_Cmd(TIM4, ENABLE);

对于调节PWM占空比

#define  HEATER_0_PIN    TIM3->CCR4	  //E0_PWM T8_2(PB0)            E0¼ÓÈÈ-PWM
#define  HEATER_1_PIN    TIM4->CCR3	  //E1_PWM T8_1(PC6)            E1¼ÓÈÈ-PWM
#define  HEATER_2_PIN    TIM3->CCR3	  //E2_PWM T8_1(PC6)            E2¼ÓÈÈ-PWM
#define  HEATER_BED_PIN  TIM4->CCR1	  //BED_PWM T8_3(PB1)           BED¼ÓÈÈ-PWM

//直接对上述赋值即可,范围为0至65535
但是经过使用,大于500的PWM效果是一样的
或使用相应的函数
TIM_SetCompareX(TIMY,Z);
X为通道、Y为定时器、Z为占空比

猜你喜欢

转载自blog.csdn.net/Nico_jion/article/details/108044409