一份不知道哪里来的第十五届国赛模拟题

这是一个不知道来源的模拟题目,没有完全完成,只作代码记录,不作分析和展示,极其冗长,但里面有长按短按双击的复合,可以看看。

题目

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

代码

底层驱动

IIC(EEPROM没在主程序用)

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

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

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

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

主程序核心代码

#include <STC15F2K60S2.H>
#include "intrins.h"
#include "inithc138.h"
#include "delay.h"
#include "onewire.h"
#include "iic.h"
#include "ds1302.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 char canshu = 0;//参数界面切换
bit mode = 1;//控制模式切换
unsigned char jiaozhun = 0;//校准设置切换
bit huixian = 0;//回显模式切换
unsigned int temp = 0;//温度
bit ce = 1;
unsigned int time = 0;//超声波传播时间
long distance = 0;//距离
unsigned char cejushangxian = 80;//测距上限
unsigned char cejuxiaxian = 20;//测距下限
unsigned int tempcan = 30;//温度参数
unsigned char light = 0;//光敏参数
unsigned char ds1302writeaddr[3] = {0x80,0x82,0x84};
unsigned char ds1302readaddr[3] = {0x81,0x83,0x85};
unsigned char rtctime[3] = {0x05,0x29,0x10};
char disjiao = 0;//距离校准值
int tempjiao = 0;//温度校准值
unsigned char temptime[3] = {0};//温度超限时间
unsigned char distime[3] = {0};//温度超限时间
double daczhi = 0;//DAC输出大小
bit zhouqi = 0;//1为进入按键周期
unsigned char keycount = 0;//按键周期计时
unsigned char cishu = 0;
bit zhouqi1 = 0;//1为进入按键周期
unsigned char keycount1 = 0;//按键周期计时
unsigned char cishu1 = 0;
bit keystat = 0;//按键状态(长短按)
unsigned int count = 0;//长按计时
unsigned char ledstat = 0xff;
unsigned char ledcount = 0;
bit ledflag = 0;
bit chaoxian = 0;
unsigned int tempshow = 0;//校准后的温度
//*****************************************测温模块
void cewen(){
	unsigned char LSB,MSB;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	if(ce){
		Delay(520);
	}
	ce = 0;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	LSB = Read_DS18B20();
	MSB = Read_DS18B20();
	init_ds18b20();
	
	temp = ((MSB << 8) | LSB) * 0.625;
	tempshow = temp + tempjiao;
	
}
//*****************************************
//*****************************************超声波模块
sbit TX = P1^0;
sbit RX = P1^1;
void showselect();
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 initpca(){
	CMOD = 0x01;
	CCON = 0x00;
}

void ceju(){
	CH = 0x00;
	CL = 0x00;
	CF = 0;
	CR = 0;			
	
	fangbo();
	CR = 1;
	while((RX == 1) && (CH < 0x17));
	CR = 0;
	
	if(RX == 0){
		RX = 1;
		time = (CH << 8) | CL;
		distance = time * 0.017;
	}
}
//*****************************************
//*****************************************DS1302实时时钟
void ds1302config(){
	unsigned char i;
	Write_Ds1302_Byte(0x8e,0x00);
	for(i = 0;i < 3;i++){
		Write_Ds1302_Byte(ds1302writeaddr[i],rtctime[i]);
	}
	Write_Ds1302_Byte(0x8e,0x80);
}

void ds1302read(){
	unsigned char i;
	for(i = 0;i < 3;i++){
		rtctime[i] = Read_Ds1302_Byte(ds1302readaddr[i]);
	}
}
//*****************************************
//*****************************************显示功能
void shujujiemian(){//数据界面
	showsmg(1,Seg_Table[12]);
	showsmg(2,Seg_Table[tempshow / 100]);
	showsmg(3,Seg_Table[tempshow / 10 % 10] & 0x7f);
	showsmg(4,Seg_Table[tempshow % 10]);
	
	if((distance + disjiao) >= 0){
			showsmg(8,Seg_Table[(distance + disjiao) % 10]);
		if((distance + disjiao) > 9){
			showsmg(7,Seg_Table[(distance + disjiao) / 10 % 10]);
		}
	}else{
		showsmg(7,0xc7);
		showsmg(8,0xc7);
	}
}

void p1(){//参数P1
	showsmg(1,0x8c);
	showsmg(2,Seg_Table[1]);
	showsmg(6,0x89);
	showsmg(7,Seg_Table[cejushangxian / 10]);
	showsmg(8,Seg_Table[cejushangxian % 10]);
}

void p2(){//参数P2
	showsmg(1,0x8c);
	showsmg(2,Seg_Table[2]);
	showsmg(6,0xc7);
	showsmg(7,Seg_Table[cejuxiaxian / 10]);
	showsmg(8,Seg_Table[cejuxiaxian % 10]);
}

void p3(){//参数P3
	showsmg(1,0x8c);
	showsmg(2,Seg_Table[3]);
	showsmg(7,Seg_Table[tempcan / 10]);
	showsmg(8,Seg_Table[tempcan % 10]);
}

void p4(){//参数P4
	showsmg(1,0x8c);
	showsmg(2,Seg_Table[4]);
	if(mode){
		showsmg(4,0x8c);
		showsmg(5,Seg_Table[14]);
	}else{
		showsmg(4,Seg_Table[10]);
		showsmg(5,0xc1);
	}
	showsmg(8,Seg_Table[light % 10]);
	if(light > 9){
		showsmg(7,Seg_Table[light / 10 % 10]);
	}
	if(light > 99){
		showsmg(6,Seg_Table[light / 100 % 10]);
	}
}

void canshujiemian(){//参数界面
	switch(canshu){
		case 0:p1();break;
		case 1:p2();break;
		case 2:p3();break;
		case 3:p4();break;
	}
}

void shijianjiemian(){//时间显示
	showsmg(1,Seg_Table[rtctime[2] / 16]);
	showsmg(2,Seg_Table[rtctime[2] % 16]);
	showsmg(3,Seg_Table[16]);
	showsmg(4,Seg_Table[rtctime[1] / 16]);
	showsmg(5,Seg_Table[rtctime[1] % 16]);
	showsmg(6,Seg_Table[16]);
	showsmg(7,Seg_Table[rtctime[0] / 16]);
	showsmg(8,Seg_Table[rtctime[0] % 16]);
}

void f1(){
	showsmg(1,Seg_Table[15]);
	showsmg(2,Seg_Table[1]);
	if(disjiao >= 0){
		showsmg(8,Seg_Table[disjiao % 10]);
		if(disjiao > 9){
			showsmg(7,Seg_Table[disjiao / 10 % 10]);
		}
	}else if(disjiao < 0){
		if(disjiao >= -9){
			showsmg(8,Seg_Table[-(disjiao) % 10]);
			showsmg(7,Seg_Table[16]);
		}
		if(disjiao < -9){
			showsmg(8,Seg_Table[-(disjiao) % 10]);
			showsmg(7,Seg_Table[-(disjiao) / 10 % 10]);
			showsmg(6,Seg_Table[16]);
		}
	}
}

void f2(){
	showsmg(1,Seg_Table[15]);
	showsmg(2,Seg_Table[2]);
	if(tempjiao > 0){
		showsmg(8,Seg_Table[tempjiao % 10]);
		showsmg(7,Seg_Table[tempjiao  / 10 % 10] & 0x7f);
	}else if(tempjiao < 0){
		showsmg(8,Seg_Table[(-tempjiao) % 10]);
		showsmg(7,Seg_Table[(-tempjiao) / 10 % 10] & 0x7f);
		showsmg(6,Seg_Table[16]);
	}else if(tempjiao == 0){
		showsmg(8,Seg_Table[0]);
	}
}

void f3(){
	showsmg(1,Seg_Table[15]);
	showsmg(2,Seg_Table[3]);
	if(mode){
		showsmg(7,0x8c);
		showsmg(8,Seg_Table[14]);
	}else{
		showsmg(7,Seg_Table[10]);
		showsmg(8,0xc1);
	}
}

void jiaozhunshezhi(){//校准设置界面
	switch(jiaozhun){
		case 0:f1();break;
		case 1:f2();break;
		case 2:f3();break;
	}
}

void wenduchaoxian(){//温度超限时间记录
	showsmg(1,0x8b);
	showsmg(2,0xa7);
	if(temptime[2] != 0){
		showsmg(3,Seg_Table[temptime[2] / 16]);
		showsmg(4,Seg_Table[temptime[2] % 16]);
		showsmg(5,Seg_Table[temptime[1] / 16]);
		showsmg(6,Seg_Table[temptime[1] % 16]);
		showsmg(7,Seg_Table[temptime[0] / 16]);
		showsmg(8,Seg_Table[temptime[0] % 16]);
	}
}

void julichaoxian(){//距离超限时间记录
	showsmg(1,0x8b);
	showsmg(2,0xa1);
	if(distime[2] != 0){
		showsmg(3,Seg_Table[distime[2] / 16]);
		showsmg(4,Seg_Table[distime[2] % 16]);
		showsmg(5,Seg_Table[distime[1] / 16]);
		showsmg(6,Seg_Table[distime[1] % 16]);
		showsmg(7,Seg_Table[distime[0] / 16]);
		showsmg(8,Seg_Table[distime[0] % 16]);
	}
}

void huixianmoshi(){//回显模式
	if(huixian == 0){
		wenduchaoxian();
	}else{
		julichaoxian();
	}
}
//*****************************************
//*****************************************DAC输出
void DACshuchu(){
	if((disjiao + distance) <= cejuxiaxian){
		daczhi = 51;
	}else if((disjiao + distance) >= cejushangxian){
		daczhi = 255;
	}else{
		daczhi = (204 / (cejushangxian - cejuxiaxian)) * (disjiao + distance - cejuxiaxian) + 51;
	}
	
	DAC(daczhi);
}
//*****************************************
//*****************************************
void showselect(){
	switch(show){
		case 0:shujujiemian();break;
		case 1:canshujiemian();break;
		case 2:shijianjiemian();break;
		case 3:jiaozhunshezhi();break;
		case 4:huixianmoshi();break;
	}
}
//*****************************************
//*****************************************单击双击检测
void Timer0_Isr(void) interrupt 1
{
	ledcount++;
	if(zhouqi){
		keycount++;
	}
	if(keycount == 100){
		zhouqi = 0;
	}
	if(zhouqi1){
		keycount1++;
	}
	if(keycount1 == 100){
		zhouqi1 = 0;
	}
	if(keystat){
		count++;
	}
	if(ledcount == 200){
		ledcount = 0;
	}
	if(ledcount % 20 == 0){
		ledflag = ~ledflag;
	}
}

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;
}

//*****************************************
//*****************************************按键扫描
void scankey(){
	P33 = 0;P32 = 1;P44 = 1;P35 = 1;
	if(P44 == 0){//S4
		Delay(de);while(P44 == 0){showselect();}
		show++;jiaozhun = 0;canshu = 0;huixian = 0;
		show %= 5;
	}
	if(P35 == 0){//S12
		Delay(de);if(P35 == 0){zhouqi = 1;}while(P35 == 0){showselect();}
		cishu++;
		if(show == 1){
			if(canshu == 2){
				tempcan++;
				if(tempcan > 40){tempcan = 40;}
			}else if((canshu == 3) && (mode == 1)){
				light += 10;
				if(light > 200){light = 200;}
			}
		}
		if(show == 3){
			if(jiaozhun == 0){
				disjiao++;
				if(disjiao > 10){disjiao = 10;}
			}else if(jiaozhun == 1){
				tempjiao++;
				if(tempjiao > 30){tempjiao = 30;}
			}
		}
	}
	if(show == 1){
		if(zhouqi == 0){
			if(cishu == 1){//单击
				if(show == 1){
					if(canshu == 0){
						cejushangxian++;
						if(cejushangxian > 90){cejushangxian = 90;}
					}else if(canshu == 1){
						cejuxiaxian++;
						if(cejuxiaxian > (cejushangxian - 20)){cejuxiaxian = cejushangxian - 20;}
					}
				}
			}
			if(cishu == 2){//双击
				if(show == 1){
					if(canshu == 0){
						cejushangxian += 10;
						if(cejushangxian > 90){cejushangxian = 90;}
					}else if(canshu == 1){
						cejuxiaxian += 10;
						if(cejuxiaxian > (cejushangxian - 20)){cejuxiaxian = cejushangxian - 20;}
					}
				}
			}
			keycount = 0;
			cishu = 0;
		}
	}
	P33 = 1;P32 = 0;P44 = 1;P35 = 1;
	if(P44 == 0){//S5
		Delay(de);while(P44 == 0){showselect();}
		if(show == 1){canshu++;canshu %= 4;}
		if(show == 3){jiaozhun++;jiaozhun %= 3;}
		if(show == 4){huixian = ~huixian;}
	}
	if(P35 == 0){//S13
		Delay(de);if(P35 == 0){zhouqi1 = 1;}while(P35 == 0){keystat = 1;showselect();}
		keystat = 0;
		if(count < 400){//短按
			cishu1++;
			if(show == 1){
				if(canshu == 2){
					tempcan--;
					if(tempcan < 20){tempcan = 20;}
				}else if((canshu == 3) && (mode == 1)){
					light -= 10;
					if(light > 200){light = 0;}
				}
			}
			if(show == 3){
				if(jiaozhun == 0){
					disjiao--;
					if(disjiao < -10){disjiao = -10;}
				}else if(jiaozhun == 1){
					tempjiao--;
					if(tempjiao < -30){tempjiao = -30;}
				}
			}
		}else{
			if(show == 3){
				if(jiaozhun == 0){disjiao = 0;}
				if(jiaozhun == 1){tempjiao = 0;}
			}
		}
		count = 0;
	}
	if(show == 1){
		if(zhouqi1 == 0){
			if(cishu1 == 1){//单击
				if(show == 1){
					if(canshu == 0){
						cejushangxian--;
						if(cejushangxian < (cejuxiaxian + 20)){cejushangxian = cejuxiaxian + 20;}
					}else if(canshu == 1){
						cejuxiaxian--;
						if(cejuxiaxian < 10){cejuxiaxian = 10;}
					}
				}
			}
			if(cishu1 == 2){//双击
				if(show == 1){
					if(canshu == 0){
						cejushangxian -= 10;
						if(cejushangxian < (cejuxiaxian + 20)){cejushangxian = (cejuxiaxian + 20);}
					}else if(canshu == 1){
						cejuxiaxian -= 10;
						if(cejuxiaxian < 10){cejuxiaxian = 10;}
					}
				}
			}
			keycount1 = 0;
			cishu1 = 0;
		}
	}
}
//*****************************************
//*****************************************LED模块与超限判断
void chaoxianpanduan(){
	if(((temp + tempjiao) / 10) > tempcan){
		chaoxian = 1;
		temptime[0] = rtctime[0];
		temptime[1] = rtctime[1];
		temptime[2] = rtctime[2];
		//eepromwirte()
	}
}

void led(){
	unsigned char tmp = 0;
	
	if(tempshow > tempcan * 10){
		ledstat = ledstat & ~0x10;
	}else{
		ledstat = ledstat | 0x10;
	}
	
	if((show == 0) && (ledflag == 1)){
		ledstat = ledstat & ~0x01;
	}else{
		ledstat = ledstat | 0x01;
	}
	
	if((show == 3) && (ledflag == 1)){
		ledstat = ledstat & ~0x02;
	}else{
		ledstat = ledstat | 0x02;
	}
	
	if(((distance + disjiao) <=cejushangxian) && ((distance + disjiao) >= cejuxiaxian)){
		ledstat = ledstat | 0x08;
	}else{
		ledstat = ledstat & ~0x08;
	}
	tmp = guangmin();
	if((mode == 1) && (tmp > light)){
		ledstat = ledstat & ~0x80;
	}else{
		ledstat = ledstat | 0x80;
	}
	
	outputp0(4,ledstat);
}
//*****************************************
void main(){
	ds1302config();
	cewen();
	initpca();
	initsys();
	ceju();
	Timer0_Init();
	while(1){
		if(mode == 0){
			light = guangmin();
		}
		cewen();
		led();
		ceju();
		showselect();
		ds1302read();
		DACshuchu();
		scankey();
		chaoxianpanduan();
	}
}

关键:双击单击长按复合代码

以S12为例

//*****************************************单击双击检测
void Timer0_Isr(void) interrupt 1
{
	ledcount++;
	if(zhouqi){
		keycount++;
	}
	if(keycount == 100){
		zhouqi = 0;
	}
	if(zhouqi1){
		keycount1++;
	}
	if(keycount1 == 100){
		zhouqi1 = 0;
	}
	if(keystat){
		count++;
	}
	if(ledcount == 200){
		ledcount = 0;
	}
	if(ledcount % 20 == 0){
		ledflag = ~ledflag;
	}
}

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;
}

//*****************************************
	P33 = 0;P32 = 1;P44 = 1;P35 = 1;
	if(P44 == 0){//S4
		Delay(de);while(P44 == 0){showselect();}
		show++;jiaozhun = 0;canshu = 0;huixian = 0;
		show %= 5;
	}
	if(P35 == 0){//S12
		Delay(de);if(P35 == 0){zhouqi = 1;}while(P35 == 0){showselect();}
		cishu++;
		if(show == 1){
			if(canshu == 2){
				tempcan++;
				if(tempcan > 40){tempcan = 40;}
			}else if((canshu == 3) && (mode == 1)){
				light += 10;
				if(light > 200){light = 200;}
			}
		}
		if(show == 3){
			if(jiaozhun == 0){
				disjiao++;
				if(disjiao > 10){disjiao = 10;}
			}else if(jiaozhun == 1){
				tempjiao++;
				if(tempjiao > 30){tempjiao = 30;}
			}
		}
	}
	if(show == 1){
		if(zhouqi == 0){
			if(cishu == 1){//单击
				if(show == 1){
					if(canshu == 0){
						cejushangxian++;
						if(cejushangxian > 90){cejushangxian = 90;}
					}else if(canshu == 1){
						cejuxiaxian++;
						if(cejuxiaxian > (cejushangxian - 20)){cejuxiaxian = cejushangxian - 20;}
					}
				}
			}
			if(cishu == 2){//双击
				if(show == 1){
					if(canshu == 0){
						cejushangxian += 10;
						if(cejushangxian > 90){cejushangxian = 90;}
					}else if(canshu == 1){
						cejuxiaxian += 10;
						if(cejuxiaxian > (cejushangxian - 20)){cejuxiaxian = cejushangxian - 20;}
					}
				}
			}
			keycount = 0;
			cishu = 0;
		}
	}

注意几个要点:
1、涉及到双击,要把判断部分抽离按键按下阶段,否则不会进行判断
2、注意按键周期,在编程过程中可以用数码管显示按键周期和按键按下进行调试。
3、定时器尽量使用1T,优先级尽量高。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值