蓝桥杯国赛真题试做

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

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);
			mangquset += 10;
			mangquset %= 100;
			while(P30 == 0){
				showselect();
			}
		}
	}
}
//*********************************
void main(){
	Timer0_Init();
	Initsys();
	while(1){
		scankey();
		showselect();
		DACshuchu();
	}
}

g0801

第9届

底层驱动代码的改动

I2C通讯

开头加上:

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

RB2读取

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

EEPROM读取与写入

void eepromWrite(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 dat;
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	dat = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	
	return dat;
}

DS18B20

开头加上:

#include <STC15F2K60S2.H>
sbit DQ = P1^4;

结尾延时数据全部乘以12

核心代码

#include <STC15F2K60S2.H>
#include "Delay.h"
#include "InitHC138.h"
#include "iic.h"
#include "onewire.h"

void wendu();
void showselect();
void scankey();
void showselectonly();

code unsigned char Seg_Table[] = 
{
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 dianya = 0;//读取RB2的电压值
unsigned int count_hz = 0;//数频率
unsigned int tmp = 0;//读取频率
unsigned char count = 0;//计时秒数
unsigned int temp = 0;//温度
unsigned char celiangmode = 0;//测量模式代号
unsigned char huixianmode = 0;//回显模式代号
unsigned char mode = 0;//测量、回显、参数代号
unsigned int tempecho = 0;//回显温度
unsigned int hzecho = 0;//回显频率
unsigned int hzo = 0;//还原后的频率
unsigned int dianyaecho = 0;//回显电压数字
unsigned char yuzhi = 1;//电压阈值
bit freeze = 0;//按下按键禁止读取温度
bit key_stat = 0;//按键状态
unsigned int count_key = 0;//计算按键按下的时间长度
unsigned char led_set = 0xfe;
unsigned char count_s;
//************************************定时器测量频率
void Timer0_Isr(void) interrupt 1
{
	count_hz++;
}

void Timer1_Isr(void) interrupt 3
{
	count++;
	count_s++;
	if(key_stat){
		count_key++;
	}
	
	if(dianya > yuzhi){
		if(((count_s % 20) == 0) && ((count_s % 40) != 0)){
			led_set = led_set & 0x7f;OutPutP0(4,led_set);
		}else if((count_s % 40) == 0){
			led_set = led_set | 0x80;OutPutP0(4,led_set);
		}
		if(count_s == 255){
			count_s = 0;
		}
	}else{
			led_set = led_set | 0x80;OutPutP0(4,led_set);
		}

	if(count == 100){
		tmp = count_hz;
		count_hz = 0;
		count = 0;
	}
}

void Timer_Init(void)		//10毫秒@12.000MHz
{
	TMOD = 0x07;			//设置定时器模式
	TL0 = 0xff;
	TH0 = 0xff;
	TL1 = 0xF0;				//设置定时初始值
	TH1 = 0xD8;				//设置定时初始值
	TF1 = 0;				//清除TF1标志
	TF0 = 0;
	TR1 = 1;				//定时器1开始计时
	TR0 = 1;
	ET1 = 1;				//使能定时器1中断
	ET0 = 1;
	EA = 1;
}

//************************************
//************************************温度测量
void DelaySMG(unsigned char xms){
	while(xms--){
		showselectonly();
		Delay(1);
	}
}


void wenduceliang(){
	unsigned char LSB,MSB;
	unsigned char i;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	
	for(i = 0;i < 10;i++){
		switch(celiangmode){
				case 0:led_set = (led_set | 0x07) & 0xfe;OutPutP0(4,led_set);break;
				case 1:led_set = (led_set | 0x07) & 0xfd;OutPutP0(4,led_set);break;
				case 2:led_set = (led_set | 0x07) & 0xfb;OutPutP0(4,led_set);break;
			}
		scankey();DelaySMG(15);
	}
	switch(celiangmode){
				case 0:led_set = (led_set | 0x07) & 0xfe;OutPutP0(4,led_set);break;
				case 1:led_set = (led_set | 0x07) & 0xfd;OutPutP0(4,led_set);break;
				case 2:led_set = (led_set | 0x07) & 0xfb;OutPutP0(4,led_set);break;
			}
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	LSB = Read_DS18B20();
	MSB = Read_DS18B20();
	
	init_ds18b20();
	
	temp = (MSB << 8) | LSB;
	temp = temp * 6.25;
}
//************************************
//************************************数据显示界面
void showdat(){
	dianya = dianyaRead();
	dianya = (dianya *10) / 51;
	ShowSMG(1,0xc1);
	ShowSMG(7,Seg_Table[dianya / 10 % 10] & 0x7f);
	ShowSMG(8,Seg_Table[dianya % 10]);
}
//************************************
//************************************频率测量显示
void showhz(){
	ShowSMG(1,Seg_Table[15]);
	ShowSMG(8,Seg_Table[tmp % 10]);
	if(tmp > 9){
		ShowSMG(7,Seg_Table[tmp / 10 % 10]);
	}
	if(tmp > 99){
		ShowSMG(6,Seg_Table[tmp / 100 % 10]);
	}
	if(tmp > 999){
		ShowSMG(5,Seg_Table[tmp / 1000 % 10]);
	}
	if(tmp > 9999){
		ShowSMG(4,Seg_Table[tmp / 10000 % 10]);
	}
}
//************************************
//************************************温度显示界面
void wendu(){
	ShowSMG(1,Seg_Table[12]);
	ShowSMG(5,Seg_Table[temp / 1000]);
	ShowSMG(6,Seg_Table[temp / 100 % 10] & 0x7f);
	ShowSMG(7,Seg_Table[temp / 10 % 10]);
	ShowSMG(8,Seg_Table[temp % 10]);
}
//************************************
//************************************数据回显界面
void showecho(){
	ShowSMG(1,0x89);
	if(huixianmode == 0){
		tempecho = (eepromRead(0x00) * 100);
		Delay(1);
		tempecho = tempecho + (eepromRead(0x01));
		Delay(1);
		ShowSMG(2,Seg_Table[12]);
		ShowSMG(5,Seg_Table[tempecho / 1000]);
		ShowSMG(6,Seg_Table[tempecho / 100 % 10] & 0x7f);
		ShowSMG(7,Seg_Table[tempecho / 10 % 10]);
		ShowSMG(8,Seg_Table[tempecho % 10]);
	}
	if(huixianmode == 1){
		OutPutP0(4,0xff);
		hzecho = (eepromRead(0x02) * 10000);
		Delay(1);
		hzecho = hzecho + (eepromRead(0x03) * 100);
		Delay(1);
		hzecho = hzecho + eepromRead(0x04);
		Delay(1);
		ShowSMG(2,Seg_Table[15]);
		ShowSMG(8,Seg_Table[hzo % 10]);
		if(hzecho > 9){
			ShowSMG(7,Seg_Table[hzecho / 10 % 10]);
		}
		if(hzecho > 99){
			ShowSMG(6,Seg_Table[hzecho / 100 % 10]);
		}
		if(hzecho > 999){
			ShowSMG(5,Seg_Table[hzecho / 1000 % 10]);
		}
		if(hzecho > 9999){
			ShowSMG(4,Seg_Table[hzecho / 10000 % 10]);
		}
	}
	if(huixianmode == 2){
		OutPutP0(4,0xff);
		dianyaecho = eepromRead(0x05);
		Delay(2);
		ShowSMG(2,0xc1);
		ShowSMG(7,Seg_Table[dianyaecho / 10] & 0x7f);
		ShowSMG(8,Seg_Table[dianyaecho % 10]);
	}
}
//************************************
//************************************电压阈值设置界面
void dianyayuzhi(){
	ShowSMG(1,0x8c);
	ShowSMG(7,Seg_Table[yuzhi / 10] & 0x7f);
	ShowSMG(8,Seg_Table[yuzhi % 10]);
}
//************************************
//************************************按键扫描
void scankey(){
	unsigned char tmp1 = 0;
	if(mode == 0){//在数据显示界面
		if(P33 == 0){//S4
			Delay(5);
			freeze = 1;
			celiangmode++;
			celiangmode %= 3;
			switch(celiangmode){
				case 0:led_set = (led_set | 0x07) & 0xfe;OutPutP0(4,led_set);break;
				case 1:led_set = (led_set | 0x07) & 0xfd;OutPutP0(4,led_set);break;
				case 2:led_set = (led_set | 0x07) & 0xfb;OutPutP0(4,led_set);break;
			}
			while(P33 == 0){
				showselectonly();
			}
			freeze = 0;
		}
		if(P32 == 0){//S5
			tmp1 = temp / 100;
			eepromWrite(0x00,tmp1);Delay(2);
			tmp1 = temp % 100;
			eepromWrite(0x01,tmp1);Delay(2);
			tmp1 = tmp / 10000;
			eepromWrite(0x02,tmp1);Delay(2);
			tmp1 = tmp / 100 % 100;
			eepromWrite(0x03,tmp1);Delay(2);
			tmp1 = tmp % 100;
			eepromWrite(0x04,tmp1);Delay(2);
			tmp1 = dianya;
			eepromWrite(0x05,tmp1);Delay(2);
		}
		if(P31 == 0){//S6
			Delay(5);
			freeze = 1;
			mode = 1;
			while(P31 == 0){
				showselectonly();
			}
			freeze = 0;
		}
		if(P30 == 0){//S7
			Delay(5);
			freeze = 1;
			mode = 2;
			while(P30 == 0){
				showselectonly();
			}
			freeze = 0;
		}
	}
	if(mode == 1){//回显模式下
		if(P31 == 0){//S6
			Delay(5);
			freeze = 1;
			mode = 0;
			while(P31 == 0){
				showselectonly();
			}
			freeze = 0;
		}
		if(P33 == 0){//S4
			Delay(5);
			freeze = 1;
			huixianmode++;
			huixianmode %= 3;
			while(P33 == 0){
				showselectonly();
			}
			freeze = 0;
		}
		if(P30 == 0){//S7
			Delay(5);
			freeze = 1;
			huixianmode++;
			huixianmode %= 3;
			while(P30 == 0){
				showselectonly();
			}
			freeze = 0;
		}
	}
	if(mode == 2){//电压阈值设置模式下
		if(P31 == 0){//S6
			Delay(5);
			key_stat = 1;
			yuzhi++;
			yuzhi %= 51;
			while(P31 == 0){
				showselectonly();
				if(count_key >= 80){
					yuzhi++;
					yuzhi %= 51;
					DelaySMG(20);
				}
			}
			key_stat = 0;
			count_key = 0;
		}
		if(P30 == 0){//S7
			Delay(5);
			freeze = 1;
			mode = 0;
			while(P30 == 0){
				showselectonly();
			}
			freeze = 0;
		}
	}
}
//************************************
//************************************选择显示
void showselect(){
	if(mode == 0){
		switch(celiangmode){
			case 0:wenduceliang();wendu();led_set = (led_set | 0x07) & 0xfe;OutPutP0(4,led_set);break;
			case 1:showhz();led_set = (led_set | 0x07) & 0xfd;OutPutP0(4,led_set);break;
			case 2:showdat();led_set = (led_set | 0x07) & 0xfb;OutPutP0(4,led_set);break;
		}
	}
	if(mode == 1){
		OutPutP0(4,0xff);
		showecho();
	}
	if(mode == 2){
		OutPutP0(4,0xff);
		dianyayuzhi();
	}
}

void showselectonly(){
	if(mode == 0){
		switch(celiangmode){
			case 0:wendu();break;
			case 1:showhz();break;
			case 2:showdat();break;
		}
	}
	if(mode == 1){
		OutPutP0(4,0xff);
		showecho();
	}
	if(mode == 2){
		OutPutP0(4,0xff);
		dianyayuzhi();
	}
}
//************************************
void main(){
	Initsys();
	Timer_Init();
	while(1){
		showselect();
		scankey();
	}
}

g0901

第十届

底层驱动代码的改动

I2C通讯

开头略

void eepromwrite(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 tmp;
	
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	tmp = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	
	return tmp;
}

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

DS18B20

核心代码

#include <STC15F2K60S2.H>
#include "Delay.h"
#include "InitHC138.h"
#include "onewire.h"
#include "iic.h"
#include "stdio.h"

void showselect();
void scankey();
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 mode = 0;//模式代号
unsigned char shuju = 0;//数据界面代号
unsigned char canshu = 0;//参数界面代号
bit wendu = 0;//是否进行测量
unsigned int time = 0;//超声波时间
unsigned int distance = 0;//测距距离
unsigned int temp = 0;//温度
unsigned int biangeng = 0;//参数变化情况
unsigned char tempcert = 30;//温度参数确定
unsigned char distancecert = 35;//距离参数确定
char tempset = 30;//温度参数设定
char distanceset = 35;//距离参数设定
bit keystat = 0;//按键状态
bit DACstat = 0;//DAC启用状态
unsigned char count = 0;//计时器
unsigned char ledstat = 0xff;//按键状态
unsigned char command[10] = {0};//命令字符存储
unsigned char num = 0;//命令字符数组下标
//**********************************串口
void Uart1_Isr(void) interrupt 4
{
	if (RI)				//检测串口1接收中断
	{
		command[num] = SBUF;
		RI = 0;			//清除串口1接收中断请求位
		num++;
	}
}

void Uart1_Init(void)	//4800bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x01;		//串口1选择定时器2为波特率发生器
	AUXR &= 0xFB;		//定时器时钟12T模式
	T2L = 0xCC;			//设置定时初始值
	T2H = 0xFF;			//设置定时初始值
	AUXR |= 0x10;		//定时器2开始计时
	ES = 1;				//使能串口1中断
}


void sendbtye(unsigned char dat){
	SBUF = dat;
	while(TI == 0);
	TI = 0;
}

void sendstring(unsigned char *str){
	while(*str != '\0'){
		sendbtye(*str++);
	}
}

//**********************************
//**********************************定时器
void Timer0_Isr(void) interrupt 1
{
	if(keystat){
		count++;
	}
}

void Timer0_Init(void)		//50毫秒@12.000MHz
{
	AUXR &= 0x7F;			//定时器时钟12T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0xB0;				//设置定时初始值
	TH0 = 0x3C;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
	EA = 1;
}
//**********************************
//**********************************超声波与显示
sbit TX = P1^0;
sbit RX = P1^1;
void fangbo(){
	unsigned char i = 0;
	for(i = 0;i < 8;i++){
		TX = 1;
		Delay12us();
		TX = 0;
		Delay12us();
	}
}

void ceju(){
	TMOD &= 0x0F;
	TL1 = 0x00;				//设置定时初始值
	TH1 = 0x00;
	
	fangbo();
	TR1 = 1;
	while((RX == 1) && (TF1 == 0));
	TR1 = 0;
	
	if(TF1 == 0){
		time = (TH1 << 8) | TL1;
		distance = time * 0.017;
	}else{
		TF1 = 0;
		distance = 99;
	}
}

void showdistance(){
	ceju();
	ShowSMG(1,0xc7);
	ShowSMG(7,Seg_Table[distance / 10]);
	ShowSMG(8,Seg_Table[distance % 10]);
}
//**********************************
//**********************************温度与温度显示
void delaysmg(unsigned char xms){
	while(xms--){
		showselect();
		Delay(1);
	}
}

void DS18B20read(){
	unsigned char LSB,MSB;
	unsigned char i;
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	wendu = 1;
	for(i = 0;i<20;i++){
		delaysmg(10);scankey();
	}
	wendu = 0;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	LSB = Read_DS18B20();
	MSB = Read_DS18B20();
	
	init_ds18b20();
	temp = (MSB << 8) | LSB;
	temp = temp * 6.25;
}

void cewen(){
	ShowSMG(1,Seg_Table[15]);
	ShowSMG(5,Seg_Table[temp / 1000]);
	ShowSMG(6,Seg_Table[temp / 100 % 10] & 0x7f);
	ShowSMG(7,Seg_Table[temp / 10 % 10]);
	ShowSMG(8,Seg_Table[temp % 10]);
}
//**********************************
//**********************************变更次数显示
void biangengcishu(){
	ShowSMG(1,0xc8);
	ShowSMG(8,Seg_Table[biangeng % 10]);
	if(biangeng > 9){
		ShowSMG(7,Seg_Table[biangeng / 10 % 10]);
	}
	if(biangeng > 99){
		ShowSMG(6,Seg_Table[biangeng / 100 % 10]);
	}
	if(biangeng > 999){
		ShowSMG(5,Seg_Table[biangeng / 1000 % 10]);
	}
	if(biangeng > 9999){
		ShowSMG(4,Seg_Table[biangeng / 10000 % 10]);
	}
}
//**********************************
//**********************************//参数界面
void wenduset(){//温度参数
	ShowSMG(1,0x8C);
	ShowSMG(4,Seg_Table[1]);
	ShowSMG(7,Seg_Table[tempset / 10]);
	ShowSMG(8,Seg_Table[tempset % 10]);
}

void disset(){//距离参数
	ShowSMG(1,0x8C);
	ShowSMG(4,Seg_Table[2]);
	ShowSMG(7,Seg_Table[distanceset / 10]);
	ShowSMG(8,Seg_Table[distanceset % 10]);
}
//**********************************
//**********************************DAC
void DACshow(){
	if(DACstat == 0){
		DAC(22);
	}else{
		if(distance <= distancecert){
			DAC(102);
		}else{
			DAC(204);
		}
	}
}
//**********************************
//**********************************显示选择
void showshuju(){
	switch(shuju){
		case 0:if(wendu == 0){DS18B20read();}cewen();break;
		case 1:showdistance();break;
		case 2:biangengcishu();break;
	}
}

void showcanshu(){
	switch(canshu){
		case 0:wenduset();break;
		case 1:disset();break;
	}
}

void showselect(){
	switch(mode){
		case 0:showshuju();break;
		case 1:showcanshu();break;
	}
}
//**********************************
//**********************************按键扫描
void scankey(){
	P32 = 0;P33 = 1;
	P35 = 1;P34 = 1;
	if(P35 == 0){//S13
		Delay(5);
		keystat = 1;
		while(P35 == 0){
			showselect();
		}
		keystat = 0;
		if(mode == 1){
			if((tempcert != tempset) || (distancecert != distanceset)){
				tempcert = tempset;
				distancecert = distanceset;
				biangeng++;
				eepromwrite(0x00,(biangeng));
				Delay(2);
				eepromwrite(0x01,(biangeng >> 8));
				Delay(2);
			}
		}
		if(count <= 20){
			mode++;
			mode %= 2;
			count = 0;
		}
		if(count > 20){
			DACstat = ~DACstat;
			count = 0;
		}
	}
	if(P34 == 0){//S17
		Delay(5);
		if(mode == 1){
			if(canshu == 0){
				tempset = tempset + 2;
				if(tempset > 99){
					tempset = 0;
				}
			}
			if(canshu == 1){
				distanceset = distanceset + 5;
				if(distanceset > 99){
					distanceset = 0;
				}
			}
		}
		while(P34 == 0){
			showselect();
		}
	}
	P32 = 1;P33 = 0;
	P35 = 1;P34 = 1;
	if(P35 == 0){//S12
		Delay(5);
		keystat = 1;
		while(P35 == 0){
			showselect();
		}
		keystat = 0;
		if(count <= 20){
			if(mode == 0){
				shuju++;
				shuju %= 3;
			}
			if(mode == 1){
				canshu++;
				canshu %= 2;
			}
			count = 0;
		}
		if(count > 20){
			biangeng = 0;
			count = 0;
			eepromwrite(0x00,(biangeng));Delay(2);
			eepromwrite(0x01,(biangeng >> 8));Delay(2);
		}
	}
	if(P34 == 0){//S16
		Delay(5);
		if(mode == 1){
			if(canshu == 0){
				tempset = tempset - 2;
				if(tempset < 0){
					tempset = 99;
				}
			}
			if(canshu == 1){
				distanceset = distanceset - 5;
				if(distanceset < 0){
					distanceset = 99;
				}
			}
		}
		while(P34 == 0){
			showselect();
		}
	}
}
//**********************************
//**********************************LED
void led(){
	if(temp > tempcert * 100){
		ledstat = ledstat & 0xfe;OutPutP0(4,ledstat);
	}else{
		ledstat = ledstat | 0x01;OutPutP0(4,ledstat);
	}
	if(distance > distancecert){
		ledstat = ledstat & 0xfd;OutPutP0(4,ledstat);
	}else{
		ledstat = ledstat | 0x02;OutPutP0(4,ledstat);
	}
	if(DACstat){
		ledstat = ledstat & 0xfb;OutPutP0(4,ledstat);
	}else{
		ledstat = ledstat | 0x04;OutPutP0(4,ledstat);
	}
}
//**********************************
//**********************************串口收发数据
void working(){
	unsigned char tmp = 0;
	if((command[0] == 'S') && (command[1] == 'T')){
		printf("$%d,%d.%d\r\n",(int)distance,(temp / 100),(temp % 100));
		num = 0;
		for(tmp = 0;tmp < 10;tmp++){
			command[tmp] = 0; 
		}
	}
	if((command[0] == 'P') && (command[1] == 'A')){
		printf("$%d,%d\r\n",(int)tempcert,(int)distancecert);
		num = 0;
		for(tmp = 0;tmp < 10;tmp++){
			command[tmp] = 0; 
		}
	}else if(command[0] != 0){
		printf("ERROR\r\n");
		num = 0;
		for(tmp = 0;tmp < 10;tmp++){
			command[tmp] = 0; 
		}
	}
}
//**********************************
void main(){
	Initsys();
	Timer0_Init();
	//eepromwrite(0x00,0);Delay(2);
	//eepromwrite(0x01,0);Delay(2);
	Uart1_Init();
	biangeng = (eepromread(0x00) | (eepromread(0x01) << 8));
	while(1){
		scankey();
		showselect();
		DACshow();
		led();
		working();
	}
}

char putchar(char ch)//重定向printf
{
	sendbtye(ch);
	return ch;
}

G1002按键操作部分

g1003DAC部分

G1001串口通讯部分

第十四届

底层驱动代码的改动

核心代码

#include <STC15F2K60S2.H>
#include "delay.h"
#include "inithc138.h"
#include "onwire.h"
#include "iic.h"

#define dt 10
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 mode = 0;//模式代号
bit unit = 0;//单位选择
bit canshu = 0;//参数选择
bit ce = 0;
unsigned char set = 0;//设置选择
unsigned int distance = 0;//距离
unsigned int time = 0;//超神波时间
unsigned int v = 340;//介质声速
unsigned int temp = 0;//温度
unsigned char n = 0;
unsigned int temprec[10] = {0};
unsigned int disrec[10] = {0};
unsigned char disset = 40;//距离参数
char tempset = 30;//温度参数
bit shuangan = 0;//按键是否都按下
unsigned int count = 0;//计时
bit shuchu = 0;
bit jilu = 0;
unsigned int count2 = 0;
unsigned char factory = 0;
char disjiao = 0;//距离校准值
unsigned char dac = 10;
unsigned char ledstat = 0xff;
unsigned char count_s = 0;
bit flag = 0;
//***********************************超声波测距和测温
void showselect();
void scankey();
sbit TX = P1^0;
sbit RX = P1^1;
void fangbo(){
	unsigned char i;
	for(i = 0;i < 8;i++){
		TX = 1;
		Delay13us();
		TX = 0;
		Delay13us();
	}
}

void ceju(){ 
	CMOD = 0x00;			//设置定时器模式
	CL = 0x00;				//设置定时初始值
	CH = 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) * v / 340) + disjiao;
		if(jilu == 1)disrec[n] = distance;
	}else{
		CF = 0;
		distance = 9999;
	}
}

void Delaysmg(unsigned char xms){
	while(xms--){
		showselect();
		Delay(1);
	}
}

void cewen(){
	unsigned char LSB,MSB;
	unsigned char i;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	ce = 1;
	for(i = 0;i < 40;i++){
		Delaysmg(2);scankey();ceju();
	}
	ce = 0;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	LSB = Read_DS18B20();
	MSB = Read_DS18B20();
	init_ds18b20();
	
	temp = (MSB << 8) | LSB;
	temp = temp * 0.625;
	if(jilu == 1){temprec[n] = temp;n++;}
}

void showdistemp(){
	showsmg(1,Seg_Table[temp / 100]);
	showsmg(2,Seg_Table[temp / 10 % 10] & 0x7f);
	showsmg(3,Seg_Table[temp  % 10]);
	showsmg(4,Seg_Table[16]);
	showsmg(8,Seg_Table[distance % 10]);
	if(unit == 0){
		if(distance > 9){
			showsmg(7,Seg_Table[distance / 10 % 10]);
		}
		if(distance > 99){
			showsmg(6,Seg_Table[distance / 100 % 10]);
		}
		if(distance > 999){
			showsmg(5,Seg_Table[distance / 1000 % 10]);
		}
	}else if(unit == 1){
		showsmg(7,Seg_Table[distance / 10 % 10]);
		showsmg(6,Seg_Table[distance / 100 % 10] & 0x7f);
		if(distance > 999){
			showsmg(5,Seg_Table[distance / 1000 % 10]);
		}
		if(distance > 9999){
			showsmg(5,Seg_Table[distance / 10000 % 10]);
		}
	}
}
//***********************************参数界面
void showset(){
	showsmg(1,0x8c);
	if(canshu == 0){
		showsmg(2,Seg_Table[1]);
		showsmg(7,Seg_Table[disset / 10]);
		showsmg(8,Seg_Table[disset % 10]);
	}else if(canshu == 1){
		showsmg(2,Seg_Table[2]);
		showsmg(7,Seg_Table[tempset / 10]);
		showsmg(8,Seg_Table[tempset % 10]);
	}
	
}
//***********************************工厂模式
void factory01(){//校准值设置
	showsmg(1,Seg_Table[15]);
	showsmg(2,Seg_Table[1]);
	if((disjiao & 0x80) == 0){
		showsmg(8,Seg_Table[disjiao % 10]);
		if(disjiao > 9){
			showsmg(7,Seg_Table[disjiao / 10 % 10]);
		}
	}else{
		showsmg(8,Seg_Table[~(disjiao - 1) % 10]);
		if((disjiao < 0) && (disjiao > -9))
			showsmg(7,Seg_Table[16]);
		if(disjiao < -9){
			showsmg(7,Seg_Table[~(disjiao - 1) / 10 % 10]);
			showsmg(6,Seg_Table[16]);
		}
	}
}

void jiezhi(){//介质设置
	showsmg(1,Seg_Table[15]);
	showsmg(2,Seg_Table[2]);
	
	showsmg(6,Seg_Table[v / 100]);
	showsmg(7,Seg_Table[v / 10 % 10]);
	showsmg(8,Seg_Table[v % 10]);
}

void factory03(){//DAC输出设置
	showsmg(1,Seg_Table[15]);
	showsmg(2,Seg_Table[3]);
	
	showsmg(7,Seg_Table[dac / 10] & 0x7f);
	showsmg(8,Seg_Table[dac % 10]);
}
//***********************************
//***********************************显示选择
void factoryselect(){
	switch(factory){
		case 0:factory01();break;
		case 1:jiezhi();break;
		case 2 :factory03();break;
	}
}

void showselect(){
	switch(mode){
		case 0:
			if(ce == 0){cewen();ceju();}
			showdistemp();
			break;
		case 1:showset();break;
		case 2:factoryselect();break;
	}
}
//***********************************
//***********************************长短按检测定时器
void led();
void Timer0_Isr(void) interrupt 1
{
	count_s++;
	if(count_s >= 10){
		flag = ~flag;
		count_s = 0;
	}
	if(shuangan){
		count++;
	}
	if(jilu == 1){
		count2++;
	}
	if(count2 >= 600){
		jilu = 0;
		count2 = 0;
	}
	led();
}

void Timer0_Init(void)		//10毫秒@11.0592MHz
{
	AUXR &= 0x7F;			//定时器时钟12T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0x00;				//设置定时初始值
	TH0 = 0xDC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
	EA = 1;
}
//***********************************
//***********************************按键扫描
void scankey(){
//	unsigned char i;
	if(jilu == 0){
	P44 = 0;P42 = 1;
	P33 = 1;P32 = 1;
	if(P33 == 0){//S4
		Delay(dt);
		canshu = 0;
		factory = 0;
		if(mode == 2){Delay(dt);Delay(2*dt);}
		mode++;
		if(mode > 2){mode = 0;}
		Delay(dt);Delay(2*dt);
		while(P33 == 0){
			showselect();
		}
	}
	if(P32 == 0){//S5
		Delay(dt);
		if(mode == 0){unit = ~unit;}
		if(mode == 1){canshu = ~canshu;}
		if(mode == 2){factory++;factory %= 3;}
		while(P32 == 0){
			showselect();
		}
	}
	P44 = 1;P42 = 0;
	P33 = 1;P32 = 1;
	if(P33 == 0){//S8
		Delay(dt);
		while(P33 == 0){
			if(P32 == 0){//S8按下同时是否有S9按下
				Delay(dt);
				shuangan = 1;
				while((P33 == 0) && (P32 == 0)){
					showselect();
				}
				shuangan = 0;
			}
			showselect();
		}
		if((count <= 200)){//短按为
			if((mode == 1) && (canshu == 0)){//距离参数加按键
				disset = disset + 10;
				if(disset == 100){
					disset = 10;
				}
			}
			if((mode == 1) && (canshu == 1)){//距离参数加按键
				tempset = tempset + 1;
				if(tempset == 80){
					tempset = 0;
				}
			}
			if(mode == 0){//记录模式
				jilu = 1;
				n = 0;
			}
			if((mode == 2) && (factory == 0)){//校准值模式加键
				disjiao = disjiao + 5;
				if(disjiao == 95){disjiao = 0;}
			}
			if((mode == 2) && (factory == 1)){//介质设置模式加键
				v = v + 10;
				if(v == 10000){v = 10;}
			}
			if((mode == 2) && (factory == 2)){//DAC下限加
				dac = dac + 1;
				if(dac == 21){dac = 1;}
			}
			count = 0;
		}
		if(count > 200){
			mode = 0;//模式代号
		unit = 0;//单位选择
		canshu = 0;//参数选择
		ce = 0;
		set = 0;//设置选择
		distance = 0;//距离
		time = 0;//超神波时间
		v = 340;//介质声速
		temp = 0;//温度
		n = 0;
		temprec[n] = 0;
		disrec[n] = 0;
		disset = 40;//距离参数
		tempset = 30;//温度参数
		shuangan = 0;//按键是否都按下
		count = 0;//计时
		shuchu = 0;
		jilu = 0;
		count2 = 0;
		factory = 0;
		disjiao = 0;//距离校准值
		dac = 10;
		count = 0;
		}
		
	}
	if(P32 == 0){//S9
		Delay(dt);
		while(P32 == 0){
			if(P33 == 0){//S9按下同时是否有S8按下
				Delay(dt);
				shuangan = 1;
				while((P33 == 0) && (P32 == 0)){
					showselect();
				}
				shuangan = 0;
			}
			showselect();
		}
		if((count <= 200)){//短按为
			if((mode == 1) && (canshu == 0)){//距离参数减按键
				disset = disset - 10;
				if(disset == 0){
					disset = 90;
				}
			}
			if((mode == 1) && (canshu == 1)){//距离参数减按键
				tempset = tempset - 1;
				if(tempset < 0){
					tempset = 80;
				}
			}
			if(mode == 0){//输出模式
				shuchu = 1;
			}
			if((mode == 2) && (factory == 0)){//校准值模式加键
				disjiao = disjiao - 5;
				if(disjiao == -95){disjiao = 0;}
			}
			if((mode == 2) && (factory == 1)){//介质设置模式加键
				v = v - 10;
				if(v == 0){v = 9990;}
			}
			if((mode == 2) && (factory == 2)){//DAC下限加
				dac = dac - 1;
				if(dac == 0){dac = 20;}
			}
			count = 0;
		}
		if(count > 200){
			count = 0;
			mode = 0;//模式代号
		unit = 0;//单位选择
		canshu = 0;//参数选择
		ce = 0;
		set = 0;//设置选择
		distance = 0;//距离
		time = 0;//超神波时间
		v = 340;//介质声速
		temp = 0;//温度
		n = 0;
		temprec[n] = 0;
		disrec[n] = 0;
		disset = 40;//距离参数
		tempset = 30;//温度参数
		shuangan = 0;//按键是否都按下
		count = 0;//计时
		shuchu = 0;
		jilu = 0;
		count2 = 0;
		factory = 0;
		disjiao = 0;//距离校准值
		dac = 10;
		}
		
	}
}
}
//***********************************
//***********************************LED
void led(){
	switch(mode){
		case 0:
			ledstat = distance;
			if(distance > 255){
				ledstat = 0x00;
			}
			outputp0(4,~ledstat);
			break;
		case 1:ledstat = 0x7f;outputp0(4,ledstat);;break;
		case 2:if(flag){ledstat = 0xfe;}else{ledstat = 0xff;}outputp0(4,ledstat);break;
	}
}
//***********************************
//***********************************继电器

//***********************************
void main(){
	unsigned char tmp = 0;
	Timer0_Init();
	initsys();
	while(1){
		scankey();
		showselect();
		tmp = (5-dac)*(disrec[n] - 10);
		tmp = ((tmp/ 80)+dac) * 51;
		if(shuchu == 1){
			DAC(tmp);
		}
		led();
		if((distance >= (disset-5)) && (distance <= (disset+5)) && temp <= tempset*10){
			outputp0(5,0x10);
		}else{
		outputp0(5,0x00);
		}
	}
}

BUG:DAC没做好,直线方程用点斜式没算准

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值