第十一屆 藍橋杯 單片機設計與開發項目 省賽 程序設計試題及源碼

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;
}
相關文章
相關標籤/搜索