蓝桥杯:第十届—“NE555 AD DA”

目录

 

一、自己写过程中遇到的问题

1、U范围对应L3亮灭总是不对

2、频率测量不正确(范围0-300之间)

二、代码(自己写的)功能基本实现

三、代码改进:

数码管改进:加小数点(码值+10)

 

一、自己写过程中遇到的问题

1、U范围对应L3亮灭总是不对

 用Rb2的范围!!!!

2、频率测量不正确(范围0-300之间)

dat_Hz、count_Hz用int!!!!

二、代码(自己写的)功能基本实现

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

unsigned char code SMG_duanma[20] = {
	//  0   1    2    3    4    5    6    7
		0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
	//  8   9    A10  B11  C12  D13  E14  F15
		0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
	// -16  .17
		0xbf,0x7f,0xff,0xc1};  //共阳数码管
unsigned char code SMG_duanmaDot[19] = {
	// 0.   1.   2.   3.   4.   5.   6.   7.
		0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,
	// 8.   9.   A10  B11  C12  D13  E14  F15
    0x00,0x10,0x88,0x80,0xc6,0xc0,0x86,0x8e,
	// -16  .17
		0xbf,0x7f,0xff};  //数码管(小数点)
unsigned char yi, er, san, si, wu, liu, qi, ba;
		
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;
		
unsigned char Rb2 = 0; U = 0; U_flat = 0;
unsigned int count_Hz = 0;//每秒变化次数计数(频率)
unsigned char count = 0;//1s
unsigned int dat_Hz = 0;//缓存上一秒频率	
unsigned char count_ad = 0;//电压数据刷新时间<=0.5s
		
unsigned char jiemian = 1;//1:电压显示界面(上电默认) / 2:频率显示界面		
unsigned char DACmode = 1;//1:固定输出2v(上电默认)/ 2:输出=Rb2电压
unsigned char LEDkongzhi = 1;//1:LED功能启用(上电默认) / 2:禁用
unsigned char SMGkongzhi = 1;//1:数码管显示功能启用(上电默认) / 2:禁用		

void InitHC138(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 Delayms(unsigned int ms)
{
	unsigned int i, j;
	for (i = ms; i > 0; i--)
		for (j = 845; j > 0; j--);
}

/*==================初始化系统=================================================

============================================================================*/
void InitSystem()
{
	InitHC138(4);
	P0 = 0xff;
	InitHC138(5);
	P0 = 0x00;
}

/*==================数码管=====================================================

============================================================================*/
void SMG_Bit(unsigned pos, unsigned char dat)
{
	InitHC138(7);
	P0 = 0xff;//消影
	InitHC138(6);
	P0 = 0x01 << pos;
	InitHC138(7);
	P0 = dat;
}

void SMG_All(unsigned char dat)
{
	InitHC138(6);
	P0 = 0xff;
	InitHC138(7);
	P0 = dat;
}

void ShowSMG()
{
	SMG_Bit(0, SMG_duanma[yi]);
	Delayms(1);
	SMG_Bit(1, SMG_duanma[er]);
	Delayms(1);
	SMG_Bit(2, SMG_duanma[san]);
	Delayms(1);
	SMG_Bit(3, SMG_duanma[si]);
	Delayms(1);
	SMG_Bit(4, SMG_duanma[wu]);
	Delayms(1);
	if (jiemian == 2)//频率显示界面
	{
		SMG_Bit(5, SMG_duanma[liu]);
		Delayms(1);
	}
	else if (jiemian == 1)//电压显示界面(有小数)
	{
		SMG_Bit(5, SMG_duanmaDot[liu]);
		Delayms(1);
	}
	SMG_Bit(6, SMG_duanma[qi]);
	Delayms(1);
	SMG_Bit(7, SMG_duanma[ba]);
	Delayms(1);
	
	SMG_All(0xff);//数码管最后一位太亮
}

/*==================按键=======================================================
S4:“界面切换”(循环切换)

S5:“输出模式切换”(循环切换)
		①DAC输出电压跟随Rb2输出电压变化
		②固定输出2.0V

S6:“LED功能控制”(循环切换)
		①功能启用
		②功能禁止

S7:“数码管显示功能控制”(循环切换)
		①显示启用
		②显示禁用
============================================================================*/
void ScanKeys()
{
	if (S7 == 0)
	{
		Delayms(5);
		if (S7 == 0)//“数码管显示功能控制”
		{
			if (SMGkongzhi == 1) SMGkongzhi = 2;
			else if (SMGkongzhi == 2) 
			{
				SMGkongzhi = 1;
				yi = 18; er = 18; san = 18; si = 18; wu = 18; liu = 18; qi = 18; ba = 18;
			}
				
		}
		while(!S7)
		{
			ShowSMG();
		}
	}
	
	else if (S6 == 0)//“LED功能控制”
	{
		Delayms(5);
		if (S6 == 0)
		{
			if (LEDkongzhi == 1) LEDkongzhi = 2;
			else if (LEDkongzhi == 2) LEDkongzhi = 1;
		}
		while(!S6)
		{
			ShowSMG();
		}
	}
	
	else if (S5 == 0)//“输出模式切换”
	{
		Delayms(5);
		if (S5 == 0)
		{
			if (DACmode == 1) DACmode = 2;
			else if (DACmode == 2) DACmode = 1;
		}
		while(!S5)
		{
			ShowSMG();
		}
	}
	
	else if (S4 == 0)//“界面切换”
	{
		Delayms(5);
		if (S4 == 0)
		{
			if (jiemian == 1) jiemian = 2;
			else if (jiemian == 2) jiemian = 1;
		}
		while(!S4)
		{
			ShowSMG();
		}
	}
}

/*==================AD=======================================================
电压数据刷新时间<=0.5s
============================================================================*/
unsigned char AD_read(unsigned AIN)//选择通道
{
	unsigned char temp;
	
	IIC_Start();
	IIC_SendByte(0x90);//写0允许
	IIC_WaitAck();
	IIC_SendByte(AIN);
	IIC_WaitAck();
	IIC_Stop();
	
	//Delayms(200);
	
	IIC_Start();
	IIC_SendByte(0x91);//读1允许
	IIC_WaitAck();
	temp = IIC_RecByte();
	IIC_WaitAck();
	IIC_Stop();
	
	return temp;
}

/*==================DA输出=======================================================

============================================================================*/
void OutDA(unsigned char dat)
{
	IIC_Start();
	IIC_SendByte(0x90);//写0允许
	IIC_WaitAck();
	IIC_SendByte(0x40);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}

/*==================NE555+定时器01=======================================================
频率数据刷新时间<=1s

用两个定时器:T0计数(1s计数多少次=>频率(单位时间变化次数))8位自动重装
					   T1定时(1s)16位
============================================================================*/
void InitTimer()
{
	TMOD = 0x16;//0x06 | 0x10
	
//定时器0:(8位)计数
	TH0 = 0xff;
	TL0 = 0xff;
	ET0 = 1;
	TR0 = 1;
	
//定时器1:(16位)定时1s = 1000ms = 100 0000us = 20*50000us
	TH1 = (65535 - 50000 + 1)/256;//+1:有1us误差
	TL1 = (65535 - 50000 + 1)%256;
	ET1 = 1;
	TR1 = 1;
	
	EA = 1;//打开总中断
}

void ServiceTimer0() interrupt 1 //计数
{
	count_Hz++;//记住用int型!!!!!
}

void ServiceTimer1() interrupt 3 //定时
{
	TH1 = (65535 - 50000 + 1)/256;//+1:有1us误差
	TL1 = (65535 - 50000 + 1)%256;
	
	count++;
	count_ad++;
	
	if (count == 20)//1s(频率数据刷新时间<=1s)
	{
		dat_Hz = count_Hz;//记住用int型!!!!!
		count = 0;
		count_Hz = 0;//清零,计算下一秒频率
	}
	
	if (count_ad == 5)//0.25s(电压数据刷新时间<=0.5s)
	{
		count_ad = 0;
		Rb2 = AD_read(3);
		U = Rb2*0.01961;
	}
}

//******************主函数*******************************************************
void main()
{
	InitSystem();
	InitTimer();
	OutDA(102);//2V:0-255  1v-51  2v-102
	
	yi = 19; er = 18; san = 18; si = 18; wu = 18; liu = 3; qi = 4; ba = 1;
	
	while(1)
	{
		ShowSMG();
		ScanKeys();
		
//数码管界面显示		
		if ((jiemian == 1) && (SMGkongzhi == 1))//电压显示界面
		{
			U_flat = Rb2*0.01961*100;
			yi = 19; er = 18; san = 18; si = 18; wu = 18; liu = U_flat/100; qi = (U_flat/10)%10; ba = U_flat%10;
		}
		else if ((jiemian == 2) && (SMGkongzhi == 1))//频率显示界面
		{
			yi = 15; er = 18;
			if (dat_Hz > 99999)//六位数码管123456
			{
				san=dat_Hz/100000;si=(dat_Hz/10000)%10;wu =(dat_Hz/1000)%10;liu=(dat_Hz/100)%10;qi=(dat_Hz/10)%10;ba=dat_Hz%10;
			}
			else if (dat_Hz > 9999)//五位12345
			{
				san=18;si=dat_Hz/10000;wu=(dat_Hz/1000)%10;liu=(dat_Hz/100)%10;qi=(dat_Hz/10)%10;ba=dat_Hz%10;
			}
			else if (dat_Hz > 999)//四位1234
			{
				san=18;si=18;wu=dat_Hz/1000;liu=(dat_Hz/100)%10;qi=(dat_Hz/10)%10;ba=dat_Hz%10;
			}
			else if (dat_Hz > 99)//三位123
			{
				san=18;si=18;wu=18;liu=dat_Hz/100;qi=(dat_Hz/10)%10;ba=dat_Hz%10;
			}
			else if (dat_Hz > 9)//两位12
			{
				san=18;si=18;wu=18;liu=18;qi=dat_Hz/10;ba=dat_Hz%10;
			}
			else if (dat_Hz >= 0)//一位1
			{
				san=18;si=18;wu=18;liu=18;qi=18;ba=dat_Hz%10;
			}
		}
//DAC输出模式		
		if (DACmode == 1)//输出固定电压2.0V
		{
			OutDA(102);
		}
		else if (DACmode == 2)//输出=Rb2电压
		{
			OutDA(Rb2);
		}
/*LED功能:电压测量:L1亮 / L2熄灭	
		      频率测量:L1熄灭 / L2亮
		 L3:电压:U<1.5灭 / 1.5<=U<2.5亮 / 2.5<=U<3.5灭 / U>=3.5亮 
		 L4:频率:F<1K灭  / 1K<=F<5K亮   / 5K<=F<10K灭  / F>=10K亮 
		
		 L5:DAC固定输出时灭 / 变化输出亮*/
		if (LEDkongzhi == 1)//LED功能启用()
		{
			if (jiemian == 1)//电压测量L1亮
			{
				if (DACmode == 1)//(固定输出)L5灭
				{
					if (Rb2 < 78 || ((Rb2>=127.5) && (Rb2<178.5)))//L3灭
					{
						InitHC138(4); P0 = 0xfe;//1111 1110
					}
					else if (Rb2 >= 178.5 || ((Rb2>=78) && (Rb2<127.5)))//L3亮
					{
						InitHC138(4); P0 = 0xfa;//1111 1010
					}
				}
				else if (DACmode == 2)//(变化输出)L5亮
				{
					if (Rb2<78 || ((Rb2>=127.5) && (Rb2<178.5)))//L3灭
					{
						InitHC138(4); P0 = 0xee;//1110 1110
					}
					else if (Rb2>=178.5 || ((Rb2>=78) && (Rb2<127.5)))//L3亮
					{
						InitHC138(4); P0 = 0xea;//1110 1010
					}
				}
			}
			else if (jiemian == 2)//频率测量L2亮
			{
				if (DACmode == 1)//(固定输出)L5灭
				{
					if (dat_Hz<1000 || ((dat_Hz>=5000) && (dat_Hz<10000)))//L4灭
					{
						InitHC138(4); P0 = 0xfd;//1111 1101
					}
					else if (dat_Hz>=10000 || ((dat_Hz>=1000) && (dat_Hz<5000)))//L4亮
					{
						InitHC138(4); P0 = 0xf5;//1111 0101
					}
				}
				else if (DACmode == 2)//(变化输出)L5亮
				{
					if (dat_Hz<1000 || ((dat_Hz>=5000) && (dat_Hz<10000)))//L4灭
					{
						InitHC138(4); P0 = 0xed;//1110 1101
					}
					else if (dat_Hz>=10000 || ((dat_Hz>=1000) && (dat_Hz<5000)))//L4亮
					{
						InitHC138(4); P0 = 0xe5;//1110 0101
					}
				}
			}
		}
		else if (LEDkongzhi == 2)//LED功能禁用
		{
			InitHC138(4); P0 = 0xff;
		}
//数码管功能	
		if (SMGkongzhi == 2)
		{
			yi = 18; er = 18; san = 18; si = 18; wu = 18; liu = 18; qi = 18; ba = 18;
		}
	}
}

三、代码改进:

数码管改进:加小数点(码值+10)

unsigned char code SMG_duanma[30] = {
	//  0   1    2    3    4    5    6    7
		0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
	//  8   9    
		0x80,0x90,//无小数点
	
	// 0.10 1.11 2.12 3.13 4.14 5.15 6.16 7.17  
		0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,
	// 8.18 9.19 
        0x00,0x10,//(+10)小数点!
	
	// A20  B21  C22  D23  E24  F25
		0x88,0x80,0xc6,0xc0,0x86,0x8e,
	// -26  .27 关28  U29
		0xbf,0x7f,0xff,0xc1};  //共阳数码管

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6KGM5LiN5Zyw5LiK,size_20,color_FFFFFF,t_70,g_se,x_16

 

 

蓝桥杯是中国最大的IT技能竞赛之一,其中单片机部分常用的教程是关于NE555定时器的。NE555是一种常用的集成电路,广泛应用于电子电路中的定时和脉冲生成等功能。以下是关于NE555的教程内容: 1. NE555的基本原理:NE555是一种8引脚的集成电路,包含比较器、RS触发器和输出驱动器等功能。它可以通过外部元件连接来实现不同的定时和脉冲生成功能。 2. NE555的引脚功能: - 引脚1(GND):接地引脚,连接到电路的地线。 - 引脚2(TRIG):触发引脚,用于接收外部触发信号。 - 引脚3(OUT):输出引脚,输出NE555产生的脉冲信号。 - 引脚4(RESET):复位引脚,用于复位NE555。 - 引脚5(CTRL):控制引脚,用于控制NE555的工作模式。 - 引脚6(THR):比较器阈值引脚,用于设置比较器的阈值电平。 - 引脚7(DISCH):放电引脚,用于控制输出引脚的放电过程。 - 引脚8(VCC):电源引脚,连接到正电源。 3. NE555的工作模式: - 单稳态模式:NE555在接收到触发信号后,输出一个固定时间的脉冲信号。 - 双稳态模式:NE555在接收到触发信号后,输出一个持续时间取决于外部元件的脉冲信号。 - 震荡模式:NE555通过外部元件的连接,产生一定频率和占空比的方波信号。 4. NE555的应用: - 时钟电路:NE555可以用作时钟电路的计时元件,实现定时功能。 - 脉冲生成器:NE555可以用作脉冲信号的生成器,用于控制其他电路的工作。 - 呼吸灯效果:NE555可以通过改变占空比来实现呼吸灯效果。 - 频率测量:NE555可以通过测量输出信号的频率来实现频率测量功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

行不地上

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

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

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

打赏作者

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

抵扣说明:

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

余额充值