蓝桥杯单片机第十二届省赛第二批——源码及设计思路

距离比赛还有15天,昨天发愤图强,想做一个练练手,又想到了第十二届的第二批没有写,然后在同专业大佬的帮助下,在一天做完了一届,速度最快的一次了,废话不多说,先看原题
请添加图片描述请添加图片描述
请添加图片描述
请添加图片描述

设计思路

第一眼看真是没什么特别难的感觉,就是一个长按键还没有想到解决方法,先从四个按键入手,S4按键切换三个模式,一开始我用的是递归,在四个while循环,直接把整个程序写死在一个函数里面了,也是迫不得已,当时也没想出什么好方法,S5是电压模式切换,这个就是两个模式切换,简单,S6是读取电压值,一看到保存数据,我直接写了个eeprom,后来一想,没必要那么麻烦,直接保存在一个中间变量进行比较就好,S7也是一样的思路。
到了LED的部分,这个一开始我把所有的LED都写到数码管显示的函数里面了,但是注意了,长按S7是可以关闭LED的,但是关闭LED不影响数码管,这就看出来我的代码有很大问题了,所以要记住,LED一定不要和数码管显示放在一个函数里面。
关于长按怎么做,我这里是大佬教我的,用的定时器2,计时1ms,使变量count_led++,如果count_led=1000后,计时1s,把count_led置为0,然后另一个变量,设一个新变量count_S7每1s自加1,这样的话,定时器中断就设置完毕了,接下来就是S7的长按功能,当S7被按下后,使count_led和count_S7都置0,接下来就进行判断,如果count_S7>=1,判断灯的状态,我们设变量aaa灯亮aaa为0,灯灭aaa为1,如果aaa<1则aaa++,把灯灭掉,else aaa=0,让灯亮,这就实现了长按,看文字描述还是不是很懂,要看代码才行。

源代码

IIC.C



#include "reg52.h"
#include "intrins.h"

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1


sbit SDA = P2^1; 
sbit SCL = P2^0;  

void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}

void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}


void IIC_SendAck(bit ackbit)
{
    SCL = 0;
    SDA = ackbit;  					
    IIC_Delay(DELAY_TIME);
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SCL = 0; 
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}


bit IIC_WaitAck(void)
{
    bit ackbit;
	
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}


void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    }
    SCL  = 0;  
}


unsigned char IIC_RecByte(void)
{
    unsigned char i, da;
    for(i=0; i<8; i++)
    {   
    	SCL = 1;
	IIC_Delay(DELAY_TIME);
	da <<= 1;
	if(SDA) da |= 1;
	SCL = 0;
	IIC_Delay(DELAY_TIME);
    }
    return da;    
}

MAIN.C

#include<reg51.h>
#include<iic.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
	sfr AUXR = 0x8e; 
sfr T2H = 0xD6;	 
sfr T2L = 0xD7;	 
sfr IE2 = 0xAF;	
sbit R1=P3^0;
sbit R2=P3^1;
sbit R3=P3^2;
sbit R4=P3^3;
unsigned char code shuzi[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0xbf,0xff};
unsigned char code zimu[]={0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0xc7,0x8c,0xc1,0xc8};
unsigned char code num[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};
unsigned char code weizhi[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char ledweizhi[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff};
unsigned int count_f = 0;
unsigned char count_t = 0;
unsigned int dat_f = 0;//频率数值
unsigned int dat_term = 0;//周期数值
unsigned char S5_mode=4;
uchar mode;
uint count_led=0;
uint count_S7=0;
uint voltage_temp;//存电压的中间变量
uint fre_temp;//存频率的中间变量
uchar i=0;
uchar j=0;
int voltage_rd1;//rd1的电压值
int dat_rd1;//rd1的数值
int voltage_rb2;//rb2的电压值
int dat_rb2;//rb2的数值
uchar aaa=0;//灯的状态
void led_0();
void Scan_S7();
void led_fun();
void Scan_S4();
void Scan_S5();
void Scan_S6();
void delay_ms(int ms)
{
 int q,w;
 for(q = 0;q<ms;q++){
  for(w=845;w>0;w--);
 }
}
void shumaguan_shuzi(uchar a,uchar b)
{
	delay_ms(1);
	P2=(P2&0X1f)|0xC0;P0=weizhi[a];
	P2=(P2&0X1f)|0xE0;P0=shuzi[b];
	delay_ms(1);
}
void shumaguan_zimu(uchar a,uchar b)
{
	delay_ms(1);
	P2=(P2&0X1f)|0xC0;P0=weizhi[a];
	P2=(P2&0X1f)|0xE0;P0=zimu[b];
	delay_ms(1);
}
void ledlight(uchar x)
{
	P2=(P2&0X1f)|0x80;
	P0=ledweizhi[x];
}
void Init()
{
	R1=R2=R3=R4=1;
}


void Init_Timer()
{
	TH0 = 0xff;        
	TL0 = 0xff;
	
	TH1 = (65536 - 50000) / 256;        
	TL1 = (65536 - 50000) % 256;
	TMOD = 0x16;     
  	ET0 = 1;
  	ET1 = 1;
	EA = 1;
	TR0 = 1;
	TR1 = 1;
}

void Timer2(void)
{
	T2H = (65535-1000)/256;
	T2L = (65535-1000)%256;
	EA = 1;
	IE2 |=0x04;   
	AUXR|=0x10;   
}
void Service_T12() interrupt 12
{
		T2H = (65535-1000)/256;
		T2L = (65535-1000)%256;
	if(count_led==1000)
	{
		count_led=0;
		 count_S7++;
	}
	else 	count_led++;
}
void Service_T0() interrupt 1
{
	count_f++;
}
 
void Service_T1() interrupt 3
{
  TH1 = (65536 - 50000) / 256;        
	TL1 = (65536 - 50000) % 256;
	count_t++;
	if(count_t == 20)
	{
		dat_f = count_f;
		count_f = 0;
		count_t = 0;
	}
}
void display_f()
{
	mode=0;
	shumaguan_zimu(0,5);
	if(dat_f>9999)
		shumaguan_shuzi(3,dat_f/10000);
	if(dat_f>999)
		shumaguan_shuzi(4,dat_f/1000%10);
	if(dat_f>99)
		shumaguan_shuzi(5,dat_f/100%10);
	if(dat_f>9)
		shumaguan_shuzi(6,dat_f/10%10);
		
		shumaguan_shuzi(7,dat_f%10);
	
}
void display_term()
{
	mode=1;
	
	shumaguan_zimu(0,10);
	dat_term=1000000/dat_f;
	if(dat_f>9999)
		shumaguan_shuzi(3,dat_term/1000);
	if(dat_f>999)
		shumaguan_shuzi(4,dat_term/1000%10);
	if(dat_f>99)
		shumaguan_shuzi(5,dat_term/100%10);
	if(dat_f>9)
		shumaguan_shuzi(6,dat_term/10%10);
		
		shumaguan_shuzi(7,dat_term%10);
}
void display_RD1()
{
	mode=2;
	
	IIC_Start();						
	IIC_SendByte(0x90); 	
	IIC_WaitAck();  	
	IIC_SendByte(0x01);
	IIC_WaitAck();  						
	IIC_Stop(); 						
	
	IIC_Start();											
	IIC_SendByte(0x91); 			
	IIC_WaitAck(); 				
	dat_rd1 = IIC_RecByte();	 			
	IIC_WaitAck(); 						
	IIC_Stop(); 						

	
	voltage_rd1=dat_rd1*100/51;
	shumaguan_zimu(0,9);
	shumaguan_shuzi(1,10);
	shumaguan_shuzi(2,1);
	shumaguan_shuzi(6,voltage_rd1%100/10);
	shumaguan_shuzi(7,voltage_rd1%10);
	P2=(P2&0X1f)|0xC0;P0=weizhi[5];
	P2=(P2&0X1f)|0xFF;P0=shuzi[voltage_rd1/100]+0x80;
}
void display_Rb2()
{
	mode=3;
	
	IIC_Start();						
	IIC_SendByte(0x90); 	
	IIC_WaitAck();  	
	IIC_SendByte(0x03);
	IIC_WaitAck();  						
	IIC_Stop(); 						
	
	IIC_Start();											
	IIC_SendByte(0x91); 			
	IIC_WaitAck(); 				
	dat_rb2 = IIC_RecByte();	 			
	IIC_WaitAck(); 						
	IIC_Stop(); 						

	
	voltage_rb2=dat_rb2*100/51;
	shumaguan_zimu(0,9);
	shumaguan_shuzi(1,10);
	shumaguan_shuzi(2,3);
	shumaguan_shuzi(6,voltage_rb2%100/10);
	shumaguan_shuzi(7,voltage_rb2%10);
	P2=(P2&0X1f)|0xC0;P0=weizhi[5];
	P2=(P2&0X1f)|0xFF;P0=shuzi[voltage_rb2/100]+0x80;
}
void Scan_S4()
{
		if(R4==0)
		{
			while(R4==0){display_term();}
			while(1)
			{
				led_fun();
					Scan_S7();
				display_term();
			
				if(R4==0)
				{
					
					if(R4==0)
					{
							while(R4==0){display_RD1();}
						while(1)
						{
							led_fun();
								Scan_S7();
							display_RD1();
							Scan_S5();
							
							if(R4==0) 
							{
								delay_ms(60);
								if(R4==0)
								{
										while(R4==0){display_f();}
									while(1)
									{
										
										led_fun();
										Scan_S7();
										display_f();
									
										if(R4==0)
										{
										
											if(R4==0)
											{
													while(R4==0){Scan_S4();}
												while(1)
												{
													Scan_S4();
												}
											}
										}
										while(R4==0);
									}
									while(R4==0);
								}
							}
							while(R4==0);
						}
						
						while(R4==0);
					}
				}
				while(R4==0);
			}
			while(R4==0);
		}
	
}
void Scan_S5()
{
	
	
	if(R3==0)
	{
		delay_ms(10);
	if(R3==0)
	{
		S5_mode++;
		while(R3==0);
	}
	}
	if(S5_mode%2==0)
	{
		display_RD1();
	}
	if(S5_mode%2==1)
	{
		while(1)
		{
			led_fun();
			Scan_S7();
			Scan_S6();
			display_Rb2();
			if(R3==0)
			{
				delay_ms(10);
				if(R3==0)
				{
					break;
					while(R3==0);
				}
			}
		}
	}
}
void Scan_S6()
{

	if(R2==0)
	{
		delay_ms(50);
		if(R2==0)
		{
			voltage_temp=voltage_rb2;
		
			while(R2==0);
		}
}
}
void Scan_S7()
{
	if(R1==0)
	{
			count_S7=0;
			count_led=0;
			while(R1==0);
			if(count_S7>=1) {if(aaa<1) aaa++;else aaa=0;}
			else 
				{
						
						fre_temp=dat_f;
				}
}
}
void led_fun()
{
	if(aaa==0)
	{
	if(mode==0)
	{
		if(dat_f>fre_temp)
	{
	P2=(P2&0X1f)|0x80;
	P0=0xf9;
	}
	else ledlight(2);
	}
	if(mode==1)
	{
	ledlight(3);
	}
	if(mode==2)
	{
		ledlight(4);
	}
	if(mode==3)
	{
	if(voltage_rb2>voltage_temp)
	{
	P2=(P2&0X1f)|0x80;
	P0=0xee;
	}
	else ledlight(4);
	}
}
	if(aaa==1)
	{
		P2=0x80;P0=0xff;
	}
}

void main()
{
	Init_Timer();
	Timer2();
	Init();
	while(1)
	{
		led_fun();
		Scan_S7();
		Scan_S6();
		Scan_S4();
		display_f();
	
	}
}


总体来说,就是长按键那里有点让人懵,剩下的部分还是很简单的。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Sol-itude

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

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

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

打赏作者

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

抵扣说明:

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

余额充值