第十届省赛程序设计题--电压频率测量【蓝桥杯真题—01】

【题目要求】

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

在这里插入图片描述
在这里插入图片描述
【实现代码】

#include <STC15F2K60S2.H>
#include <IIC.H>

sbit s7=P3^0;
sbit s6=P3^1;
sbit s5=P3^2;
sbit s4=P3^3;

unsigned char flag_s4=0;//0显示电压,1显示频率
unsigned char flag_s5=0;//DAC输出模式切换按键
unsigned char flag_s6=0;//LED 指示灯功能控制按键
unsigned char flag_s7=0;//数码管显示功能控制
unsigned char flag=0;//ADC采样与DAC输出切换标志位


unsigned char table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};
unsigned char table1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//有小数点段选
unsigned int count;//定时器1定时标志位
unsigned int f;//计算频率
unsigned int dat_f;//NE555的频率
unsigned int dat_v;//rb2的电压
unsigned int dat_rb2;//rb2采样值


//====================================读取电位器 RB2 输出的模拟电压==============================
void Read_RB2()
{
    //进行写操作,选择电位器rb2,AIN3,通道3
	IIC_Start(); 
	IIC_SendByte(0x90); //PCF8591的写设备地址
	IIC_WaitAck(); 
	IIC_SendByte(0x43); //选择通道3,即RB2
	IIC_WaitAck();
	IIC_Stop();

	//进行读取RB2,AIN3通道的电压
	IIC_Start();
	IIC_SendByte(0x91); //PCF8591的读设备地址
	IIC_WaitAck(); 
	dat_rb2=IIC_RecByte();//通道3,即RB2的电压读取存放到dat_v当中
	IIC_Ack(0);         //产生非应答信号
	IIC_Stop();
	
	dat_v=dat_rb2*2;  //计算实际电压值	
}

//DAC输出
void SetData_DAC(unsigned char dat)
{
	IIC_Start(); 
	IIC_SendByte(0x90); //PCF8591的写设备地址
	IIC_WaitAck(); 
	IIC_SendByte(0x40); //DAC电压输出设置
	IIC_WaitAck();
	IIC_SendByte(dat); //设置电压输出参数
	IIC_WaitAck();
	IIC_Stop();
}
//==================================定时器0计数,1定时,进行频率测量==============================
void Init_Timer()
{
    //定时器0用作计数,8位重装方式
	TH0=0XFF;
	TL0=0XFF;
	//定时器1用作定时50ms,测量1s的频率
	TH1=(65536-50000)/256;
	TH1=(65536-50000)%256;

	TMOD=0x16;
	ET0=1;
	ET1=1;
	TR0=1;
	TR1=1;
	EA=1;
}
void Service_Time0() interrupt 1
{
	f++;	
}
void Service_Time1() interrupt 3
{
//	TH1=(65536-50000)/256;
//	TH1=(65536-50000)%256;
	count++;
	if(f%5==0)  
		flag=~flag; 
	if(count==20)//20个50ms,取出1s的频率值
	{
		dat_f=f;
		f=0;
		count=0;
	}		
}

//===================================数码管显示与寄存器选择相关函数=================================
void delay_ms(int n)
{
	int i,j;
	for(i=n;i>0;i--)
		for(j=110;j>0;j--);
}
void SelectHC(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;
	}
}
//第w个数码管显示n,n为对应16进制
void show(unsigned char w,unsigned char n)
{
	SelectHC(6);
	P0=0X01<<w;
	SelectHC(7);
	P0=n;
	delay_ms(5);
	P0=0xff;
	P2&=0x1f;
}
//========================================数码管显示电压和频率=======================================
void Show_F()
{
	show(0,0x8e);
	delay_ms(1);
	show(1,0xff);
	delay_ms(1);
	show(2,0xff);
	delay_ms(1);
	if(dat_f>9999)
	{
		show(3,table[dat_f/10000]);
		delay_ms(1);
	}
	if(dat_f>999)
	{
		show(4,table[dat_f/1000%10]);
		delay_ms(1);
	}
	if(dat_f>99)
	{
		show(5,table[dat_f/100%10]);
		delay_ms(1);
	}
	if(dat_f>9)
	{
		show(6,table[dat_f/10%10]);
		delay_ms(1);
	}
	show(7,table[dat_f/1%10]);
	delay_ms(1);
}
void Show_V()
{
	show(0,0xc1);
	delay_ms(1);
	show(1,0xff);
	delay_ms(1);
	show(2,0xff);
	delay_ms(1);
	show(3,0xff);
	delay_ms(1);
	show(4,0xff);
	delay_ms(1);
	show(5,table1[(dat_v/100)%10]);
	delay_ms(1);
	show(6,table[(dat_f/10)%10]);
	delay_ms(1);
	show(7,table[dat_f%10]);
	delay_ms(1);
}
//========================================LED指示电压和频率=======================================
void LED_F()
{
	if(dat_f<1000)
		P0|=0x04;
	if(dat_f<5000)
		P0&=~0x04;
	if(dat_f<100000)
	    P0|=0x04;
	else
		P0&=~0x04;
}
void LED_V()
{
	if(dat_v<150)
		P0|=0x08;
	if(dat_v<250)
		P0&=~0x08;
	if(dat_v<350)
		P0|=0x08;
	else
		P0&=~0x08;
}

//=======================================LED功能指示函数=======================================
void displayLED()
{
	P2=P2&0X1F;
	if(flag_s6==0)
	{
		if(flag_s4==0)
		{
			P0=0xfe;
			LED_V();
		}
		else
		{
			P0=0xfd;
			LED_F();
		}
		if(flag_s5==0)
			P0|=0x10;  //DAC输出2V电压指示灯
		else 
	   		P0&=~0x10;
	}
	else
		P0=0XFF;
	SelectHC(4);	
}
//=====================================LED与数码管显示函数====================================
void  display()
{
	if(flag_s7==0)
	{
		if(flag_s4==0)
			Show_V();
		else 
		    Show_F();
	}
	else  //数码管显示禁止
	{
		SelectHC(6);
		P0=0XFF;
		SelectHC(7);
		P0=0XFF;
	}
	displayLED();
	P2&=0X1F;
}

//========================================按键开关扫描=======================================
void keys()
{
	if(s4==0)
	{
		delay_ms(1);
		flag_s4=~flag_s4;
		while(s4==0)
		display();
	}
	if(s5==0)
	{
		delay_ms(1);
		flag_s5=~flag_s5;
		while(s5==0)
		display();
	}
	if(s6==0)
	{
		delay_ms(1);
		flag_s6=~flag_s6;
		while(s6==0)
		display();
	}
	if(s7==0)
	{
		delay_ms(1);
		flag_s7=~flag_s7;
		while(s7==0)
		display();
	}	
}


void main()
{
    SelectHC(5);
	P0=0x00;
	P2&=0x1f;
	Init_Timer();
	while(1)
	{
	    keys();
		if(flag==0)
		{
			Read_RB2();
		}
		else
		{
			if(flag_s5==0)
				SetData_DAC(102);//DAC输出2V电压
			else
			    SetData_DAC(dat_rb2);//DAC输出电压随RB2变化
		}
		display();   			
	}
}
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

谏书稀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值