2021-10-20

基于stm32的简易电压表## 简易电压表
这是一个基于STM32F1系列的简易的电压表,可以测量0-12电压。并显示在0.96存4脚的OLED上。

、外围电路

STM32的ADC引脚只能承受3.3V,所以要额外搭建一个降压电路,就是把要测量的电压值将到3.3V以下,然后通过比例计算出当前的电压。这里只用到两三个电阻,按照串联降压的特性计算。(U a = 1/2U)

二、SMT32程序

利用32的ADC模数转换器(12位)采集要测量的电压值,再通过冒泡排序得到一个平均值即可。

void ADC_Sampling (void) 	
{	
	u16 ADC1_ConvertedValueTab[CodeSize];
  u16 ADC2_ConvertedValueTab[CodeSize];
	u16	temp2;												    //  排序中间变量
	u16	adcx[2];											    //	数字电压值
	u8	i,j,count;										    //	循环变量	
	u32 sum[2] = {0LU};										//	求和值
	
	for (count = 0; count < CodeSize; count ++)											// 采样N个数据
	{
		ADC1_ConvertedValueTab[count] = 0;
		ADC2_ConvertedValueTab[count] = 0;	
	}
	
	for (count = 0; count < CodeSize; count ++)											// 采样CodeSize个数据
	{
		ADC_SoftwareStartConvCmd(ADC1,ENABLE); 												// 启动AD采样	
		ADC_SoftwareStartConvCmd(ADC2,ENABLE); 												// 启动AD采样							

		while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));										// 等待AD转换完成
		while(!ADC_GetFlagStatus(ADC2,ADC_FLAG_EOC));						
		
		ADC_ClearFlag(ADC1,ADC_FLAG_EOC);																// AD转换完成,清除标志位
		ADC_ClearFlag(ADC2,ADC_FLAG_EOC);
				
		ADC1_ConvertedValueTab[count]=ADC_GetConversionValue(ADC1);
		ADC2_ConvertedValueTab[count]=ADC_GetConversionValue(ADC2);
	}
  
	for (j = 0; j < CodeSize - 1; j ++)				// 冒泡排序
		{ 	
			for (i = 0; i < CodeSize - j; i ++) 
			{ 
			if (ADC1_ConvertedValueTab[i] > ADC1_ConvertedValueTab[i + 1]) 
			{ 
				temp2 = ADC1_ConvertedValueTab[i]; 
				ADC1_ConvertedValueTab[i] = ADC1_ConvertedValueTab[i + 1]; 
				ADC1_ConvertedValueTab[i + 1] = temp2; 
			} 
		} 
	}  
	for (j = 0; j < CodeSize - 1; j ++)				// 冒泡排序
	{ 
		for (i = 0; i < CodeSize - j; i ++) 
		{ 
			if (ADC2_ConvertedValueTab[i] > ADC2_ConvertedValueTab[i + 1]) 
			{ 
				temp2 = ADC2_ConvertedValueTab[i]; 
				ADC2_ConvertedValueTab[i] = ADC2_ConvertedValueTab[i + 1]; 
				ADC2_ConvertedValueTab[i + 1] = temp2; 
			} 
		} 
	} 

	for(count = 3; count < CodeSize - 3; count ++)	    // 去除低三位和高三位 余下求和 
	{
		sum[0] += ADC1_ConvertedValueTab[count]; 					// 求和
		sum[1] += ADC2_ConvertedValueTab[count]; 
	}											
	adcx[0]		=	(u16)(sum[0] / (CodeSize - 6));					// 取平均值
	adcx[1]		=	(u16)(sum[1] / (CodeSize - 6));					// 取平均值
	
	AnalogVoltage[0]	=	(adcx[0] * 3300 / 4095);		// 求出模拟电压值 mv
	AnalogVoltage[1]	=	(adcx[1] * 3300 / 4095);
}

三、OLED显示

void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size)
{
	//在指定地方显示一个字符,包括部分字符
	u8 c=0,i=0;
	c=chr-' ';
	if(x>127)
	{
		x=0;
		y=y+2;
	}
	if(size == 16)
	{
		OLED_Set_Pos(x,y);
		for(i=0;i<8;i++)
		{
			OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);			
		} 
		OLED_Set_Pos(x,y+1);
		for(i=0;i<8;i++)
		{
			OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
		}
		
	} 
	else
	{
		OLED_Set_Pos(x,y);
		for(i=0;i<6;i++)
		{
			OLED_WR_Byte(F6x8[c][i],OLED_DATA);
		}
	}	
}

void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
{
	unsigned char c = 0,i = 0,j = 0;
	switch(TextSize)
	{
		case 1:
		{
			while(ch[j] != '\0')
			{
				c = ch[j] - 32;
				if(x > 126)
				{
					x = 0;
					y++;
				}
				//OLED_SetPos(x,y);
				OLED_Set_Pos(y,x);
				for(i=0;i<6;i++)
					OLED_WR_Byte(F6x8[c][i],OLED_DATA);
				x += 6;
				j++;
			}
		}break;
		case 2:
		{
			while(ch[j] != '\0')
			{
				c = ch[j] - 32;
				if(x > 120)
				{
					x = 0;
					y++;
				}
				//OLED_SetPos(x,y);
				OLED_Set_Pos(y,x);
				for(i=0;i<8;i++)
					OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
				//OLED_SetPos(x,y+1);
				OLED_Set_Pos(y+1,x);
				for(i=0;i<8;i++)
					OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
				x += 8;
				j++;
			}
		}break;
	}
}

void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size)
{
	//显示一个汉字串和字符号串
	u8 x0=x;
	u16 k;
	while(*chr!='\0')
	{
		if((*chr)<128)
		{
			if(*chr==13)
			{
				x=x0;
				y+=size/8;
			}
			else
			{
				OLED_ShowChar(x,y,*chr,size);
				x+=8;
				if(x>120)
				{
					x=0;
					y+=size/8;
				}			
			} 
			chr++;
		}
		else if(size==16)        //字体是否为16
		{
			for(k=0;k<hz16_num;k++)  //汉字搜索
			{
				if ((hz16[k].Index[0]==*(chr))&&(hz16[k].Index[1]==*(chr+1)))   //是否是已登记汉字
			   { 
					u8 t;
					OLED_Set_Pos(x,y);
					for(t=0;t<16;t++)
					{
						OLED_WR_Byte(hz16[k].Msk[t],OLED_DATA);
						
					}
					OLED_Set_Pos(x,y+1);
					for(t=0;t<16;t++)
					{
						OLED_WR_Byte(hz16[k].Msk[t+16],OLED_DATA);
					}
				
				}
				
			} 
			if(x>112)
			{
				x=0;
				y+=2;
			}				
			chr+=2;x+=16;
			
		}
		else       //输入错误,忽略汉字
		{
		   chr+=2;
		}
	}
}

总结说明、

这是在做学校的综合制作的,小白一个,就想试一下,最后还是实现了0-12V的电压测量,可以支持直流和交流、测交流的时候只需要将交流转成直流的电压值接入即可,这里用到AD637,最后测了一下,误差大概在3%,可以在综合制作课里通过。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值