蓝桥杯国赛真题试做

不断更新
锁存器、晶体管显示驱动代码、延时函数

void Delay(unsigned int xms)	//@12.000MHz
{
   
   
	while(xms--){
   
   
		unsigned char data i, j;

	i = 12;
	j = 169;
	do
	{
   
   
		while (--j);
	} while (--i);
	}
}

#include <STC15F2K60S2.H>
#include "Delay.h"

void InitHC138(unsigned char channel){
   
   
	switch(channel){
   
   
		case 0:P2 = (P2 & 0x1f) | 0x00;break;
		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;
	}
}

void OutPutP0(unsigned char channel,unsigned char dat){
   
   
	InitHC138(0);
	P0 = dat;
	InitHC138(channel);
	InitHC138(0);
}

void ShowSMG(unsigned char pos,unsigned char dat){
   
   
	OutPutP0(6,(0x01 << (pos - 1)));
	OutPutP0(7,dat);
	Delay(1);
}

void Initsys(){
   
   
	OutPutP0(4,0xff);
	OutPutP0(5,0x00);
	OutPutP0(6,0xff);
	OutPutP0(7,0xff);
}

第8届

底层驱动代码的改动

I2C通讯

开头加上

#include <STC15F2K60S2.H>
#include "intrins.h"
sbit sda = P2^1;
sbit scl = P2^0;

EEPROM存储读取驱动

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

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

DAC转换驱动

void I2CDACWriteByte(unsigned char dat){
   
   
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x41);
	I2CWaitAck();
	I2CSendByte(dat);
	I2CWaitAck();
	I2CStop();
}

核心代码

12μs延时函数:

#include "intrins.h"

void Delay12us(void)	//@12.000MHz
{
   
   
	unsigned char data i;

	_nop_();
	_nop_();
	i = 33;
	while (--i);
}
#include <STC15F2K60S2.H>
#include "Delay.h"
#include "InitHC138.h"
#include "iic.h"

sbit TX = P1^0;
sbit RX = P1^1;

code unsigned char Seg_Table[17] = 
{
   
   
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e, //F
0xbf  //-
};

unsigned int time = 0;
unsigned int distance = 0;//当前测量的距离
unsigned int distance_view = 0;//想要查看的距离
unsigned char cishu;//测量次数
unsigned int dislast = 0;//上次测量的距离
unsigned int dissum = 0;//本次与上次的测量的和
bit caozuo = 0;//操作
bit suc = 0;//测量成功标志位
unsigned char datnum = 0;//数据编号
unsigned char mangquset = 0;//盲区参数
unsigned char mangqu = 0;
unsigned char cishu;//测量次数
unsigned char led_stat = 0xff;
unsigned int count = 0;//数秒数
unsigned char showmode = 0;//显示选择代号
unsigned char shuchu = 0;

//*********************************超声波测量
void fangbo(){
   
   //产生方波
	unsigned char i;
	for(i = 0;i < 8;i++){
   
   
		TX = 1;
		Delay12us();
		TX = 0;
		Delay12us();
	}
}

void ceju(){
   
   //测距
	TMOD &= 0x0f;			//设置定时器模式
	TL1 = 0x00;				//设置定时初始值
	TH1 = 0x00;
	
	fangbo();
	TR1 = 1;
	while((TF1 == 0) && (RX == 1));
	TR1 = 0;
	
	if(TF1 == 0){
   
   
		suc = 1;//测量成功
		TR0 = 1;				//定时器0开始计时
		time = (TH1 << 8) | TL1; 
		distance = time * 0.017;
		I2CWriteByte(cishu,distance);
		cishu++;
		cishu %= 10;
		Delay(10);
		TL1 = 0x00;	TH1 = 0x00;
	}else{
   
   
		TF1 = 0;
	}
}
//*********************************测量成功后闪灯
void Timer0_Isr(void) interrupt 1
{
   
   
	count++;
	if(suc){
   
   
		if(((count % 20) == 0) && ((count % 40) != 0)){
   
   
			led_stat = led_stat & 0xfe;OutPutP0(4,led_stat); 
		}else if((count % 40) == 0){
   
   
			led_stat = led_stat | 0x01;OutPutP0(4,led_stat); 
		}
		if(count == 400){
   
   
			led_stat = led_stat | 0x01;OutPutP0(4,led_stat); 
			count = 0;
			suc = 0;//退出闪灯
			TR0 = 0;
		}
	}
}

void Timer0_Init(void)		//10毫秒@12.000MHz
{
   
   
	AUXR &= 0x7F;			//定时器时钟12T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0xF0;				//设置定时初始值
	TH0 = 0xD8;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	ET0 = 1;				//使能定时器0中断
	EA = 1;
}
//*********************************

//*********************************测距显示界面
void xianshi(){
   
   
	led_stat = (led_stat & 0x3f) | 0xc0;OutPutP0(4,led_stat);
	if(cishu > 1){
   
   
		dislast = I2CReadByte((cishu-2)); 
		Delay(5);
	}
	ShowSMG(1,Seg_Table[caozuo]);
	ShowSMG(6,Seg_Table[distance / 100]);
	ShowSMG(7,Seg_Table[distance / 10 % 10]);
	ShowSMG(8,Seg_Table[distance % 10]);
	
	if(caozuo == 0){
   
   
		ShowSMG(5,Seg_Table[dislast % 10]);
		if(dislast > 9){
   
   
			ShowSMG(4,Seg_Table[dislast / 10 % 10]);
		}
		if(dislast > 99){
   
   
			ShowSMG(3,Seg_Table[dislast / 100]);
		}
	}
	if(caozuo == 1){
   
   
		dissum = I2CReadByte((cishu-2)) + I2CReadByte((cishu-1));
		ShowSMG(5,Seg_Table[dissum % 10]);
		if(dissum > 9){
   
   
			ShowSMG(4,Seg_Table[dissum / 10 % 10]);
		}
		if(dissum > 99){
   
   
			ShowSMG(3,Seg_Table[dissum / 100]);
		}
	}
}
//*********************************
//*********************************数据回显界面
void showecho(){
   
   
	led_stat = (led_stat & 0x3f) | 0x40;OutPutP0(4,led_stat);
	distance_view = I2CReadByte(datnum);
	ShowSMG(1,Seg_Table[datnum / 10]);
	ShowSMG(2,Seg_Table[datnum % 10]);
	ShowSMG(6,Seg_Table[distance_view / 100]);
	ShowSMG(7,Seg_Table[distance_view / 10 % 10]);
	ShowSMG(8,Seg_Table[distance_view % 10]);
}
//*********************************
//*********************************参数设置界面
void canshu(){
   
   
	led_stat = (led_stat & 0x3f) | 0x80;OutPutP0(4,led_stat);
	ShowSMG(1,Seg_Table[15]);
	ShowSMG(7,Seg_Table[mangquset / 10]);
	ShowSMG(8,Seg_Table[mangquset % 10]);
}
//*********************************选择显示
void showselect(){
   
   
	switch(showmode){
   
   
		case 0:xianshi();break;
		case 1:showecho();break;
		case 2:canshu();break;
	}
}
//*********************************
//*********************************模拟信号输出
void DACshuchu(){
   
   
	if(distance <= mangqu){
   
   
		I2CDACWriteByte(0);
	}else{
   
   
		shuchu = (distance - mangqu) * 51 / 100;
		if(shuchu > 255){
   
   
		I2CDACWriteByte(255);
		}else{
   
   
			I2CDACWriteByte(shuchu);
		}
	}
}
//*********************************
//*********************************按键扫描
void scankey(){
   
   
	if(showmode == 0){
   
   
		if(P33 == 0){
   
   //S4
			Delay(5);
			ceju();
			Delay(5);
			while(P33 == 0){
   
   
				showselect();
			}
		}
		if(P30 == 0){
   
   //S7
			Delay(5);
			if(caozuo){
   
   
				caozuo = 0;
			}else{
   
   
				caozuo = 1;
			}
			while(P30 == 0){
   
   
				showselect();
			}
		}
		if(P32 == 0){
   
   //S5
			Delay(5);
			showmode = 1;
			while(P32 == 0){
   
   
				showselect();
			}
		}
		if(P31 == 0){
   
   //S6
			Delay(5);
			showmode = 2;
			while(P31 == 0){
   
   
				showselect();
			}
		}
	}
	if(showmode == 1){
   
   //S5
		if(P32 == 0){
   
   
			Delay(5);
			showmode = 0;
			while(P32 == 0){
   
   
				showselect();
			}
		}
		if(P31 == 0){
   
   //S6
			Delay(5);
			showmode = 2;
			while(P31 == 0){
   
   
				mangqu = mangquset;
				showselect();
			}
		}
		if(P30 == 0){
   
   //S7
			Delay(5);
			datnum++;
			datnum %= 10;
			while(P30 == 0){
   
   
				showselect();
			}
		}
	}
	if(showmode == 2){
   
   
		if(P32 == 0){
   
   //S5
			Delay(5);
			showmode = 1;
			while(P32 == 0){
   
   
				showselect();
			}
		}
		if(P31 == 0){
   
   //S6
			Delay(5);
			showmode = 0;
			while(P31 == 0){
   
   
				mangqu = mangquset;
				showselect();
			}
		}
		if(P30 == 0){
   
   //S7
			Delay(5<
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值