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

链接:https://pan.baidu.com/s/1fscNgkshupeaJGGRapj8UQ 
提取码:2022

(里面包含选择题)

可以直接从百度网盘下载或者将下列代码复制粘贴,其中有蓝桥杯提供的底层代码,有修改的已经标注在开头。

题目

 

 

 

iic.h蓝桥杯底层代码,没有改变

#ifndef _IIC_H
#define _IIC_H

void IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
void IIC_SendAck(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
unsigned char IIC_RecByte(void); 

#endif

 iic.c蓝桥杯底层代码,没有改变

/*
  程序说明: IIC总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台 8051,12MHz
  日    期: 2011-8-9
*/

#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;  					// 0:应答,1:非应答
    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;
}

//通过I2C总线发送数据
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;  
}

//从I2C总线上接收数据
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;    
}

11.c//程序运行代码

#include <reg52.h>
#include "iic.h"

#define uchar unsigned char
#define uint unsigned int

sfr P4=0xc0;//矩阵键盘里面P3^6->P4^2;P3^7->P4^4;P4要进行定义

sbit P3_0=P3^0;
sbit P3_1=P3^1;
sbit P3_2=P3^2;
sbit P3_3=P3^3;
sbit L1=P0^0;
sbit L2=P0^1;
sbit L3=P0^2;

sbit P3_4=P3^4;
sbit P3_5=P3^5;
sbit P4_2=P4^2;
sbit P4_4=P4^4;
	
uchar V_data=0;//电压值
uint P_data=0;//电压参数值扩大100倍
uint N_data=0;//电压相等的次数(注意看触发条件,不是单纯相等就加,要由大变小)
uchar N_flag1=0;//防止一直加
uint L3_flag=0;//控制L3,大于等于3时亮
uchar L1_flag=0;//控制L1

uint key12=0;//按键S12

uint T0_count=0;//定时器

uchar code smg_duan[]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xc1,0x8c,0xc8};

void select_138(uchar x);//138选择
void close_all();//初始化关闭外设
void read_V();//读取Rb2电压
void smg_bit(uchar pos,uchar num);//数码管显示一位,不带小数点
void smg_bit2(uchar pos,uchar num);//数码管显示一位,带小数点
void all_smg(uchar Char);//控制所有数码管,用来消影
void display_V();//显示电压值
void display_P();//显示电压参数值
void display_N();//显示次数

void read_P(uchar addr);//读取电压参数值
void write_P(uchar addr,uchar x);//将电压参数值写入iic地址

void delay(uchar x);//延迟函数

void key_scan();//按键扫描
void display();//总显示
void LED_running();//Led灯
void Timer_init();//定时器初始化

void main()
{
	
	close_all();
	Timer_init();
	read_P(0);//上电后读取电压参数值
	while(1)
	{
		float V_num=0;
		read_V();
		V_num=V_data*1.961;//将读取电压值变为十进制并且扩大100倍
		if (V_num > P_data)//P_data也是电压参数值扩大100倍
		{
			N_flag1 = 1;
		}
		else if (V_num <= P_data)
		{
			if (N_flag1 == 1)//防止一直加
			{
				N_data++;
				N_flag1 = 0;
			}
		}
		
		if(V_num<P_data)//读出电压值小于电压参数,定时器打开
		{
			TR0=1;
		}
		
		if(V_num>=P_data)//读出电压值大于电压参数,定时器关闭,全部重置
		{
			TH0=(65536-50000)/256;
			TL0=(65536-50000)%256;
			TR0=0;
			T0_count=0;L1_flag=0;
		}
		
		key_scan();
		display();
		LED_running();
	}
	
}

//==========138选择========
void select_138(uchar x)
{
	switch(x)
	{
		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;
	}
}
/*
巧记
0x1f=000 1 1111
0x80=100 0 0000    //4
0xa0=101 0 0000    //5
0xc0=110 0 0000    //6
0xe0=111 0 0000    //7
0x00=000 0 0000    //0
看前3位
*/
//============关闭外设===========
void close_all()
{
	select_138(4);
	P0=0xff;
	select_138(5);
	P0=0x00;
	select_138(0);
}

//==========读取Rb2============
void read_V()
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck(); 
	IIC_SendByte(0x43);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck(); 
	V_data=IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
}

//===========数码管=============
void smg_bit(uchar pos,uchar num)
{
	select_138(7);
	P0=0xff;
	select_138(6);
	P0=(0x01<<pos);
	select_138(7);
	P0=smg_duan[num];
	select_138(0);
}

void smg_bit2(uchar pos,uchar num)
{
	select_138(7);
	P0=0xff;
	select_138(6);
	P0=(0x01<<pos);
	select_138(7);
	P0=(smg_duan[num]&0x7f);
	select_138(0);
}

void all_smg(uchar Char)
{
	select_138(6);
	P0=0xff;
	select_138(7);
	P0=Char;
}

void display_V()
{
	smg_bit(0,10);
	delay(500);
	smg_bit2(5,V_data/51);
	delay(500);
	smg_bit(6,(V_data%51)*10/51);
	delay(500);
	smg_bit(7,(((V_data%51)*10)%51)*10/51);
	delay(500);
	all_smg(0xff);
}

void display_P()
{
	smg_bit(0,11);
	delay(500);
	smg_bit2(5,P_data/100);
	delay(500);
	smg_bit(6,P_data%100/10);
	delay(500);
	smg_bit(7,0);
	delay(500);
	all_smg(0xff);
}

void display_N()
{
	smg_bit(0,12);
	delay(500);
	if(N_data>99)
	{
		N_data=0;
	}
	if(N_data>9)
	{
		smg_bit(6,N_data/10);
		delay(500);
	}
	smg_bit(7,N_data%10);
	delay(500);
	all_smg(0xff);
}

//===========读写P_data========
void read_P(uchar addr)
{
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	P_data=IIC_RecByte()*10; 
}

void write_P(uchar addr,uchar x)
{
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_SendByte(x);
	IIC_WaitAck();
	IIC_Stop();		
}

//===========延迟========
void delay(uchar x)
{
	while(x--){};
}

//===========按键========
void key_scan()
{
	P3=0xff;
	P4=0xff;
	P4_4=0;
	if(P3_0==0)//7
	{
		delay(100);
		if(P3_0==0)
		{
			L3_flag++;
			while(!P3_0){display();LED_running();};
		}
	}
	if(P3_1==0)//6
	{
		delay(100);
		if(P3_1==0)
		{
			L3_flag++;
			while(!P3_1){display();LED_running();};
		}
	}
	if(P3_2==0)//5
	{
		delay(100);
		if(P3_2==0)
		{
			L3_flag++;
			while(!P3_2){display();LED_running();};
		}
	}
	if(P3_3==0)//4
	{
		delay(100);
		if(P3_3==0)
		{
			L3_flag++;
			while(!P3_3){display();LED_running();};
		}
	}
	
	P3=0xff;//要重置,不然可能与第一列重复
	P4=0xff;
	P4_2=0;
	if(P3_0==0)//11
	{
		delay(100);
		if(P3_0==0)
		{
			L3_flag++;
			while(!P3_0){display();LED_running();};
		}
	}
	if(P3_1==0)//10
	{
		delay(100);
		if(P3_1==0)
		{
			L3_flag++;
			while(!P3_1){display();LED_running();};
		}
	}
	if(P3_2==0)//9
	{
		delay(100);
		if(P3_2==0)
		{
			L3_flag++;
			while(!P3_2){display();LED_running();};
		}
	}
	if(P3_3==0)//8
	{
		delay(100);
		if(P3_3==0)
		{
			L3_flag++;
			while(!P3_3){display();LED_running();};
		}
	}
	
	P3=0xff;
	P4=0xff;
	P3_5=0;
	if(P3_0==0)//15
	{
		delay(100);
		if(P3_0==0)
		{
			L3_flag++;
			while(!P3_0){display();LED_running();};
		}
	}
	if(P3_1==0)//14
	{
		delay(100);
		if(P3_1==0)
		{
			L3_flag++;
			while(!P3_1){display();LED_running();};
		}
	}
	if(P3_2==0)//13
	{
		delay(100);
		if(P3_2==0)
		{
			L3_flag=0;
			if(key12==2)
			{
				N_data=0;
			}
			while(!P3_2){display();LED_running();};
		}
	}
	if(P3_3==0)//12
	{
		delay(100);
		if(P3_3==0)
		{
			L3_flag=0;
			key12=(key12+1)%3;
			while(!P3_3){display();LED_running();};
		}
	}
	
	P3=0xff;
	P4=0xff;
	P3_4=0;
	if(P3_0==0)//19
	{
		delay(100);
		if(P3_0==0)
		{
			L3_flag++;
			while(!P3_0){display();LED_running();};
		}
	}
	if(P3_1==0)//18
	{
		delay(100);
		if(P3_1==0)
		{
			L3_flag++;
			while(!P3_1){display();LED_running();};
		}
	}
	if(P3_2==0)//17
	{
		delay(100);
		if(P3_2==0)
		{
			L3_flag=0;
			if(key12==1)
			{
				P_data=P_data-50;//按一下减0.5V,扩大100倍就减50
				if(P_data==-50)
				{
					P_data=500;
				}
				write_P(0,P_data/10);//题目要求是电压参数值的10倍,P_data为100倍
			}
			while(!P3_2){display();LED_running();};
		}
	}
	if(P3_3==0)//16
	{
		delay(100);
		if(P3_3==0)
		{
			L3_flag=0;
			if(key12==1)
			{
				P_data+=50;//按一下加0.5V,扩大100倍就加50
				if(P_data==550)
				{
					P_data=0;
				}
				write_P(0,P_data/10);//题目要求是电压参数值的10倍,P_data为100倍
			}
			while(!P3_3){display();LED_running();};
		}
	}
	P3=0xff;
	P4=0xff;
}

//=======总显示=======
void display()
{
	if(key12==0)
	{
		display_V();
	}
	if(key12==1)
	{
		display_P();
	}
	if(key12==2)
	{
		display_N();
	}
}

//==========LED===========
void LED_running()
{
	select_138(4);
	if((N_data%2==0)&&(N_data!=0))
	{
		L2=0;
	}
	if(L3_flag>=3)
	{
		L3=0;
	}
	if(L3_flag<3)
	{
		L3=1;
	}
	if(L1_flag==1)
	{
		L1=0;
	}
	if(L1_flag==0)
	{
		L1=1;
	}
	select_138(0);
}

//========定时器==========
void Timer_init()
{
	TMOD=0x01;
	EA=1;ET0=1;
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	TR0=0;//刚开始关闭,读出电压值小于电压参数时开始
}

void t0() interrupt 1
{
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	T0_count++;
	if(T0_count==100)//5秒
	{
		L1_flag=1;
		T0_count=0;
		TR0=0;
	}
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值