第十一届 蓝桥杯 单片机设计与开发项目 省赛 程序设计试题及源码

1、试题

一、 基本要求

1.1 使用大赛组委会提供的国信长天单片机竞赛实训平台,完成本试题的程序设计
与调试。
1.2 选手在程序设计与调试过程当中,可参考组委会提供的“资源数据包”。
1.3 请注意: 程序编写、调试完成后选手应经过考试系统提交完整、可编译的 Keil
工程文件。选手提交的工程文件应是最终版本, 要求 Keil 工程文件以准考证
号(8 位数字)命名, 工程文件夹内应包含以准考证号命名的 hex 文件,该 hex
文件是成绩评审的依据。 不符合以上文件提交要求的做品将被评为零分或者被
酌情扣分。
1.4 请勿上传与做品工程文件无关的其它文件。







函数

二、 竞赛板配置要求

2.1将 IAP15F2K61S2 单片机内部振荡器频率设定为 12MHz。
2.2键盘工做模式跳线 J5 配置为 BTN 按键模式。
2.3扩展方式跳线 J13 配置为 IO 模式。
2.4请注意: 选手需严格按照以上要求配置竞赛板,编写和调试程序, 不符合以上
配置要求的做品将被评为零分或者被酌情扣分。



ui

三、 硬件框图

在这里插入图片描述

图 1 系统硬件框图spa

四、 功能描述

4.1基本功能设计

  1. 经过 DS18B20 完成温度数据测量。
  2. 经过数码管实现数据和参数界面的显示。
  3. 经过按键实现界面切换、参数设置等功能。
  4. 经过 LED 指示灯实现状态指示与报警输出功能。
  5. 经过 PCF8591 完成 DAC 模拟电压输出功能。
    4.2设计要求
  6. 温度数据刷新时间:≤0.5 秒
  7. 显示界面切换时间:≤0.3 秒
  8. DAC 模拟电压输出响应时间:≤0.3 秒
  9. 温度参数可调整范围:
     温度上限参数 0 ≤ TMAX < 100
     温度下限参数 0 ≤ TMIN < 100
    4.3显示功能


  10. 数据界面
    数据界面如图 2 所示,显示内容包括提示符 C 和经过 DS18B20 温度传感器
    采集到的温度数据,温度数据取整数。
    在这里插入图片描述


图 2 数据显示界面
2) 参数界面如图 3 所示,显示内容包括提示符 P、温度上限参数 TMAX和温度下
限参数 TMIN。
在这里插入图片描述


调试

图 3 参数设置界面
4.4按键功能
code

  1. 按键功能说明
     S4: 定义为“界面切换”按键,按下 S4 按键,切换选择数据显示界
    面和参数设置界面。3 / 3
     S5:定义为“参数切换” 按键,按下 S5 按键,切换选择温度上限参
    数 TMAX和温度下限参数 TMIN。
     S6:定义为“加” 按键, 按下 S6 按键,当前选择的温度参数增长 1℃。
     S7:定义为“减”按键,按下 S7 按键,当前选择的温度参数减小 1℃。





  2. 按键功能设计要求
     按键 S6 和按键 S7 的加、 减功能仅在参数设置界面有效。
     合理设置参数边界范围, 防止出现参数越界和逻辑错误。
     每次从数据界面切换到参数界面,默认当前选择的参数是温度下限参
    数 TMIN。
     经过 S4 按键,从参数设置界面退出,进入数据显示界面时,须要进行
    必要的参数合理性检查( TMAX≥TMIN);若设置的参数合理,参数生效,
    进入数据界面;反之, 自动恢复进入参数设置界面前的有效参数, 进
    入数据界面。
    4.5DAC 输出功能








  3. 当前温度 T > TMAX时,控制 DAC 输出 4.0V。
  4. 当前温度 TMIN ≤ T ≤ TMAX时,控制 DAC 输出 3.0V。
  5. 当前温度 T < TMIN时,控制 DAC 输出 2.0V。
    4.6LED 指示灯功能
  6. 当前温度知足 T > TMAX,指示灯 L1 点亮,不然熄灭。
  7. 当前温度知足 TMIN ≤ T ≤ TMAX,指示灯 L2 点亮,不然熄灭。
  8. 当前温度知足 T < TMIN,指示灯 L3 点亮,不然熄灭。
  9. 如出现错误的参数设置操做,指示灯 L4 点亮,直至下一次正确的参数设
    置后,指示灯熄灭。
    4.7初始状态说明

  10. 初始状态上电默认处于数据显示界面。
  11. 默认参数
     温度上限参数 TMAX = 30℃
     温度下限参数 TMIN = 20℃

2、源码(有瑕疵)

一、main.c

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

#define uchar unsigned char
#define uint unsigned int
	
void delayms(uint ms);
void Select573(char channel);	
void allinit();
void display1();
void display2();
void display3();
void display4();
void keyscan();
void work_key();
void work_led();
void work_dac();

uchar code tab[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xFF,0xc6,0x8c};
uchar code dot[]={ 0x40,0x79,0x24,0x30,0x19,0x12,0x20,0x78,0x00,0x10};//&0x7f
uchar yi,er,san,si,wu,liu,qi,ba;

int temper;
bit mode=0;
bit choose=1;
char tmax;
char tmin;
char tomax;
char tomin;

void main()
{ 
	allinit();
	temper=temperature_rd_F();
	tmax=30;
	tmin=20;
	while(1)
	{ 
		work_key();
		work_led();
		work_dac();
		display1();
		display2();
		display3();
		display4();
		keyscan();
	}
}

void work_key()
{ 
	if(mode==0)
	{ 
		yi=12;
		er=11;san=11;si=11;wu=11;liu=11;
		qi=temper/10;ba=temper%10;
	}
	else
	{ 
		yi=13;
		er=11;san=11;
		si=tmax/10;wu=tmax%10;
		liu=11;
		qi=tmin/10;ba=tmin%10;
	}
}

void work_led()
{ 
	Select573(4);
	if(tmax<tmin)
	{ 
		P03=0;
		P00=1;P01=1;P02=1;
	}
	else P03=1;
	if(tmax>=tmin)
	{ 
		if(temper>tmax)P00=0;
		else P00=1;
		if(temper<tmin)P02=0;
		else P02=1;
		if(temper<tmax&&temper>tmin)P01=0;
		else P01=1;
	}
	Select573(0);
}

void work_dac()
{ 
	if(temper>tmax)
		AD_write(0x40,204);
	if(temper<tmin)
		AD_write(0x40,102);
	if(temper<tmax&&temper>tmin)
		AD_write(0x40,153);
	if(tmax<tmin)
		AD_write(0x40,0);
}

void delayms(uint ms)
{ 
	uint i,j;
	for(i=ms;i>0;i--)
		for(j=845;j>0;j--);
}

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

void allinit()
{ 
	Select573(4);
	P0=0xff;
	Select573(5);
	P0=0x00;
	Select573(6);
	P0=0xff;
	Select573(7);
	P0=0xff;
	Select573(0);
}

void display1()
{ 
	Select573(6);
	P0=0x01;
	Select573(7);
	P0=tab[yi];
	delayms(1);
	
	Select573(6);
	P0=0x02;
	Select573(7);
	P0=tab[er];
	delayms(1);
}

void display2()
{ 
	Select573(6);
	P0=0x04;
	Select573(7);
	P0=tab[san];
	delayms(1);
	
	Select573(6);
	P0=0x08;
	Select573(7);
	P0=tab[si];
	delayms(1);
}

void display3()
{ 
	Select573(6);
	P0=0x10;
	Select573(7);
	P0=tab[wu];
	delayms(1);
	
	Select573(6);
	P0=0x20;
	Select573(7);
	P0=tab[liu];
	delayms(1);
}

void display4()
{ 
	Select573(6);
	P0=0x40;
	Select573(7);
	P0=tab[qi];
	delayms(1);
	
	Select573(6);
	P0=0x80;
	Select573(7);
	P0=tab[ba];
	delayms(1);
	
	Select573(6);
	P0=0xff;
	Select573(7);
	P0=0xff;
}

void keyscan()
{ 
	if(P33==0)
	{ //S4
		delayms(5);
		if(P33==0)
		{ 
			if(mode==0)
			{ 
				mode=1;
				tomax=tmax;
				tomin=tmin;
			}
			else if(mode==1)
			{ 
				mode=0;
				if(tmax<tmin)
				{ 
					tmax=tomax;
					tmin=tomin;
				}
			}
		}
		while(!P33);
	}
		
	if(P32==0)
	{ //S5
		delayms(5);
		if(P32==0)
		{ 
			if(mode==1)
			{ 
				if(choose==0)choose=1;
				else if(choose==1)choose=0;	
			}
		}
		while(!P32);
	}
		
	if(P31==0)
	{ //S6
		delayms(5);
		if(P31==0)
		{ 
			if(mode==1)
			{ 
				if(choose==0)
				{ 
					if(tmax<99)tmax++;
				}
				else if(choose==1)
				{ 
					if(tmin<99)tmin++;
				}
			}

		}
		while(!P31);
	}
	
	if(P30==0)
	{ //S7
		delayms(5);
		if(P30==0)
		{ 
			if(mode==1)
			{ 
				if(choose==0)
				{ 
					if(tmax>0)tmax--;
					
				}
				else if(choose==1)
				{ 
					if(tmin>0)tmin--;
				}
		}
		while(!P30);
	  }
	}
}

二、icc.c

/* 程序说明: IIC总线驱动程序 软件环境: Keil uVision 4.10 硬件环境: CT107单片机综合实训平台 8051,12MHz 日 期: 2011-8-9 */

#include "reg52.h"
#include "intrins.h"

#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();} 


#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */


//总线启动条件
void IIC_Start(void)
{ 
	SDA = 1;
	SCL = 1;
	somenop;
	SDA = 0;
	somenop;
	SCL = 0;	
}

//总线中止条件
void IIC_Stop(void)
{ 
	SDA = 0;
	SCL = 1;
	somenop;
	SDA = 1;
}

//应答位控制
void IIC_Ack(bit ackbit)
{ 
	if(ackbit) 
	{ 	
		SDA = 0;
	}
	else 
	{ 
		SDA = 1;
	}
	somenop;
	SCL = 1;
	somenop;
	SCL = 0;
	SDA = 1; 
	somenop;
}

//等待应答
bit IIC_WaitAck(void)
{ 
	SDA = 1;
	somenop;
	SCL = 1;
	somenop;
	if(SDA)    
	{    
		SCL = 0;
		IIC_Stop();
		return 0;
	}
	else  
	{  
		SCL = 0;
		return 1;
	}
}

//经过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{ 
	unsigned char i;
	for(i=0;i<8;i++)
	{    
		if(byt&0x80) 
		{ 	
			SDA = 1;
		}
		else 
		{ 
			SDA = 0;
		}
		somenop;
		SCL = 1;
		byt <<= 1;
		somenop;
		SCL = 0;
	}
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{ 
	unsigned char da;
	unsigned char i;
	
	for(i=0;i<8;i++)
	{    
		SCL = 1;
		somenop;
		da <<= 1;
		if(SDA) 
		da |= 0x01;
		SCL = 0;
		somenop;
	}
	return da;
}

unsigned char AD_get(unsigned char add)
{ 
	unsigned char temp;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();	
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_Stop();
	return temp;
}

void AD_write(unsigned char add,unsigned char dat)
{ 
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}


unsigned char EEPROM_get(unsigned char add)
{ 
	unsigned char temp;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();	
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_Stop();
	return temp;
}

void EEPROM_write(unsigned char add,unsigned char dat)
{ 
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_Stop();
}

三、onewire.c

/* 程序说明: 单总线驱动程序 软件环境: Keil uVision 4.10 硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机 日 期: 2011-8-9 */
#include "reg52.h"

sbit DQ = P1^4;  //单总线接口

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{ 
	char i;
	while(t--)
	{ 
		for(i=12;i>0;i--);
	}
}

//经过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{ 
	unsigned char i;
	for(i=0;i<8;i++)
	{ 
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{ 
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{ 
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{ 
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}

//DS18B20设备初始化
bit init_ds18b20(void)
{ 
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80);
  	DQ = 1;
  	Delay_OneWire(10); 
    initflag = DQ;     
  	Delay_OneWire(5);
  
  	return initflag;
}

unsigned char temperature_rd(void)
{ 
	unsigned char low,high;
	unsigned char temp;
	init_ds18b20();
	Write_DS18B20(0XCC);
	Write_DS18B20(0X44);
	Delay_OneWire(200);
	
	init_ds18b20();
	Write_DS18B20(0XCC);
	Write_DS18B20(0XBE);
	low=Read_DS18B20();
	high=Read_DS18B20();
	temp=high<<4;
	temp|=low>>4;
	return temp;
}

float temperature_rd_F(void)
{ 
	unsigned char low,high;
	unsigned int temp;
	float temperature;
	init_ds18b20();
	Write_DS18B20(0XCC);
	Write_DS18B20(0X44);
	Delay_OneWire(200);
	
	init_ds18b20();
	Write_DS18B20(0XCC);
	Write_DS18B20(0XBE);
	low=Read_DS18B20();
	high=Read_DS18B20();
	temp=high&0x0f;
	temp<<=8;
	temp|=low;
	temperature=temp*0.0625;
	return temperature;
}
相关文章
相关标签/搜索