第九届蓝桥杯国赛

main.c

#include "main.h"

unsigned char tab[27]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XC0&0X7F,0XF9&0X7F,0XA4&0X7F,0XB0&0X7F,0X99&0X7F,0X92&0X7F,0X82&0X7F,0XF8&0X7F,0X80&0X7F,0X90&0X7F,0XBF,0XFF,0XC1,0X8E,0X89,0XC6,0X8C};
unsigned char dsbuff[8]={21,21,21,21,21,21,21,21};
unsigned char com;

unsigned int temperature,dianya,pinlv;
int temperature_history[2],dianya_history,pinlv_history[3];
unsigned int temperature_value,dianya_value,pinlv_value;
unsigned int dianya_para;

bit led1,led2,led3,led8;
int led8_count;

unsigned int ne555_count,t1_count;
bit ne555_flag;

unsigned char key4;//0-温度 1-电压 2-频率 
bit key5,key6,key7;//key5-存储 key6-回显/ key7-设置
bit down;
unsigned int down_count,up_time,down_time;

bit display_flag ;
int display_count;

void main(void)
{
	EA=1;
	all_init();
//	eeprom_init(6);
	Timer0Init();
	Timer1Init();
//	Timer2Init();
	
	//读参数
	eeprom_read(2,temperature_history,0x10);
	dianya_history = iic_read(0x12);Delay2ms();
	eeprom_read(3,pinlv_history,0x13);

	while(1)
	{
		Key_Individual();
		if(display_flag == 1)
		{
			display_flag = 0;
			dianya = pcf8951_adc(0x03)/5.1;
			temperature = temp1_get();
		}
		
		ne555();
		if(display_flag == 1)
		{
			if(key7 == 1)//电压参数显示
			{
				smg_display(26,21,21,21,21,21,dianya_para/10%10+10,dianya_para/1%10);
			}else if(key7 == 0)
			{
				if(key6 == 1)//回显数据
				{		
					history_display();			
				}else if(key6 == 0)//实时数据
				{
					data_display();
				}	
			}
		}
	}
}

void ne555(void)
{
	if(ne555_flag)
	{
		ne555_flag = 0;
		pinlv = ne555_count*10;
		ne555_count = 0;
		ET0 = 1;
		TR0 = 1;
	}
}
void eeprom_init(int num)
{
	int i;
	for(i=0;i 99999)
	{
		dsbuff[2]= pinlv/100000%10;
	}else
	{
		dsbuff[2]= 21;
	}
	if(pinlv > 9999)
	{
		dsbuff[3]= pinlv/10000%10;
	}else{
		dsbuff[3]= 21;
	}
	if(pinlv > 999)
	{
		dsbuff[4]= pinlv/1000%10;
	}else
	{
		dsbuff[4]= 21;
	}
	if(pinlv > 99)
	{
		dsbuff[5]= pinlv/100%10;
	}else 
	{
		dsbuff[5]= 21;
	}
	dsbuff[6]= pinlv/10%10;
	dsbuff[7]= pinlv/1%10;
}


void history_display(void)
{
	if(key4 == 0)//温度
	{
		eeprom_read(2,temperature_history,0x10);
		temperature_value = temperature_history[0]*100+temperature_history[1];
		smg_display(24,25,21,21,temperature_value/1000%10,temperature_value/100%10+10,temperature_value/10%10,temperature_value/1%10);
	}else if(key4 == 1)//电压
	{
		dianya_history = iic_read(0x12);Delay2ms();
	
		smg_display(24,22,21,21,21,21,dianya_history/10%10+10,dianya_history/1%10);
	}else if(key4 == 2)//频率
	{
		eeprom_read(3,pinlv_history,0x13);
		pinlv_value = pinlv_history[0]*10000+pinlv_history[1]*100+pinlv_history[2];
		pinlv_history_display();
	}
}


void pinlv_history_display(void)
{
	dsbuff[0]= 24;
	dsbuff[1]= 23;
	
	if(pinlv_value > 99999)
	{
		dsbuff[2]= pinlv_value/100000%10;
	}else
	{
		dsbuff[2]= 21;
	}
	if(pinlv_value > 9999)
	{
		dsbuff[3]= pinlv_value/10000%10;
	}else{
		dsbuff[3]= 21;
	}
	if(pinlv_value > 999)
	{
		dsbuff[4]= pinlv_value/1000%10;
	}else
	{
		dsbuff[4]= 21;
	}
	if(pinlv_value > 99)
	{
		dsbuff[5]= pinlv_value/100%10;
	}else 
	{
		dsbuff[5]= 21;
	}
	dsbuff[6]= pinlv_value/10%10;
	dsbuff[7]= pinlv_value/1%10;
}

void led_one(unsigned char dat)//单个LED操作
{
	P0 = dat;
	P2 = ((P2&0X1F)|0X80);
	P2 &= 0X1F;
}
void led_option(void)
{
	if(key4 == 0)
	{
		led1 = 1;led2 = 0;led3 = 0;
	}else if(key4 == 1)
	{
		led1 = 0;led2 = 1;led3 = 0;	
	}else if(key4 == 2)
	{
		led1 = 0;led2 = 0;led3 = 1;
	}
	
	if(led1&&led2&&led3&&led8)//1111
	{
		led_one(0X78);
	}else if(led1&&led2&&led3&&!led8)//1110
	{
		led_one(0XF8);
	}else if(led1&&led2&&!led3&&led8)//1101
	{
		led_one(0X7C);
	}else if(led1&&led2&&!led3&&!led8)//1100
	{
		led_one(0XFC);
	}else if(led1&&!led2&&led3&&led8)//1011
	{
		led_one(0X7A);
	}else if(led1&&!led2&&led3&&!led8)//1010
	{
		led_one(0XFA);
	}else if(led1&&!led2&&!led3&&led8)//1001
	{
		led_one(0X7E);
	}else if(led1&&!led2&&!led3&&!led8)//1000
	{
		led_one(0XFE);
	}else if(!led1&&led2&&led3&&led8)//0111
	{
		led_one(0X79);
	}else if(!led1&&led2&&led3&&!led8)//0110
	{
		led_one(0XF9);
	}else if(!led1&&led2&&!led3&&led8)//0101
	{
		led_one(0X7D);
	}else if(!led1&&led2&&!led3&&!led8)//0100
	{
		led_one(0XFD);
	}	else if(!led1&&!led2&&led3&&led8)//0011
	{
		led_one(0X7B);
	}else if(!led1&&!led2&&led3&&!led8)//0010
	{
		led_one(0XFB);
	}else if(!led1&&!led2&&!led3&&led8)//0001
	{
		led_one(0X7F);
	}else if(!led1&&!led2&&!led3&&!led8)//0000
	{
		led_one(0XFF);
	}
}

//全部初始化
void all_init(void)
{
	P2 &= 0X1F;
	 
	P0 = 0XFF;
	P2 = ((P2&0X1F)|0X80);
	P2 &= 0X1F;
	
	P0 = 0X00;
	P2 = ((P2&0X1F)|0XA0);
	P2 &= 0X1F;
	
	P0 = 0XFF;
	P2 = ((P2&0X1F)|0XE0);
	P2 &= 0X1F;
}

//数码管显示
void display(void)
{
	P0 = 0XFF;
	P2 = ((P2&0X1F)|0XE0);
	P2 &= 0X1F;
	
	P0 = 0X01 << com;
	P2 =( (P2&0X1F)|0XC0);
	P2 &= 0X1F;
	
	P0 = tab[dsbuff[com]];
	P2 = ((P2&0X1F)|0XE0);
	P2 &= 0X1F;
	if(++com >= 8)
		com = 0;
}


//独立按键扫描
void Key_Individual(void)
{
	P3 |= 0x0F;
	if(P3_LOW4  != 0x0F)
	{
		Delay2ms();
		if(P3_LOW4  != 0x0F)
		{
			 switch(P3_LOW4)
			{
				case 0x0E://S7
					key7 = ~key7;
						
				while(P3_LOW4  == 0x0E);
				break;
					
				case 0x0D://S6
					down = 1;
				down_time = down_count;

				while(P3_LOW4  == 0x0D);
					down = 0;
				up_time = down_count;
				if(up_time - down_time >= 400)//长按800ms
				{
					if(key7 == 1)//1-设置
					{
						dianya_para += 10;
						if(dianya_para > 50)
						{
							dianya_para = 0;
						}
					}
				}else													//短按
				{
					if(key7 == 1)//1-设置
					{
						if(++dianya_para > 50)
						{
							dianya_para = 0;
						}
					}else if(key7 == 0)//0-非设置
					{
						key6 = ~key6;
				   	}
				}
					down_count = 0;
					
				break;
				
				case 0x0B://S5
					iic_write(0x10,temperature/100);Delay2ms();
					iic_write(0x11,temperature%100);Delay2ms();
					
					iic_write(0x12,dianya);Delay2ms();
					
					iic_write(0x13,pinlv/10000);Delay2ms();
					iic_write(0x14,pinlv/100%100);Delay2ms();
					iic_write(0x15,pinlv%100);Delay2ms();
				while(P3_LOW4  == 0x0B);
				break;
				
				case 0x07://S4
					if(++key4 > 2)
					{
						key4 = 0;
					}
				while(P3_LOW4  == 0x07);
				break;
			}
		}
	}
}

//定时器0初始化
void Timer0Init(void)		//计数模式
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD |= 0x04;		//设置定时器模式
	TL0 = 0xFF;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;
	
}

//定时器0中断服务函数
void timer0_isr() interrupt 1
{
	ne555_count++;
}

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

void timer1_isr() interrupt 3
{
	display();
	led_option();
	if(++display_count >= 30)
	{
		display_count = 0;
		display_flag = 1;
	}
	if(++t1_count >= 50)
		{
			t1_count = 0;
			ET0 = 0;
			TR0 = 0;
			ne555_flag = 1;
		}
	
	if(dianya > dianya_para)
	{
		if(++led8_count >= 100)
		{
			led8_count = 0;
			led8 = ~led8;
		}
	}else if(dianya <= dianya_para)
	{
		led8 = 0;
	}
	if(down == 1)
	{
		down_count++;
	}
}

void Delay2ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	_nop_();
	i = 22;
	j = 128;
	do
	{
		while (--j);
	} while (--i);
}

//551

main.h

#ifndef _MAIN_H
#define _MAIN_H
#include "STC15F2K60S2.h"
#include "iic.h"
#include "onewire.h"

#define P3_LOW4 (P3&0x0F)


void all_init(void);//全部初始化
void display(void);//数码管显示
void Key_Individual(void);//独立按键扫描
void Timer0Init(void);		//2毫秒@11.0592MHz
void Timer1Init(void);		//2微秒@11.0592MHz
void Timer2Init(void);		//10毫秒@11.0592MHz
void Delay2ms();		//@11.0592MHz
void led_option(void);
void data_display(void);
void pinlv_display(void);
void history_display(void);
void pinlv_history_display(void);
void eeprom_init(int num);
void ne555(void);
void eeprom_read(int num,int *value,int addr);
void smg_display(int s1,int s2,int s3,int s4,int s5,int s6,int s7,int s8);
void led_one(unsigned char dat);//单个LED操作

#endif

iic.c

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

#include "iic.h"

//总线启动条件
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(unsigned char 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;
}


void iic_write(unsigned char addr,unsigned char dat)
{
	IIC_Start();
	IIC_SendByte(0XA0);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}


unsigned char iic_read(unsigned char addr)
{
	unsigned char temp;
	
	IIC_Start();
	IIC_SendByte(0XA0);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_Stop();
	
	
	IIC_Start();
	IIC_SendByte(0XA1);
	IIC_WaitAck();
	temp = IIC_RecByte();
	IIC_WaitAck();
	IIC_Stop();
	return temp;
}
unsigned char pcf8951_adc(unsigned char addr)
{
	unsigned char temp;
	
	IIC_Start();
	IIC_SendByte(0X90);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0X91);
	IIC_WaitAck();
	temp = IIC_RecByte();
	IIC_Ack(0);
	IIC_Stop();	
	
	return temp;
}

iic.h

#ifndef _IIC_H
#define _IIC_H

#include "STC15F2K60S2.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_();}

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

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


//函数声明
void IIC_Start(void); 
void IIC_Stop(void);  
void IIC_Ack(unsigned char ackbit); 
void IIC_SendByte(unsigned char byt); 
bit IIC_WaitAck(void);  
unsigned char IIC_RecByte(void); 
void iic_write(unsigned char addr,unsigned char dat);//eeprom写操作
unsigned char iic_read(unsigned char addr);//eeprom读操作
void pcf8951_dac(unsigned char dat);//pcf8951_dac输出
unsigned char pcf8951_adc(unsigned char addr);//pcf8951_adc采集

#endif

onewire.c

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

#include "onewire.h"

//单总线延时函数
void Delay_OneWire(unsigned int t)
{
	int i;
  while(t--)for(i=0;i<8;i++);
}

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

//通过单总线向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;
}



//一位小数
unsigned int temp1_get(void)
{
	unsigned int high,low,temp;
	
	Init_DS18B20();
	Write_DS18B20(0xcc);
	Delay_OneWire(200);
	Write_DS18B20(0x44);
	Delay_OneWire(200);
	
	Init_DS18B20();
	Write_DS18B20(0xcc);
	Delay_OneWire(200);
	Write_DS18B20(0xBE);
	
	
	low = Read_DS18B20();
	high = Read_DS18B20();
	
	
	temp = high << 8;
	temp |= low;
	
//	temp = temp*(0.625);//一位小数
	temp = temp*(6.25);//两位小数
	return temp;
}

iic.h

#ifndef _ONEWIRE_H
#define _ONEWIRE_H

#include "STC15F2K60S2.h"

#define OW_SKIP_ROM 0xcc
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xbe

//IC引脚定义
sbit DQ = P1^4;

//函数声明
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
bit Init_DS18B20(void);
unsigned char Read_DS18B20(void);
unsigned char temp_get(void);
unsigned int temp1_get(void);

#endif

 

你可能感兴趣的