蓝桥杯单片机第9届国赛

题目

在这里插入图片描述

main.c

#include<stc15f2k60s2.h>

#define uchar unsigned char

#define s0 0
#define s1 1
#define s2 2

void write_eeprom(uchar add, uchar dat);
uchar read_eeprom(uchar add);
uchar read_vol();
int get_tempr();

code uchar semg[16] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8,  0x80,  0x90,
											 0xc1, 0x8e, 0xc6, 0x89, 0x8c, 0xff};
code uchar semg_bit[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20,  0x40,  0x80};
uchar semg_temp[8] = {15, 15, 15, 15, 15, 15, 15, 15};

uchar state = s0;
uchar state_dis = s0;
uchar state_mem = s0;
uchar state_para = s0;


long count = 0;
long fre = 0;
uchar vol = 0;
uchar vol_thre = 10;
int tempr = 0;

uchar div_temp[6] = {0, 0, 0, 0, 0, 0};
uchar memory_write[7] = {35, 1, 1, 255, 0, 230, 10};
uchar memory_read[6] = {0, 0, 0, 0, 0, 0};

flag_s6 = 0;
uchar keycode = 0;


void Delay4ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 47;
	j = 174;
	do
	{
		while (--j);
	} while (--i);
}


void allinit()
{
	P2 = 0x80;	P0 = 0xff;
	P2 = 0xa0;	P0 = 0x00;
	P2 = 0xc0;	P0 = 0xff;
	P2 = 0xe0;	P0 = 0xff;	
}


void Timer1Init(void)		//2毫秒@12.000MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x40;		//设置定时初值
	TH1 = 0xA2;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	ET1 = 1;
	EA = 1;
}


void count0init()
{
    AUXR |= 0x80;                    //timer0 work in 1T mode
    TMOD |= 0x06;                    //set timer0 as counter mode2 (8-bit auto-reload)
    TL0 = TH0 = 0xff;               //fill with 0xff to count one time
    TR0 = 1;                        //timer0 start run
    ET0 = 1;                        //enable T0 interrupt
}


void display()
{
	uchar i;
	
	if(state == s0)
	{
		if(state_dis == s0 && i == 6)
		{
			P2 = 0xe0;	P0 = semg[semg_temp[i]] & 0x7f;
		}
		else if(state_dis == s2 && i == 5)
		{
			P2 = 0xe0;	P0 = semg[semg_temp[i]] & 0x7f;
		}
		else
		{
			P2 = 0xe0;	P0 = semg[semg_temp[i]];
		}
	}
	else if(state == s1)
	{
		if(state_mem == s0 && i == 6)
		{
			P2 = 0xe0;	P0 = semg[semg_temp[i]] & 0x7f;
		}
		else if(state_mem == s2 && i == 5)
		{
			P2 = 0xe0;	P0 = semg[semg_temp[i]] & 0x7f;
		}
		else
		{
			P2 = 0xe0;	P0 = semg[semg_temp[i]];
		}
	}
	else if(state == s2)
	{
		if(i == 6)
		{
			P2 = 0xe0;	P0 = semg[semg_temp[i]] & 0x7f;
		}
		else
		{
			P2 = 0xe0;	P0 = semg[semg_temp[i]];
		}
	}
	else
	{
		P2 = 0xe0;	P0 = semg[semg_temp[i]];
	}
	P2 = 0xc0;	P0 = semg_bit[i];
	P2 = 0x00;	P0 = 0xff;
	
	i++;
	if(i == 8)
		i = 0;
}


void led()
{
	static uchar time_led = 0;
	
	if(state == s0)
	{
		if(state_dis == s0)
			P02 = 0;
		else if(state_dis == s1)
			P01 = 0;
		else if(state_dis == s2)
			P00 = 0;
		else	;	
	}
	else
		P0 = P0 | 0x7f;
	
	if(vol > vol_thre)
	{
		if(time_led < 100)
			P07 = 0;
		else if(time_led < 200)
			P07 = 1;
		else
			time_led = 0;
		time_led++;
	}
	else
		P07 = 1;
	P2 = 0x80;
	P2 = 0x00;	P0 = 0xff;
}


void fun_count() interrupt 1
{
	count++;
}


void fun() interrupt 3
{
	static int time_fre = 0, time_s6 = 0;
	uchar i = 0, j; 
	static uchar state_key = s0;
	
	display();
	led();
	
	time_fre++; j++;
	
	if(j == 50)
	{
		vol = read_vol();
	}
	
	if(time_fre == 500)
	{
		ET0 = 0;
		time_fre = 0;
		fre = count;
		count = 0;
		ET0 = 1;
	}
	
	switch(state_key)
	{
		case s0:
		{
			if(keycode == 0x02 && state == s2)
			{
				time_s6++;
				if(time_s6 == 400)
				{
					time_s6 = 0;
					flag_s6 = 1;
					state_key = s1;
				}
			}
			else	;
		}	break;
		
		case s1:
		{
			if(keycode != 0x02)
			{
				state_key = s0;
				flag_s6 = 0;
			}
			else	;
		}	break;
		
		default:	state_key = s0;	break;
	}
}


char keyscan()
{
	char keyvalue = -1;
	uchar trg = 0, i = 0;
	static uchar keybefore = 0;
	
	P3 = P3 | 0x0f;	P44 = 0;	P42 = 0;	P35 = 0;
	keycode = (P3 ^ 0xff) & 0x0f;
	trg = keycode & (keycode ^ keybefore);
	keybefore = keycode;
	
	if(trg)
	{
		for(i = 0; i < 4; i++)
			if(trg == (0x08 >> i))
			{
				keyvalue = i + 4;
				break;
			}
	}
	
	return keyvalue;
}


void menu(char keyvalue)
{
	uchar i = 0;
	static uchar j = 0, c_save = 0, flag_save = 0;
	long temp = 0;
	
	if(keyvalue == 5)
	{
		flag_save = 1;
	}
	if(flag_save == 1)
	{
		if(c_save == 0)
			memory_write[0] = vol;
		else if(c_save == 1)
			memory_write[1] = fre >> 16;
		else if(c_save == 2)
			memory_write[2] = (fre & 0x0000ff00) >> 8;
		else if(c_save == 3)
			memory_write[3] = fre & 0x000000ff;
		else if(c_save == 4)
			memory_write[4] = tempr >> 8;
		else if(c_save == 5)
			memory_write[5] = tempr & 0x00ff;
		else if(c_save == 6)
			memory_write[6] = vol_thre;
		EA = 0;
		write_eeprom(2 * c_save, memory_write[c_save]);
		EA = 1;
		if(c_save <= 5)
			memory_read[c_save] = memory_write[c_save];
		c_save ++;
		if(c_save == 7)
		{
			c_save = 0;
			flag_save = 0;
		}
	}
	switch(state)
	{
		case s0:
		{
			if(keyvalue == 6)
			{
				state = s1;
				state_mem = s0;
			}
			else if(keyvalue == 7)
			{
				state = s2;
				state_para = s0;		
			}
			else	;
			
			semg_temp[0] = 10 + state_dis;
			semg_temp[1] = 15;
			semg_temp[2] = 15;
			switch(state_dis)
			{
				case s0:
				{
					semg_temp[0] = 10;
					semg_temp[3] = 15;
					semg_temp[4] = 15;
					semg_temp[5] = 15;
					semg_temp[6] = vol / 10;
					semg_temp[7] = vol % 10;
					
					if(keyvalue == 4)
						state_dis = s1;
				}	break;
				
				case s1:
				{	
					for(i = 2; i < 8; i++)
					{
						if(div_temp[i - 2] > 0)
							break;
						else
							semg_temp[i] = 15;
					}
					for(i = i; i < 8; i++)
					{
						semg_temp[i] = div_temp[i - 2];
					}
					
					if(keyvalue == 4)
						state_dis = s2;					
				}	break;

				case s2:
				{
					semg_temp[3] = 15;
					if(div_temp[0] == 0)
					{
						semg_temp[4] = 15;
						i = 5;
					}
					else
						i = 4;
					for(i = 4; i < 8; i++)
					{
						semg_temp[i] = div_temp[i - 4];
					}
					
					if(keyvalue == 4)
						state_dis = s0;
				}	break;
				
				default:	state_dis = s0;	break;
			}
		}	break;
		
		case s1:
		{
			if(keyvalue == 7)
			{
				state = s2;
				state_para = s0;				
			}
			else	;
			
			semg_temp[0] = 13;
			semg_temp[1] = 10 + state_mem;
			semg_temp[2] = 15;
			switch(state_mem)
			{
				case s0:
				{
					semg_temp[3] = 15;
					semg_temp[4] = 15;
					semg_temp[5] = 15;
					semg_temp[6] = memory_read[0] / 10;
					semg_temp[7] = memory_read[0] % 10;
					
					if(keyvalue == 4)
						state_mem = s1;
				}	break;
				
				case s1:
				{	
					for(i = 2; i < 8; i++)
					{
						if(div_temp[i - 2] > 0)
							break;
						else
							semg_temp[i] = 15;
					}
					for(i = i; i < 8; i++)
					{
						semg_temp[i] = div_temp[i - 2];
					}
					
					if(keyvalue == 4)
						state_mem = s2;					
				}	break;

				case s2:
				{
					semg_temp[3] = 15;
					if(div_temp[0] == 0)
					{
						semg_temp[4] = 15;
						i = 5;
					}
					else
						i = 4;
					for(i = 4; i < 8; i++)
					{
						semg_temp[i] = div_temp[i - 4];
					}
					
					if(keyvalue == 4)
						state_mem = s0;
				}	break;
				
				default:	state_mem = s0;	break;
			}
		}	break;

		case s2:
		{
			semg_temp[0] = 14;
			for(i = 1; i < 6; i++)
				semg_temp[i] = 15;
			semg_temp[6] = vol_thre / 10;
			semg_temp[7] = vol_thre % 10;
			if(flag_s6 == 0)
			{
				if(keyvalue == 6)
					vol_thre++;
				if(vol_thre > 50)
					vol_thre = 0;
			}
			else
			{
				j++;
				if(j == 10)
				{
					j = 0;
					vol_thre++;
					if(vol_thre > 50)
						vol_thre = 0;
				}
			}
			if(keyvalue == 7)
			{
				state = s0;
				state_dis = s0;
			}
		}	break;
		
		default:	state = s0;	break;
	}
}


void handle_data()
{
	long temp = 0, div = 0;
	uchar i = 0;
	
	if( state == s0)
	{
		if(state_dis == s1)
		{
			div = 100000;
			temp = fre;
			for(i = 0; i < 6; i++)
			{
				div_temp[i] = temp / div;
				temp = temp - div * div_temp[i];
				div = div / 10;
			}
		}
		else if(state_dis == s2)
		{
			div = 1000;
			temp = tempr;
			for(i = 0; i < 4; i++)
			{
				div_temp[i] = temp / div;
				temp = temp - div * div_temp[i];
				div = div / 10;
			}
		}
	}
	else if(state == s1)
	{
		if(state_mem == s1)
		{
			div = 100000;
			temp = (memory_read[1] * 65536) | (memory_read[2] * 256) | (memory_read[3]);
			for(i = 0; i < 6; i++)
			{
				div_temp[i] = temp / div;
				temp = temp - div * div_temp[i];
				div = div / 10;
			}
		}
		else if(state_mem == s2)
		{
			div = 1000;
			temp = memory_read[4] * 255 + memory_read[5];
			for(i = 0; i < 4; i++)
			{
				div_temp[i] = temp / div;
				temp = temp - div * div_temp[i];
				div = div / 10;
			}
		}
	}
}


void main()
{
	char keyvalue = -1;
	uchar i = 0;

	for(i = 0; i < 6; i++)
		memory_read[i] = read_eeprom(2 * i);
	vol_thre = read_eeprom(12);
	allinit();
	
	Timer1Init();
	count0init();
	
	while(1)
	{
		keyvalue = keyscan();
		menu(keyvalue);
		handle_data();
		tempr = get_tempr();
		Delay4ms();
	}
}

iic.c

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

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

#define uchar unsigned char
	
#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

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

void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}
//总线启动条件
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

//总线停止条件
void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//等待应答
bit IIC_WaitAck(void)
{
	SCL  = 1;
	IIC_Delay(DELAY_TIME);
	SDA = 1;
	IIC_Delay(DELAY_TIME);
	
	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++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    }
    SCL  = 0;  
}

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


void write_eeprom(uchar add, uchar dat)
{
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}

uchar read_eeprom(uchar add)
{
	uchar dat;
	
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	dat = IIC_RecByte();
	IIC_Stop();
	
	return dat;
}

uchar read_vol()
{
	uchar dat;
	
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x03);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	dat = IIC_RecByte();
	IIC_Stop();
	
	return dat * 0.196078;
}

onewire.c

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

#define uchar unsigned char
	
sbit DQ = P1^4;  //单总线接口

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	uchar i = 0;
	while(t--)
		for(i = 0; i < 12; 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;
}

int get_tempr()
{
	uchar low, high, temp;
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	Delay_OneWire(500);
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	low = Read_DS18B20();
	high = Read_DS18B20();
	
	temp = (low % 16) * 6.25;
	low = low >> 4;
	high = high << 4;
	
	return ((low + high) * 100 + temp);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值