51单片机简易数字万用表(电阻电流电压测量)仿真设计( proteus仿真+程序+报告+讲解视频)

51单片机简易数字万用表(电阻电流电压测量)仿真设计( proteus仿真+程序+报告+讲解视频)

仿真图proteus7.8及以上

程序编译器:keil 4/keil 5

编程语言:C语言

设计编号:S0041

1.主要功能:

运用所学知识,制作一个51单片机简易数字万用表设计

具体功能:万用表能够切换测量电压值、电流值以及电阻值,并且以四位数码显示,短路时会报警

1、电压测量范围0-20V,测量误差0.5V左右

2、电流测量范围0-200mA,测量误差5mA左右

3、电阻测量范围0-1000欧,误差10欧左右

4、短路报警: 将待测两点用导线相接,蜂鸣器发出声音。

5、通过数码管显示测量数值,通过开关选择测量类型。

以下为本设计资料展示图:

2.仿真

开始仿真

开始仿真后可以通过拨动开关选择测量类型,数码管第一位显示A表示测量电压,B表示测量电阻,C表示测量电流。后三位显示测量的值。如果同时选择了两种测量内容,蜂鸣器报警。

电压档测试:
在仿真时当将电压档开关打开,仿真结果如图3.1所示。改变滑动变阻器相当于改变红黑表笔接的不同回路进行电压测量(可以在重新测量之前按下复位键进行复位后在进行测量)。通过R2,R3进行分压,设测得的电压U,则实际电压U1=(U/R3)*R2;注:所测电压大于20V讲烧坏AD转换器。
img

电阻档测试:
在进行电阻档位仿真时首先进行复位键进行复位,待显示清零以后再进行测量仿真,在仿真过程中改变滑动变阻器的位置相当于改变了红黑表笔所接的不同阻值的电阻。如图4.5所示,设测的电压为U,则电路中电流I=(5-U)/100所测电阻R=U/I=U/((5-U)/100),注:电阻过大,则会造成测量不准确。
img

电流档测试:
在进行电流测量时首先进行电流档复位待显示清零后在进行电流档仿真,改变滑动变阻器相当于改变红黑表笔接的不同回路进行电流测量。如图4.4所示,在测量中若设测得的电压为U:则电路中的电流为I=(U/5)*1000(MA);注:电流过大则会烧坏电阻R4;
img

3. 程序代码

使用keil4或者keil5编译,代码有注释,可以结合报告理解代码含义。

img
主函数代码

void main (void)
{
    
    
	u8 Mode;
	uchar Read_AD;	//用于读取ADC数据
	uchar VIN;			//电压值变量
	u16 RIN;				//电阻值变量
	u16 IIN;				//电流值变量
	u16 i=0;;
	while (1)      				//主循环
	{
    
    		
		if(Key_V==0)				//电压按键按下
		{
    
    
			Key_V=1;					//清除按下标记
			if((Key_R==0)||(Key_I==0))//电阻电流按键也有按下
			{
    
    
				Key_I=1;
				Key_R=1;
				Key_V=1;
				Mode=4;					//标记为错误模式
			}
			else							//电阻电流键都没有按下
			Mode=1;						//标记为电压模式
		}
		if(Key_R==0)				//同电压键
		{
    
    
			Key_R=1;
			if((Key_V==0)||(Key_I==0))
			{
    
    
				Key_I=1;
				Key_R=1;
				Key_V=1;
				Mode=4;
			}
			else
			Mode=2;
		}
		if(Key_I==0)				//同电压键
		{
    
    
			Key_I=1;
			if((Key_V==0)||(Key_R==0))
			{
    
    
				Key_I=1;
				Key_R=1;
				Key_V=1;
				Mode=4;
			}
			else
			Mode=3;
		}
		if((Key_V==1)&&(Key_R==1)&&(Key_I==1))//都没有按下
		{
    
    
			Mode=0;			//标记为空闲模式
		}
		if(i==0)
		{
    
    
		Read_AD=Adc0832(0);				//读取AD值
		}
		i++;
		if(i>300)
			i=0;
			switch(Mode)
		{
    
    
			case 0:
						//空闲模式
								dis_smg[0]=DisplayOther[2];//关闭数码管显示
								dis_smg[1]=DisplayOther[2];
								dis_smg[2]=DisplayOther[2];
								dis_smg[3]=DisplayOther[2];
									Speak = 0;
			break;
			case 1:
						//电压模式
								VIN=Read_AD*200/255;										//换算出电压值
								dis_smg[0]=DisplayNum[0xa];							//显示电压标志
								dis_smg[1]=DisplayNum[VIN/100%10];			//电压十位
								dis_smg[2]=DisplayNum[VIN/10%10]&0x7f;	//电压个位
								dis_smg[3]=DisplayNum[VIN%10];					//电压十分位
								
								if(VIN > 160)	  //电压档大于16V报警
									Speak = 1;
								else
									Speak = 0;
			break;
			case 2:
						//电阻模式		
								RIN=Read_AD*100/(255-Read_AD);				//换算出电阻值
								dis_smg[0]=DisplayNum[0xb];       		//显示电阻标志
								dis_smg[1]=DisplayNum[RIN/100%10];    //电阻百位
								dis_smg[2]=DisplayNum[RIN/10%10];     //电阻十位
								dis_smg[3]=DisplayNum[RIN%10];        //电阻个位
								if(RIN>=1000)													//超过或等于1000;
								{
    
    
									dis_smg[1]=DisplayOther[2];					//显示"-"
									dis_smg[2]=DisplayOther[2];					//显示"-"
									dis_smg[3]=DisplayOther[2];					//显示"-"
								}
								
								if(RIN > 800)		 //电阻档大于800报警
									Speak = 1;
								else
									Speak = 0;
			break;
			case 3:
						//电流模式		
								IIN=4*Read_AD;//单位mA								//换算出电流值
								dis_smg[0]=DisplayNum[0xc];           //显示电流标志
								if(IIN<=200)													//没有超过范围
								{
    
    
									dis_smg[1]=DisplayNum[IIN/100%10];	//电流百位
									dis_smg[2]=DisplayNum[IIN/10%10]; 	//电流十位
									dis_smg[3]=DisplayNum[IIN%10];    	//电流个位
								}
								else
								{
    
    
									dis_smg[1]=DisplayOther[2];					//显示"-"
									dis_smg[2]=DisplayOther[2];					//显示"-"
									dis_smg[3]=DisplayOther[2];					//显示"-"
								}
								
								if(IIN > 80)	 //电流档大于80报警
									Speak = 1;
								else
									Speak = 0;
			break;
			case 4:
							Speak = 1;
						//错误模式		
							dis_smg[0]=DisplayNum[0xe];					//显示"E"
							dis_smg[1]=DisplayNum[0xe];         //显示"E"
							dis_smg[2]=DisplayNum[0xe];         //显示"E"
							dis_smg[3]=DisplayNum[0xe];         //显示"E"
			break;
			default	:	
			break;
		}
		DisplayScan();		//数码管动态扫描
	}
}

概要:
定义了一些变量:

Mode 是一个8位无符号整数,用于存储当前的模式(0-4)。
Read_AD 是一个8位无符号整数,用于存储ADC(模拟到数字转换器)的读取值。
VIN 是一个16位无符号整数,用于存储电压值。
RIN 是一个16位无符号整数,用于存储电阻值。
IIN 是一个16位无符号整数,用于存储电流值。
i 是一个16位无符号整数,用于计数。
主循环(while(1))会一直运行,除非有中断或异常使其停止。

在循环内部,根据按键的状态设置 Mode。这里用到了三个条件判断语句:

如果 Key_V 等于0(表示电压按键被按下),检查其他两个按键是否也被按下。如果是,设置 Mode 为4(错误模式),否则设置 Mode 为1(电压模式)。
如果 Key_R 等于0(表示电阻按键被按下),同样的检查流程,如果其他两个按键没有被按下,设置 Mode 为4,否则设置 Mode 为2(电阻模式)。
如果 Key_I 等于0(表示电流按键被按下),同样的检查流程,如果其他两个按键没有被按下,设置 Mode 为4,否则设置 Mode 为3(电流模式)。
如果所有按键都没有被按下,设置 Mode 为0(空闲模式)。
在读取ADC值时使用了函数 Adc0832(0),这可能是一个硬件相关的函数,用于从ADC设备读取数据。

每300次读取操作后重置计数器,以便重新开始计数。

根据不同的 Mode 执行不同的操作:

在空闲模式下,关闭数码管的显示,并停止声音输出。
在电压模式下,根据从ADC读取的值计算电压,并将其显示在数码管上。如果电压大于160V,发出报警声音。
在电阻模式下,根据从ADC读取的值计算电阻,并将其显示在数码管上。如果电阻大于1000,在百位、十位和个位上都显示"-"。

4. 设计资料内容清单&下载地址

资料设计资料包括仿真,程序代码、讲解视频、功能要求、设计报告、软硬件设计框图。

0、常见使用问题及解决方法–必读!!!!
1、仿真
2、代码
3、讲解视频
4、功能要求
5、设计报告
6、软硬件框图
Altium Designer 软件资料
KEIL 软件资料
Proteus 软件资料
双击打开更多 51 STM32单片机设计.url

img

资料下载链接(可点击):

猜你喜欢

转载自blog.csdn.net/weixin_52733843/article/details/132378500