【蓝桥杯单片机】第十届省赛(含题目和解答代码)

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

9f2b540130e84d8e8012e8596cf8ee9e.png

90767225a509432ca23b66e1cdf60812.png

7835d7e04e1d41fba952ec08e18136c9.png

b3c86eba485d4fc7ab536bf7b3c9e08e.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 unsigned char Seg_Table[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xc1}; //16:U
code unsigned char Seg_Table_dot[] ={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};
uchar flag_S4,flag_S5,flag_S6,flag_S7;
uint U,count_f,dat_f,count;
//=======================函数声明区================================
void hc573(uchar channel);
void delay_s(uint t);
void delay_l(uint xms);
void Nixie_dot(uchar loc,num);
void Nixie(uchar loc,num);
void Init_System();
void KeyScan();
void display();
void DAC_S6();
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(500);
	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)
	{
		delay_s(100);
		{
			if(S4 == 0)  //S4按下
			{
				flag_S4 = (flag_S4+1)%2; 
				while(S4 == 0)
				{
					display();
					U = Read_PCF();
					DAC_S6();
					LED();
				}
			}
			if(S5 == 0)  //S5按下
			{
				flag_S5 = (flag_S5+1)%2; 
				while(S5 == 0)
				{
					display();
					U = Read_PCF();
					DAC_S6();
					LED();
				}
			}
			if(S6 == 0)  //S5按下
			{
				flag_S6 = (flag_S6+1)%2; 
				while(S6 == 0)
				{
					display();
					U = Read_PCF();
					DAC_S6();
					LED();
				}
			}
			if(S7 == 0)  //S5按下
			{
				flag_S7 = (flag_S7+1)%2; 
				while(S7 == 0)
				{
					display();
					U = Read_PCF();
					DAC_S6();
					LED();
				}
			}
		}
	}
}

//================定时器初始化================================
void Init_Timer()
{
	TMOD =0x16;    // 计数器0 8位自动重装     定时器1 16位自动重载
	TL1 = (65535 - 50000) % 256;
	TH1 = (65536 - 50000) / 256;
	
	TL0 = 0xff;
	TH0 = 0xff;
	EA = 1;
	ET0 = 1;
	ET1 = 1;
	TR0 = 1;
	TR1 = 1;
}

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

//================定时器1的中端服务函数============================
void Timer1_Isr(void) interrupt 3//定时器1
{
	TL1 = (65535 - 50000) % 256;
	TH1 = (65536 - 50000) / 256;
	count++;
	if(count == 10)
	{
		dat_f = count_f;
		dat_f *=2;
		count_f = 0;
		count = 0;
	}		
}
//======================所有的数码管显示=========================================
void display()
{
	if(flag_S7 == 0)
	{
		if(flag_S4==0) // 电压显示界面
		{
			Nixie(1,16);
			Nixie_dot(6,U/100);
			Nixie(7,U%100/10);
			Nixie(8,U%10);
		}
		if(flag_S4==1)  //频率显示界面
		{
			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);
		}
	}
	else
	{
		hc573(0);
		P0 = 0xff;
		hc573(6);
		hc573(0);
		P0 = 0xff;
		hc573(7);
		hc573(0);
	}
}
//===============S5控制的电压输出=================================
void DAC_S6()
{
	if(flag_S5 == 0)	Write_PCF(102);
	else Write_PCF(U*51/100);
}

//===================S6控制下的LED显示============================
void LED()
{
	hc573(0);
	if(flag_S6 == 0)
	{
		if(flag_S4==0)  L1 = 0;
		if(flag_S4==1)	L2 = 0;
		if(U<150||(U>=250&&U<350)) L3 = 1;
		if(U>=350||(U>=150&&U<250)) L3 = 0;
		if(dat_f<1000||(dat_f>=5000&&dat_f<10000)) L4 = 1;
		if(dat_f>=10000||(dat_f>=1000&&dat_f<5000)) L4 = 0;
		if(flag_S5 == 0) L5 = 1;
		if(flag_S5 == 1) L5 = 0;
	}
	else	P0 = 0xff;
	hc573(4);
	hc573(0);
}

void main()
{
	Init_System();
	Init_Timer();
	while(1)
	{
		KeyScan();
		display();
		U = Read_PCF();
		DAC_S6();
		LED();
	}
}

iic.c

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

#define DELAY_TIME	5
sbit sda = P2^1;
sbit scl = P2^0;
//
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 xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 12;
		j = 169;
		do
		{
			while (--j);
		} while (--i);
	}
}

unsigned int Read_PCF()
{
	unsigned int U;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x03);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	U = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	U = U*100/51;
	delay(10);
	return U;
}

void Write_PCF(unsigned char dat)
{
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x43);
	I2CWaitAck();
	I2CSendByte(dat);
	I2CWaitAck();
	I2CStop();
}

iic.h

#ifndef __iic_h__
#define __iic_h__

unsigned int Read_PCF();
void Write_PCF(unsigned char dat);
#endif 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值