【蓝桥杯单片机】第十二届省赛第二场题目及解答代码

若代码有误,欢迎在评论区批评指正!  

fe9e6eb3d7874072bb96e18c83978fab.png

4fc55d6b8729426d88418f091172ddad.png

dcffd40a3321443ba6aa9bd2642575fe.png

eed1d3564ad14de49919c4573be7355c.png

main.c

#include <REGX52.H>
#include <iic.H>

#define uchar unsigned char
#define uint unsigned int

sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;
sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L3 = P0^2;
sbit L4 = P0^3;
sbit L5 = P0^4;

code uchar Seg_Table[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xc1,0xc8,0xbf}; //16:U,17N,18 -
code uchar Seg_Table_dot[] ={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};

uchar flag_S4,flag_S5,count,count_ms,flag_LED = 1;
uint count_f,dat_f,U,T,U_ROM,dat_f_ROM,U1,U3;
//=================================函数声明命区================================
void hc573(uchar channel);
void delay_s(uint t);
void delay_l(uint xms);
void Nixie(uchar loc,num);
void Nixie_dot(uchar loc,num);
void Init_System();
void display();
void InitTimer();
void LED();
//=============================================================================
void hc573(uchar channel)
{
	switch(channel)
	{
		case 4: P2 = (P2 & 0x1f) | 0x80; break;  //LED
		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 delay_s(uint t)
{
	while(t--);
}
//==================================长延时===========================================
void delay_l(uint xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 12;
		j = 169;
		do
		{
			while (--j);
		} while (--i);
	}
}
//==============================不带小数点的数码管基础显示==================================
void Nixie(uchar loc,num)
{
	hc573(0);
	P0 = 0x01<<(loc-1);
	hc573(6);
	hc573(0);
	P0 = Seg_Table[num];
	hc573(7);
	delay_s(700);
	P0 = 0xff;
	hc573(0);
}
//==============================带小数点的数码管基础显示==================================
void Nixie_dot(uchar loc,num)
{
	hc573(0);
	P0 = 0x01<<(loc-1);
	hc573(6);
	hc573(0);
	P0 = Seg_Table_dot[num];
	hc573(7);
	delay_s(500);
	P0 = 0xff;
	hc573(0);
}

//==================================系统初始化=============================
void Init_System()
{
	hc573(0);
	P0 = 0x00;
	hc573(5);
	hc573(0);
	P0 = 0xff;
	hc573(4);
	hc573(0);
}
//====================================独立键盘检测=======================
void KeyScan()
{
	if(S4==0||S5==0||S6==0||S7==0)
	{
		display();
		if(S4 == 0)
		{
			flag_S4 = (flag_S4 + 1)%3;
			if(flag_S4 == 2) flag_S5 = 0;
			U3 = Read_PCF(0x03);
			while(S4 == 0)
			{
				display();
				LED();
				U1 = Read_PCF(0x01);
				U3 = Read_PCF(0x03);
			}
		}
		if(S5 == 0)
		{
			flag_S5 = (flag_S5 + 1)%2;
			U3 = Read_PCF(0x03);
			while(S5 == 0)
			{
				display();
				LED();
				U1 = Read_PCF(0x01);
				U3 = Read_PCF(0x03);
			}
		}
		if(S6 == 0)
		{
			Write_ROM(0x01,U3/256); delay_l(2);
			Write_ROM(0x02,U3%255); delay_l(2);
			U_ROM = (Read_ROM(0x01)<<8)|Read_ROM(0x02);
			while(S6 == 0)
			{		
				display();
				LED();
				U1 = Read_PCF(0x01);
				U3 = Read_PCF(0x03);
			}
		}
		if(S7 == 0)
		{
			count_ms = 0;
			while(S7 == 0)
			{	
				if(count_ms>=20) count_ms = 21;
				display();
				LED();
				U1 = Read_PCF(0x01);
				U3 = Read_PCF(0x03);
			}
			if(count_ms>=20) flag_LED = 1 - flag_LED;
			else
			{
				Write_ROM(0x03,dat_f/256); delay_l(2);
				Write_ROM(0x04,dat_f%256); delay_l(2);
				dat_f_ROM = (Read_ROM(0x03)<<8)|Read_ROM(0x04);
			}
			
		}
	}
}
//===============================数码管显示==========================
void display()
{
	if(flag_S4 == 0)
	{
		Nixie(1,15);
		if(dat_f>9999) Nixie(4,dat_f/10000);
		if(dat_f>999) Nixie(5,dat_f/1000%10);
		if(dat_f>99) Nixie(6,dat_f/100%10);
		if(dat_f>9) Nixie(7,dat_f/10%10);
		if(dat_f) Nixie(8,dat_f%10);
		
	}
	if(flag_S4 == 1)
	{
		Nixie(1,17);
		T = 1000000/dat_f;
		if(T>9999) Nixie(4,T/10000);
		if(T>999) Nixie(5,T/1000%10);
		if(T>99) Nixie(6,T/100%10);
		if(T>9) Nixie(7,T/10%10);
		if(T) Nixie(8,T%10);
	}
	if(flag_S4 == 2)
	{
		Nixie(1,16);
		Nixie(2,18);
		if(flag_S5 == 0) 
		{
			Nixie(3,1);
			Nixie_dot(6,U1/100);
			Nixie(7,U1/10%10);
			Nixie(8,U1%10);
		}
		if(flag_S5 == 1) 
		{
			Nixie(3,3);
			Nixie_dot(6,U3/100);
			Nixie(7,U3/10%10);
			Nixie(8,U3%10);
		}
	}
}

//=====================定时器0和定时器1的初始化=====================
void InitTimer()
{
	TMOD = 0x06;
	TL0 = 0xff;
	TH0 = 0xff;
	TL1 = (65535 - 50000) % 256;
	TH1 = (65535 - 50000) / 256; //0.05ms
	TR0 = 1;
	TR1 = 1;
	EA = 1;
	ET0 = 1;
	ET1 = 1;
}

//===============================定时器0的中断服务函数============================
void Timer0_Isr(void) interrupt 1
{
	count_f++;
}

void Timer1_Isr(void) interrupt 3
{
	count++;
	count_ms++;
	if(count == 10)
	{
		dat_f = count_f*2;
		count_f = 0;
		count = 0;
	}
}
//================================LED显示=============================
void LED()
{
	hc573(0);
	if(flag_LED == 1)
	{
		if(U3 > U_ROM) L1 = 0;
		else L1 = 1;
		if(dat_f > dat_f_ROM) L2 = 0;
		else L2 = 1;
		if(flag_S4 == 0) L3 = 0;
		if(flag_S4 == 1) L4 = 0;
		if(flag_S4 == 2) L5 = 0;
	}
	else P0 = 0xff;
	hc573(4);
	hc573(0);
	
}
void main()
{
	Init_System();
	InitTimer();
	delay_l(400);
	Write_ROM(0x01,255); delay_l(10);
	Write_ROM(0x02,255); delay_l(10);
	Write_ROM(0x03,255); delay_l(10);
	Write_ROM(0x04,255); delay_l(10);
	U_ROM = (Read_ROM(0x01)<<8)|Read_ROM(0x02);
	dat_f_ROM = (Read_ROM(0x03)<<8)|Read_ROM(0x04);
	while(1)
	{
		KeyScan();
		display();
		LED();
		U1 = Read_PCF(0x01);
		U3 = Read_PCF(0x03);
	}
}

iic.c

/*	#   I2C代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <REGX52.H>
#include <intrins.H>

#define DELAY_TIME	5

sbit scl = P2^0;
sbit sda = P2^1;
static void I2C_Delay(unsigned char n)
{
    do
    {
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();		
    }
    while(n--);      	
}

//
void I2CStart(void)
{
    sda = 1;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 0;
	I2C_Delay(DELAY_TIME);
    scl = 0;    
}

//
void I2CStop(void)
{
    sda = 0;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 1;
	I2C_Delay(DELAY_TIME);
}

//
void I2CSendByte(unsigned char byt)
{
    unsigned char i;
	
    for(i=0; i<8; i++){
        scl = 0;
		I2C_Delay(DELAY_TIME);
        if(byt & 0x80){
            sda = 1;
        }
        else{
            sda = 0;
        }
		I2C_Delay(DELAY_TIME);
        scl = 1;
        byt <<= 1;
		I2C_Delay(DELAY_TIME);
    }
	
    scl = 0;  
}

//
unsigned char I2CReceiveByte(void)
{
	unsigned char da;
	unsigned char i;
	for(i=0;i<8;i++){   
		scl = 1;
		I2C_Delay(DELAY_TIME);
		da <<= 1;
		if(sda) 
			da |= 0x01;
		scl = 0;
		I2C_Delay(DELAY_TIME);
	}
	return da;    
}

//
unsigned char I2CWaitAck(void)
{
	unsigned char ackbit;
	
    scl = 1;
	I2C_Delay(DELAY_TIME);
    ackbit = sda; 
    scl = 0;
	I2C_Delay(DELAY_TIME);
	
	return ackbit;
}

//
void I2CSendAck(unsigned char ackbit)
{
    scl = 0;
    sda = ackbit; 
	I2C_Delay(DELAY_TIME);
    scl = 1;
	I2C_Delay(DELAY_TIME);
    scl = 0; 
	sda = 1;
	I2C_Delay(DELAY_TIME);
}

void delay(unsigned int t)
{
	while(t--);
}
unsigned int Read_PCF(unsigned char addr) //0x03为Rb2   0x01为光敏电阻
{
	unsigned char i;
	unsigned int dat;
	for(i=0;i<=1;i++)
	{
		I2CStart();
		I2CSendByte(0x90);
		I2CWaitAck();
		I2CSendByte(addr);
		I2CWaitAck();
		
		I2CStart();
		I2CSendByte(0x91);
		I2CWaitAck();
		dat = I2CReceiveByte();
		I2CSendAck(1);
		I2CStop();
		dat = dat * 100 / 51;
	}
		delay(1000);
	return dat;
}

void Write_ROM(unsigned char addr,dat)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	I2CSendByte(dat);
	I2CWaitAck();
	I2CStop();
}

unsigned char Read_ROM(unsigned char addr)
{
	unsigned char dat;
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	dat = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	return dat;
}

iic.h

#ifndef __iic_h__
#define __iic_h__

unsigned int Read_PCF(unsigned char addr);
void Write_ROM(unsigned char addr,dat);
unsigned char Read_ROM(unsigned char addr);

#endif

作者:own0913

物联沃分享整理
物联沃-IOTWORD物联网 » 【蓝桥杯单片机】第十二届省赛第二场题目及解答代码

发表评论