4T第十五届国(sheng)赛模拟题第三套

前言:第三套模拟题,说是国赛其实就是省赛难度,而且出题不规范,导致我一些理解上的错误,但是题目中有一些值得练习的点。

题目


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

个人理解和分析

这是4T官网出的第三套题,也不知道是哪年省赛题的改编,在旋钮时的表述不知道S8按一下在干什么,我就理解成了要按住S8才能扭,就导致我三个点扣了分。
在这里插入图片描述
当然后续刷分可以刷到满分,但是多次提交会判定请求过多,当我写下这篇博文的时候已经时凌晨,便也等不得。相反,我觉得按住再扭旋钮可以作为一个较为新颖的考点。
其他的话甚至没有比今年省赛复杂。我便不展示演示视频了。

底层驱动代码

IIC

unsigned char RB2(){
	unsigned char ret;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x43);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	ret = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	
	return ret;
}

锁存器和延时

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

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

#include <STC12C5A60S2.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(7,0xff);
	outputp0(6,0x01 << (pos - 1));
	outputp0(7,dat);
	Delay(1);
}

void initsys(){
	outputp0(4,0xff);
	outputp0(5,0x00);
	outputp0(6,0xff);
	outputp0(7,0xff);
}

主程序核心代码

注:我没有修改按住才能扭动的功能,代码不难理解,自行修改即可

#include <STC12C5A60S2.H>
#include "intrins.h"
#include "delay.h"
#include "inithc138.h"
#include "iic.h"

#define de 5
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 char show = 0;//显示功能切换
unsigned int time = 0;//传播时间
unsigned int distance = 0;//传播距离
bit canshu = 0;//切换旋钮模式和按钮模式
unsigned char canshuxiaxian = 10;//参数下限
unsigned char canshushangxian = 60;//参数上限
unsigned char baojingcishu = 0;//报警次数
unsigned char voltage = 0;
unsigned char ledstat = 0xff;
bit flag = 1;
unsigned char count = 0;
bit flag2 = 0;
//************************************超声波
sbit TX = P1^0;
sbit RX = P1^1;

void initpca(){
	CMOD = 0x01;
	CCON = 0x00;
}

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

	_nop_();
	_nop_();
	i = 36;
	while (--i);
}

void fangbo(){
	unsigned char i;
	for(i = 0;i < 8;i++){
		TX = 1;
		Delay13us();
		TX = 0;
		Delay13us();
	}
}

void ceju(){
	CL = 0x00;				//设置定时初始值
	CH = 0x00;				//设置定时初始值
	CF = 0;				//清除TF0标志
	CR = 0;				//定时器0开始计时
	
	fangbo();
	CR = 1;
	while((RX == 1) && (CH <= 0x20));
	CR = 0;
	if(RX == 0){
		RX = 1;
		time = (CH << 8) | CL;
		distance = time * 0.017;
	}
}
//************************************
//************************************显示功能
void cejujiemian(){//测距界面
	showsmg(1,Seg_Table[10]);
	showsmg(8,Seg_Table[distance % 10]);
	if(distance > 9){
		showsmg(7,Seg_Table[distance / 10 % 10]);
	}
	if(distance > 99){
		showsmg(6,Seg_Table[distance / 100 % 10]);
	}
}

void canshujiemian(){
	showsmg(1,0x8c);
	if(canshu){
		showsmg(2,Seg_Table[2]);
	}else{
		showsmg(2,Seg_Table[1]);
	}
	showsmg(4,Seg_Table[canshuxiaxian / 10]);
	showsmg(5,Seg_Table[canshuxiaxian  % 10]);
	showsmg(6,Seg_Table[16]);
	showsmg(7,Seg_Table[canshushangxian / 10]);
	showsmg(8,Seg_Table[canshushangxian % 10]);
}

void jilujiemian(){
	showsmg(1,Seg_Table[14]);
	if(baojingcishu < 10){
		showsmg(8,Seg_Table[baojingcishu]);
	}else{
		showsmg(8,Seg_Table[16]);
	}
}
//************************************
//************************************
void showselect(){
	switch(show){
		case 0:cejujiemian();break;
		case 1:canshujiemian();break;
		case 2:jilujiemian();break;
	}
}
//************************************
//************************************按键扫描
void xuanniu(unsigned char channel){
	voltage = RB2();
	if(canshu){
		if(channel == 0){
			if(voltage < 51){
				canshushangxian = 50;
			}else if((51 <= voltage) && (voltage < 102)){
				canshushangxian = 60;
			}else if((102 <= voltage) && (voltage < 153)){
				canshushangxian = 70;
			}else if((153 <= voltage) && (voltage < 204)){
				canshushangxian = 80;
			}else if((204 <= voltage) && (voltage <= 255)){
				canshushangxian = 90;
			}
		}
		if(channel == 1){
			if(voltage < 51){
				canshuxiaxian = 0;
			}else if((51 <= voltage) && (voltage < 102)){
				canshuxiaxian = 10;
			}else if((102 <= voltage) && (voltage < 153)){
				canshuxiaxian = 20;
			}else if((153 <= voltage) && (voltage < 204)){
				canshuxiaxian = 30;
			}else if((204 <= voltage) && (voltage <= 255)){
				canshuxiaxian = 40;
			}
		}
	}
}

void scankey(){
	P33 = 0;P32 = 1;P44 = 1;P42 = 1;
	if(P44 == 0){Delay(de);//S4
		while(P44 == 0){ceju();showselect();}
		show++;
		show %= 3;
		canshu = 0;
	}
	if(P42 == 0){Delay(de);//S8
		while(P42 == 0){xuanniu(0);ceju();showselect();}
		if((show == 1) && (canshu == 0)){
			canshuxiaxian += 10;
			canshuxiaxian %= 50;
		}
	}
	P33 = 1;P32 = 0;P44 = 1;P42 = 1;
	if(P44 == 0){Delay(de);//S5
		while(P44 == 0){ceju();showselect();}
		if(show == 1){
			canshu = ~canshu;
		}
		if(show == 2){
			baojingcishu = 0;
		}
	}
	if(P42 == 0){Delay(de);//S9
		while(P42 == 0){xuanniu(1);ceju();showselect();}
		if((show == 1) && (canshu == 0)){
			canshushangxian += 10;
			if(canshushangxian > 90){canshushangxian = 50;}
		}
	}
}
//************************************
//************************************定时器配置闪烁
void Timer0_Isr(void) interrupt 1
{
	count++;
	if(count == 20){
		flag2 = ~flag2;
		count = 0;
	}
}

void Timer0_Init(void)		//5毫秒@12.000MHz
{
	AUXR |= 0x80;			//定时器时钟1T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0xA0;				//设置定时初始值
	TH0 = 0x15;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
	EA = 1;
}

//************************************
//************************************LED
void julicanshupanduan(){//距离参数判断
	if((distance <= canshuxiaxian) || (distance >= canshushangxian)){
		if(flag == 0){
			flag = 1;
			baojingcishu++;
		}
	}
}

void led(){
	
	if(show == 0){
		ledstat = ledstat & ~0x01;
	}else{
		ledstat = ledstat | 0x01;
	}
	if(show == 1){
		ledstat = ledstat & ~0x02;
	}else{
		ledstat = ledstat | 0x02;
	}
	if(show == 2){
		ledstat = ledstat & ~0x04;
	}else{
		ledstat = ledstat | 0x04;
	}
	
	if((distance >= canshuxiaxian) && (distance <= canshushangxian)){
		ledstat = ledstat & ~0x80;
		flag = 0;
	}else{
		if(flag2){
			ledstat = ledstat & ~0x80;
		}else{
			ledstat = ledstat | 0x80;
		}
	}
	
	outputp0(4,ledstat);
}
//************************************
//************************************
void main(){
	initpca();
	initsys();
	ceju();
	Timer0_Init();
	while(1){
		ceju();
		julicanshupanduan();
		scankey();
		showselect();
		voltage = RB2();
		Delay(1);
		led();
	}
}
  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值