[El Sprint 02 de simulación de competencia provincial de la 13.ª Copa Blue Bridge MCU]

La 13.ª Copa del Puente Azul MCU Competición Provincial Simulación Sprint 02

El tema viene del taller de diseño electrónico
En la última semana o dos, estuve haciendo dos conjuntos de preguntas de simulación y practiqué el uso de cada módulo.

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

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

/**************************************
*第十三届蓝桥杯单片机省赛模拟
*Date:2022-3-29
*Author:小殷
***************************************/

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;

unsigned char s_press = 0,s_count = 0; //按键按下标志位和计时
unsigned char count = 0,led_flag = 0;	//计时  led标志位
unsigned int count_value = 0,count_value2 = 0;//按键值 和保存值
unsigned char interface = 1;	//界面
//数码管段码
unsigned char code smg_data[] = {
    
    0xC0,0xF9,0xA4,0xB0,0x99,0x92,
																	0x82,0xF8,0x80,0x90,0xbf,0xff};


//1简单延时
void delay(unsigned int t)
{
    
    
 	while(t--);
}

//操作锁存器
void Init_74HC138(unsigned char channel)
{
    
    
 	switch(channel)
	{
    
    
	 	case 4:P2 = (P2 & 0x1f) | 0x80;break; //Y4
		case 5:P2 = (P2 & 0x1f) | 0xa0;break; //Y5
		case 6:P2 = (P2 & 0x1f) | 0xc0;break; //Y6
		case 7:P2 = (P2 & 0x1f) | 0xe0;break; //Y7
		case 0:P2 = (P2 & 0x1f) | 0x00;break; //不选通任何一个
	}
		P2 = (P2 & 0x1f) | 0x00;
}

//数码管安位操作
void SMG_DisplayBit(unsigned char pos,unsigned char dat)
{
    
    
 	P0 = (0x01 << pos);
	Init_74HC138(6);
	P0 = dat;
	Init_74HC138(7);
}

//操作所有数码管
void SMG_All(unsigned char dat)
{
    
    
 	P0 = 0xff;
	Init_74HC138(6);
	P0 = dat;
	Init_74HC138(7);
}


//显示数码管数据 累加和减的数据
void SMG_Display_Data1(void)
{
    
    
 //0001 0001  ->0x88
 	SMG_DisplayBit(0,0x88);
	delay(200);
	//	SMG_DisplayBit(0,0xff);
	SMG_DisplayBit(1,0xff);
	delay(200);
	SMG_DisplayBit(2,0xff);
	delay(200);
	SMG_DisplayBit(3,0xff);
	delay(200);
	SMG_DisplayBit(4,0xff);
	delay(200);
	//3位数码管来显示键值
	if(count_value > 99)
	{
    
    
		SMG_DisplayBit(5,smg_data[count_value/100]);
	 	delay(200);
	}
	if(count_value > 9)
	{
    
    
			SMG_DisplayBit(6,smg_data[count_value/10%10]);
			delay(200);
	}
	
	SMG_DisplayBit(7,smg_data[count_value%10]);
	delay(200);
	SMG_All(0xff);
	delay(200);
}


//系统初始化
void Init_System(void)
{
    
    
 	P0 = 0xff;
	Init_74HC138(4);
	P0 = 0x00;
	Init_74HC138(5);
	SMG_All(0xff);
}

//回显数据显示
void SMG_Display_Data2(void)
{
    
    
 //1001 0001 ->0x89
 	SMG_DisplayBit(0,0x89);
	delay(200);
	//	SMG_DisplayBit(0,0xff);
	SMG_DisplayBit(1,0xff);
	delay(200);
	SMG_DisplayBit(2,0xff);
	delay(200);
	SMG_DisplayBit(3,0xff);
	delay(200);
	SMG_DisplayBit(4,0xff);
	delay(200);
	//3位数码管来显示键值
	if(count_value > 99)
	{
    
    
		SMG_DisplayBit(5,smg_data[count_value2/100]);
	 	delay(200);
	}
	if(count_value > 9)
	{
    
    
			SMG_DisplayBit(6,smg_data[count_value2/10%10]);
			delay(200);
	}
	
	SMG_DisplayBit(7,smg_data[count_value2%10]);
	delay(200);
	SMG_All(0xff);
	delay(200);
}


//EEPROM写操作
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();
}

//读操作
unsigned char Read_AT24C02(unsigned char addr)
{
    
    
 	unsigned int temp = 0;
	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 Key_Scan(void)
{
    
    
	H3 = 0;
	H1 = H2 = H4 = 1;
	L1 =  L2 = L3 = L4 = 1;
	//S9		回显
	if(L3 == 0)
	{
    
    
	 	delay(20);
		if(L3 == 0)
		{
    
    
		 	while(L3 == 0){
    
    
			if(interface == 1)
			{
    
    
			 	interface = 2; //界面切换
				SMG_Display_Data1();	
			}
			else if(interface == 2)
			{
    
    
			 	interface = 1;
				SMG_Display_Data2();
			}
		}
		}
	}
	//S5 减
	else if(L4 == 0)
	{
    
    
	 	delay(20);
		if(L4 == 0)
		{
    
    
			
		 	while(L4 == 0)	 
			{
    
    
				SMG_Display_Data1();
			}
			 //在计数界面下进行键值的减
			if(interface == 1)
			{
    
    
					count_value--;
			}
		
		}
	}

	H4 = 0;
	H1 = H2 = H3 = 1;
	L1 =  L2 = L3 = L4 = 1;
	//S8	存储
	if(L3 == 0)
	{
    
    
	 	delay(20);
		if(L3 == 0)
		{
    
    
			//每次按下时将计时和标志位清零
			s_press = 0;
			s_count = 0;
		 	while(L3 == 0)	
			{
    
    
					SMG_Display_Data1();
			}	
			if(s_press == 1)	 //长按标志
			{
    
    
			 	count_value = 0;			//计数清零
			}
			//短按
			else
			{
    
    
				if(interface == 1)
				{
    
    
				 	//count_value2 = count_value;		//保存当前值
					Write_AT24C02(0x00,count_value);
				}
			}
		
		}
	}
	//S4  加
	else if(L4 == 0)
	{
    
    
	 	delay(20);
		if(L4 == 0)
		{
    
    		
			
			 	while(L4 == 0)
				{
    
    
				 	SMG_Display_Data1();
				}
				//在计数界面下 进行键值的累加
				if(interface == 1)
				{
    
    
					count_value++;
				}
		}
	}

}


//dac数据
void Read_DAC(float dat)
{
    
    
 	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x43);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}




//电压显示
void Voltage_Tackle(void)
{
    
    
 	//为5非0 整数倍	 DAC->4  ELSE DAC ->1
	if((count_value % 5)== 0)
	{
    
    
	 	Read_DAC(204); //数字转模拟	  0-5  ->0-255
		//5/255 = 4/x    4x51 = 204
	}
	else
	{
    
    
	 	Read_DAC(51);
	}
}

void Led_Tackle(void)
{
    
    
	if(interface == 1)
	{
    
    
	 	LED1 = 0;
	}
	else
	{
    
    
	 	LED1 = 1;
	}
	if(count_value > count_value2)
	{
    
    
	 		if(led_flag == 0)
			{
    
    
			 	LED2 = 0;
			}
			else if(led_flag == 1)
			{
    
    
			 	LED2 = 1;
			}
	}
	Init_74HC138(4);
}


void Init_Timer(void)
{
    
    
 	TMOD = 0x01;
	TH0 = (65535-50000)/256;		 //50ms
	TL0 = (65535-50000)%256;
	ET0 = 1;
	TR0 = 1;
	EA  = 1;
}
//主函数
void main(void)
{
    
    
	Init_System();
	Init_Timer();
	while(1)
	{
    
    
		Key_Scan();
	 	switch(interface)
		{
    
    
		 	case 1:SMG_Display_Data1();break;
			case 2:
						count_value2 = Read_AT24C02(0x00);
						SMG_Display_Data2();break;
		}
		Led_Tackle();
		Voltage_Tackle();
		
	}
}


void Server_Timer0() interrupt 1
{
    
    
 	TH0 = (65535-50000)/256;		 //50ms
	TL0 = (65535-50000)%256;
	count++;
	s_count++;
	if(count == 4) //0.2s 开启led标志位
	{
    
    
		count = 0;
	 	if(led_flag == 0)
		{
    
    
		 	led_flag = 1;
		}
		else if(led_flag == 1)
		{
    
    
		 	led_flag = 0;
		}
	}

	if(s_count == 40) //定时2s
	{
    
    
	 	s_press = 1; //长按标志位置1 代表已进入长按模式
	} 

}

Supongo que te gusta

Origin blog.csdn.net/boybs/article/details/123829667
Recomendado
Clasificación