【蓝桥杯第十一届省赛-电压采集】

【蓝桥杯第十一届省赛-电压采集】

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

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


/*=============================================================
Date:2022-1-26
Author:小殷同学
Version:1.0
==============================================================*/

sfr P4 = 0xc0;

sbit H1 = P3^0;
sbit H2 = P3^1;
sbit H3 = P3^2;
sbit H4 = P3^3;
sbit L1 = P3^4;
sbit L2 = P3^5;
sbit L3 = P4^2;
sbit L4 = P4^4;

sbit Led1 = P0^0;
sbit Led2 = P0^1;
sbit Led3 = P0^2;
sbit Led4 = P0^3;

unsigned char Rd2 = 0,Vp = 200,Count = 0;	//PCF8591电压采集  vP 和计数记录
unsigned char setmode = 0;// 模式切换记录
unsigned char invalid_key = 0;//无效次数按键记录
unsigned char count_flag = 0,led_flag = 0,v_flag = 0; //计时5s 和led标志

unsigned char code smg_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};

unsigned char SMG_Duan_Dot[] = {0x40,0x79,0x34,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; 

//---------------------------简单延时--------------------------
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;
		case 0:P2 = (P2 & 0x1f) | 0X00;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;
}
//-----------------------------数码管界面显示-------------------
//1000 0011	 0xc1 u   0011 0001 0x8c p   1101 1001 0x9b	  n
//1.数据界面
void SMG_Display_Data(void)
{
	SMG_DisplayBit(0,0xc1);
	Delay(200);
	SMG_DisplayBit(1,smg_duan[11]);
	Delay(200);
	SMG_DisplayBit(2,smg_duan[11]);
	Delay(200);
	SMG_DisplayBit(3,smg_duan[11]);
	Delay(200);
	SMG_DisplayBit(4,smg_duan[11]);
	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);
}

//2.参数界面
void SMG_Display_Paramter(void)
{
 	SMG_DisplayBit(0,0x8c);
	Delay(200);
	SMG_DisplayBit(1,smg_duan[11]);
	Delay(200);
	SMG_DisplayBit(2,smg_duan[11]);
	Delay(200);
	SMG_DisplayBit(3,smg_duan[11]);
	Delay(200);
	SMG_DisplayBit(4,smg_duan[11]);
	Delay(200);
	SMG_DisplayBit(5,SMG_Duan_Dot[Vp/100]);
	Delay(200);
	SMG_DisplayBit(6,smg_duan[Vp/10%10]);
	Delay(200);
	SMG_DisplayBit(7,smg_duan[Vp%10]);
	Delay(200);
	SMG_Close();
	Delay(200);
}

//3.计数界面
void SMG_Display_Count(void)
{
 	SMG_DisplayBit(0,0x9b);
	Delay(200);
	SMG_DisplayBit(1,smg_duan[11]);
	Delay(200);
	SMG_DisplayBit(2,smg_duan[11]);
	Delay(200);
	SMG_DisplayBit(3,smg_duan[11]);
	Delay(200);
	SMG_DisplayBit(4,smg_duan[11]);
	Delay(200);	
	if(Count > 99)
	{
		SMG_DisplayBit(5,smg_duan[Count/100]);
		Delay(200);
	}
	if(Count > 9)
	{
		
		SMG_DisplayBit(6,smg_duan[Count/10%10]);
	}
	Delay(200);
	SMG_DisplayBit(7,smg_duan[Count%10]);
	Delay(200);
	SMG_Close();
	Delay(200);
}
//-----------------------------AIN3 Rd2检测--------------------
//Rd2 0x03
unsigned char Read_Rd2_Data(void)
{
	unsigned char temp;
 	IIC_Start();
	IIC_SendByte(0x90); 
	IIC_WaitAck();
	IIC_SendByte(0x43);
	IIC_WaitAck();
	IIC_Stop();

	IIC_Start();
	IIC_SendByte(0x91); 
	IIC_WaitAck();
	temp = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
	return temp;
}
//--------------------------AT24C02写入数据--------------------
void Write_AT24C02(unsigned char addr,unsigned char dat)
{
 	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}
//-----------IIC_Stop();---------------AT24C02读取数据--------------------
unsigned char Read_AT24C02(unsigned char addr)
{
	unsigned char temp;	
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();

	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	temp = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
	return temp;
}
//----------------------------按键扫描-------------------------
void KeyScans(void)
{
 	H3 = 0;
	H1 = H2 = H4 = 1;
	L1 = L2 = L3 = L4 = 1;
	//S17	 vp减 0.5到0时返回5.0v
	if(L1 == 0)
	{	
		Delay(20);
		if(L1 == 0)
		{
			while(L1 == 0)
			{
				if(setmode == 1)
				{
					 Vp -= 50;
					 if(Vp == 0)	//边界处理
					 {
							Vp = 500;
					 }
					 invalid_key = 0;
				}
				else
				{
				 	invalid_key++;		//无效次数累加
				}
			}
		}
	}
	//S13
	if(L2 == 0)
	{
	 	Delay(20);
		if(L2 == 0)
		{
		 	while(L2 == 0)
			{
				Count = 0;	
			}
		}
	}
	H4 = 0;
	H1 = H3 = H2 = 1;
	L1 = L2 = L3 = L4 = 1;
	//S16	 加0.5加到5时 -》0
	if(L1 == 0)
	{
	 	Delay(20);
		if(L1 == 0)
		{
		 	while(L1 == 0)
			{
					if(setmode == 1)
					{
						Vp += 50;
						if(Vp == 500)	 //边界处理
						{
						 	Vp = 0;
						}
						invalid_key = 0;
					}
					else
					{
					 	invalid_key++;//无效次数累加
					}
			}
		}
	}
	//s12
	if(L2 == 0)
	{
	 	Delay(20);
		if(L2 == 0)
		{
		 	while(L2 == 0)
			{
				if(setmode == 0) //数据显示界面
				{
				  setmode = 1;
					SMG_Display_Data();
				}
				else if(setmode == 1)	//参数显示界面
				{
				 	setmode = 2;
					Write_AT24C02(0x00,Vp*10);
					Delay(200);
					SMG_Display_Paramter();
				}
				else if(setmode == 2)	 //计数显示界面
				{
					setmode = 0;
					SMG_Display_Count();
				}
			}
		}
	}
}
//------------------------定时器初始化------------------------
void Init_Timer(void)
{
 	TMOD = 0x01;
	TH0  = (65535-50000)/256;//50ms
	TL0  = (65535-50000)%256;
	TR0  = 1;
	ET0  = 1;
	EA   = 1;
}
//---------------------------Led功能函数----------------------
void Led_Running(void)
{
	//指示灯L1:当VAIN3 < VP的状态持续时间超过5秒时,L1点亮,否则熄灭
 	if(Rd2 < Vp) 
	{
	 	TR0 = 1;
	}
	else
	{
	 	TR0 = 0;
		count_flag = 0;
		led_flag = 0;
	}
	Init_74HC138(4);
	if(led_flag == 1) //VIN3 < Vp超过5s
	{
	 	Led1 = 0;
	}
	else
	{
	 	Led1 = 1;
	}
	//指示灯L2:当前计数值为奇数时,L2点亮,否则熄灭。 
	if(Count % 2 == 0)
	{
	 	Led2 = 1;
	}
	else
	{
	 	 Led2 = 0;
	}
	//指示灯L3:连续3次以上(含3次)的无效按键操作触发L3点亮,直到出现有效的按键操作,L3熄灭
	if(invalid_key >= 3)
	{
	 	Led3 = 0;
	}
	else
	{
	 	Led3 = 1;
	}
	Init_74HC138(0);
}
//--------------------------主函数-----------------------------
void main(void)
{
	Init_System();
	Vp = Read_AT24C02(0x00) * 10;
	while(1)
	{
	 	Rd2 = Read_Rd2_Data();// 计算转换电压
		Rd2 = (Rd2/256.0*5)*100;
		switch(setmode)
		{
		 	case 0:SMG_Display_Data();break;
			case 1:SMG_Display_Paramter();Delay(2000);break;
			case 2:SMG_Display_Count();break;
		}
		if(Rd2 > Vp)
		{
		 	v_flag = 1;
		}
		else if(Rd2 < Vp)
		{
			if(v_flag == 1)
			{
			 	Count++;
				v_flag = 0;
			}
		}
			KeyScans();
		Led_Running();
		
	}
}
//---------------------中断服务函数-------------------------
void Server_Timer0() interrupt 1
{
 	TH0 = (65535-50000)/256;
	TL0 = (65535-50000)%256;
	count_flag++;
	if(count_flag > 100) // 大于5s
	{
	 	count_flag = 0;
		led_flag = 1;
		TR0 = 0;
	}
}

版权声明:本文为CSDN博主「奋斗的小殷」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/boybs/article/details/122713311

生成海报
点赞 0

奋斗的小殷

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

蓝桥杯单片机第十二届省赛

如果有用请点赞,还会继续更新的 题目: 思路: 还是千篇一律的定时器中断,简直就是yyds。这届和第十一届的题可以说是有很多相似的地方,我感觉难点可能还是LED的那个部分

ESP8266 无限重启踩坑

最近做了一个电子墨水屏万年历,在移植屏幕代码时遇到了esp8266无限软复位的问题,如果你的串口打印是以下图片所示,那么恭喜你问题解决了。 造成软复位的原因是因为,程序里有死循环&#xf

DS1302详解(蓝桥杯单片机模块)

特性 实时时钟计算秒、分、小时,日期,月,日、周,年与闰年赔偿有效期至2100年31 x 8支持电池的通用RAM2.0V至5.5V都可运行在2.0V时使用小于300nA电流单字节或多字节