【蓝桥杯第十届省赛题-频率测量与电压输出】

【蓝桥杯第十届省赛题-频率测量与电压输出】

修改版:功能已完成刷新时间还没处理

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include "reg52.h"
#include "iic.h"

/*====================================================
Date:2022-1-15
Author:小殷同学
Version:1.0
=====================================================*/
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;
sbit Led1 = P0^0;
sbit Led2 = P0^1;
sbit Led3 = P0^2;
sbit Led4 = P0^3;
sbit Led5 = P0^4;
//0-9 f - 
unsigned char code SMG_Duan[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
															   0x80,0x90,0x8E,0xbf,0xff};
unsigned char SMG_Duan_Dot[] = {0x40,0x79,0x34,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; 
unsigned int f_count = 0,f_data = 0,t_count = 0;//频率存储和计时
unsigned int  Rd2 = 0,u_dat2 = 0; //存储读取电压值
unsigned char setmode = 0;//界面模式切换 1->频率 2->电压
unsigned char smg_flag = 0; //0-》数码管正常使用  1-》熄灭
unsigned char led_flag = 0;//0-》led指示功能使用 1-》关闭
unsigned char k5 = 0;
//--------------------------------简单延时函数----------------------------
void Delay(unsigned char t)
{
 	while(t--);
}
//------------------------------74HC138初始化-----------------------------
void Init_74HC138(unsigned char n)
{
 	switch(n)
	{
	 	case 4:P2 = (P2 & 0x1f) | 0x80;break;
		case 5:P2 = (P2 & 0x1f) | 0xa0;break;
		case 6:P2 = (P2 & 0x1f) | 0xc0;break;
		case 7:P2 = (P2 & 0x1f) | 0xe0;break;
	}
}
//---------------------------------系统初始化-----------------------------
void Init_System(void)
{
 	Init_74HC138(4);
 	P0 = 0xff;//关闭led
	Init_74HC138(5);
	P0 = 0x00;//关闭继电器蜂鸣器
}
//------------------------------------数码管安位显示----------------------
void SMG_DisplayBit(unsigned char pos,unsigned char dat)
{
 	Init_74HC138(6);
	P0 = (0x01 << pos);
	Init_74HC138(7);
	P0 = dat;
}
//-------------------------------------数码管显示-------------------------
void SMG_Close(void)
{
	Init_74HC138(6);
	P0 = 0xff;
	Init_74HC138(7);
	P0 = 0xff;
}

void SMG_Open(void)
{
 	Init_74HC138(6);
	P0 = 0xff;
	Init_74HC138(7);
	P0 = 0x00;
}

void SMG_Display_F(void)
{
	 SMG_DisplayBit(0,SMG_Duan[10]);
	 Delay(200);
	 SMG_DisplayBit(1,0xff);
	 Delay(200);
	 if(f_data > 99999)
	 {
			SMG_DisplayBit(2,SMG_Duan[f_data/100000]);
	    Delay(200);
	 }
	 if(f_data > 9999)
	 {
			SMG_DisplayBit(3,SMG_Duan[f_data/10000%10]);
	 		Delay(200);
	 }
	 if(f_data > 999)
	 {
			SMG_DisplayBit(4,SMG_Duan[f_data/1000%10]);
	 		Delay(200);
	 }
	 if(f_data > 99)
	 {
		 SMG_DisplayBit(5,SMG_Duan[f_data/100%10]);
	 	 Delay(200);
	 }
	 if(f_data > 9)
	 {
		 SMG_DisplayBit(6,SMG_Duan[f_data/10%10]);
	   Delay(200);
	 }
		SMG_DisplayBit(7,SMG_Duan[f_data%10]);
	  Delay(200);	 
		SMG_Close();
		Delay(200);
}


void SMG_Display_AD(void)
{
	 SMG_DisplayBit(0,0xc1); // U
	 Delay(200);
	 SMG_DisplayBit(1,0xff);
	 Delay(200);
	 SMG_DisplayBit(2,0xff);
	 Delay(200);
	 SMG_DisplayBit(3,0xff);
	 Delay(200);
	 SMG_DisplayBit(4,0xff);
	 Delay(200);															
	 SMG_DisplayBit(5,SMG_Duan_Dot[Rd2/100]);
	 Delay(200);
	 SMG_DisplayBit(6,SMG_Duan[Rd2/10%10]);
	 Delay(200);
	 SMG_DisplayBit(7,SMG_Duan[Rd2%10]);
	 Delay(200);
	 SMG_Close();
	 Delay(200);
}
//-----------------------------------定时器初始化---------------------------
void Init_Timer(void)
{
 	//定时器0计数	  8位自动重装载值	方式二
	TMOD = 0x16;
	TH0 = 0xff;
	TL0 = 0xff;
	//定时器1定时 
	TH1 = (65535-50000)/256;
	TL1 = (65535-50000)%256;

	ET0  = 1; //定时器0中断使能
	ET1  = 1; //定时器1中断使能
	EA   = 1; //中断总开关
	TR0  = 1; //启动定时器0
	TR1  = 1; //启动定时器1
}

//---------------------------------PCF8591ad-da--------------------------------
unsigned char PCF8591_ADC(void)
{
	unsigned char temp;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x43);	//AIN3 可调电阻 
	IIC_WaitAck();
	IIC_Stop();

 	IIC_Start();
	IIC_SendByte(0x91); //读设备地址
	IIC_WaitAck();
	temp = IIC_RecByte();
	IIC_SendAck(1);	 //非应答
	IIC_Stop();
	return temp;
}

//------------------------------------------DAC输出---------------//
void PCF8591_DAC(float dat)
{
  IIC_Start();        //总线启动
	
  IIC_SendByte(0X90); //地址字节 写数据
  IIC_WaitAck();      //等待应答
	
  IIC_SendByte(0X43); //控制字节 模拟输出使能
  IIC_WaitAck();      //等待应答
	
  IIC_SendByte(dat);  //数据字节 数模转换的数据
  IIC_WaitAck();      //等待应答	
  IIC_Stop();         //总线停止
}

//--------------------------------------按键处理-------------------------
void KeyScans(void)
{
	//s4 进行频率和电压界面切换
	if(smg_flag == 0)
	{
		if(S4 == 0)
		{
		 	Delay(20);
			if(S4 == 0)
			{	 							
				while(S4 == 0)
				{
					if(setmode == 0)
					{	 	 
						 //显示电压
						 setmode = 1;
						 SMG_Display_AD();				 
					}
					else if(setmode == 1)
					{
					 	//显示频率
						SMG_Display_F();
						setmode = 0;
					}
				}
			}
		}
	}
	//控制DAC
	if(S5 == 0)
	{
		Delay(20);
		if(S5 == 0)
		{
		 	while(S5 == 0)
			{
				if(k5 == 0)
				{
				 	k5 = 1;
				}
				else if(k5 == 1)
				{
				 	k5 = 0;
				}
					 SMG_Display_AD();			
			}
		}
	}
	 //控制指示灯
	if(S6 == 0)
	{
		Delay(20);
		if(S6 == 0)
		{
		 	while(S6 == 0){
				if(led_flag == 0)
				{
				 	led_flag = 1;
				}
				else if(led_flag == 1)
				{		 	
					Init_74HC138(4);
					P0 = 0xff;
					led_flag = 0;
				}
			}
		}
	}
	//S7控制数码管的使能
	if(S7 == 0)
	{
	 	Delay(20);
		if(S7 == 0)
		{
		 	while(S7 == 0)
			{
				 if(smg_flag == 0)
				 {
						smg_flag = 1;
					  SMG_Open();
				 }
				 else if(smg_flag == 1)
				 {
				 		smg_flag = 0;
						SMG_Close(); //关闭所有数码管
						
				 }
			}
		}
	}
}
//-------------------------------------主函数----------------------------
void main(void)
{
	Init_System();
	Init_Timer();
	while(1)
	{
		
		//Rd2 = (Rd2 /255.0*5)*100;	 //乘100 换成整数好处理需要在显示的将百位一小数点显示就行
		//  500/255  = 1.961
		if(k5 == 0)
		{
			 PCF8591_DAC(102.4);5V对应255,2V对应102.4
			 Rd2 = 200;
		}
		else if(k5 == 1)
		{
			 u_dat2 = PCF8591_ADC(); 
			 Rd2 = u_dat2 * 1.961; 
			 PCF8591_DAC(u_dat2);
		}
	
		KeyScans();
		if(smg_flag == 0)	//默认下数码管开启
		{
			switch(setmode)
			{
			 	case 0:SMG_Display_AD();break;	//AD采集显示
				case 1:SMG_Display_F();break;		//频率显示
			}	 
		}
		else
		{
			 SMG_Close();
		}
		//F < 1KHZ Led4  熄灭  1< f< 5 亮  5 <f<10 熄灭  f > 10亮
		if(led_flag == 0)
		{
			Init_74HC138(4);
			if(f_data < 1000)
			{
				Led4 = 1;	
			}
			else if((f_data >= 1000) && (f_data < 5000))
			{
			 	Led4 = 0;
			}
			else if((f_data >= 5000) && (f_data < 10000))
			{
			 	Led4 = 1;
			} 
			else
			{
			 	Led4 = 0;
			}
			//Rd2 < 1.5v Led3熄灭 1.5<= v <2.5 亮 2.5 <=v<3.5 熄灭 v>=3.5亮
			//扩大100方便算
			if(Rd2 < 150)
			{
				 Led3 = 1;
			}
			else if((Rd2 >= 150) && (Rd2 < 250))
			{
				Led3 = 0;
			}
			else if((Rd2 >= 250) && (Rd2 < 350))
			{
			 	Led3 = 1;
			}
			else 
			{
			 	Led3 = 0;
			}
			//电压测量功能指示:L1点亮,L2熄灭  频率测量功能指示:L1熄灭,L2点亮 
			if(setmode == 0) //电压模式
			{
			 	Led1 = 0;
				Led2 = 1;
			}
			else
			{
			 	Led1 = 1;
				Led2 = 0;
			}
		}
	}
}
//---------------------------------中断服务函数----------------------------
void Server_Timer0() interrupt 1
{
	f_count++;
}

void Server_Timer1() interrupt 3
{
	TH1 = (65535-50000)/256;
	TL1 = (65535-50000)%256;
	t_count++;
	if(t_count == 20) //1s
	{
	 	f_data = f_count;
		f_count = 0;
		t_count = 0;
	}
}
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小殷学长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值