蓝桥杯省一之路05——第十二届省赛真题第一场

一,代码部分

 1,ds18b20.c

#include "reg52.h"
#include "onewire.h"


void Convert_18b20()
{
	init_ds18b20();//初始化
	Write_DS18B20(0xcc);//跳过ROM
	Write_DS18B20(0x44);//开启温度转化
	
}

float Read_18b20()
{
	int t;
	float Temp;
	unsigned char LSB,MSB;
	init_ds18b20();//初始化
	Write_DS18B20(0xcc);//跳过ROM
	Write_DS18B20(0xbe);
	LSB=Read_DS18B20();
	MSB=Read_DS18B20();
	t=(MSB << 8) | LSB;
  Temp=t/16.0;
  return Temp;	
}
void Init_18b20()
{
   int T;
	Convert_18b20();
	
	do
	{
		T=Read_18b20();
	}while(T>60);
}

2,onewire

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

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

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	while(t--);
}

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

//从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(50);
	}
	return dat;
}

//DS18B20设备初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(120);
  	DQ = 0;
  	Delay_OneWire(800);
  	DQ = 1;
  	Delay_OneWire(100); 
    initflag = DQ;     
  	Delay_OneWire(50);
  
  	return initflag;
}






3,pcf8591.c

#include "reg52.h"
#include "iic.h"

//float Read_ADC()//RB2模拟量转数字量
//{
//	unsigned char temp;
//  float v;
//	//伪写操作
//	IIC_Start();
//  IIC_SendByte(0x90);//设备地址,最后一位置0为可写入
//  IIC_WaitAck();   	
//	IIC_SendByte(0x43);//RB2连接在8591的通道3
//	IIC_WaitAck();
//	
//	IIC_Start();
//	IIC_SendByte(0x91);
//	IIC_WaitAck();
//	temp=IIC_RecByte();//0~255 
//	IIC_SendAck(1); 
//	IIC_Stop(); 
//	v=temp*5/255.0;
//	return v;
//}	
void DAC(float temp)
{
	unsigned char u;
	u=temp*51;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck(); 
	IIC_SendByte(0x43);
	IIC_WaitAck();
	IIC_SendByte(u); //0~255
	IIC_SendAck(1);
	IIC_Stop(); 
}

3,smgshow.c

#include "reg52.h"
void Delay(int t)
{
	while(t--);
}
void HC573(unsigned char channel, unsigned char dat)
{
	P0=dat;
	switch(channel)
	{
		case 4:
			P2=(P2 & 0x1f) | 0x80;//选通Y4C,LED
		  break;
		case 5:
			P2=(P2 & 0x1f) | 0xa0;//选通Y5C,蜂鸣器,继电器
		  break;
		case 6:
			P2=(P2 & 0x1f) | 0xc0;//选通Y6C,数码管位选
		  break;
		case 7:
			P2=(P2 & 0x1f) | 0xe0;//选通Y7C,数码管段码
		  break;
	}
	P2=(P2 & 0x1f) | 0x00;
}
void Display_SMG(unsigned char pos,unsigned char val)
{

	HC573(6,0x01<<pos);
	HC573(7,val);
	Delay(500);
//	HC573(6,0x01<<pos);
	HC573(7,0xff);//消隐
}	
void Display_ALL(unsigned char dat)
{
	HC573(6,0xff);
	HC573(7,dat);
}

4,iic.c

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

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

#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);
}

//发送应答
void IIC_SendAck(bit ackbit)
{
    SCL = 0;
    SDA = ackbit;  					// 0:应答,1:非应答
    IIC_Delay(DELAY_TIME);
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SCL = 0; 
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//等待应答
bit IIC_WaitAck(void)
{
    bit ackbit;
	
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}

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

5,main.c

#include "reg52.h"
#include "ds18b20.h"
#include "pcf8591.h"
#include "smgshow.h"
sbit R1=P3^2;
sbit R2=P3^3;
sbit C1=P4^4;
sbit C2=P4^2;
unsigned int T;//DS18B20温度
int T_stand=25;
float U_out;//输出的电压值
int U_smg;//用于显示输出电压
bit sta_DAC=0; 
int T_temp=25;
void Read_T()//测量
{
	Convert_18b20();
	
	T=Read_18b20()*100;
}
void Out_DAC()
{
	if(sta_DAC==0 && (T/100)<T_stand)//模式1
	{
		U_out=0;
		DAC(U_out);
		U_smg=U_out*100;
		
	}
	else
	{
		U_out=5;
		DAC(U_out);
		U_smg=U_out*100;
	}
	if(sta_DAC==1)//模式2
	{
		if((T/100)<20)
		{
			U_out=1;
		  DAC(U_out);
		  U_smg=U_out*100;
		}
		else if((T/100)>20 && (T/100)<40)
		{
			U_out=(T/100.0)*3/20.0;
		  DAC(U_out);
		  U_smg=U_out*100;
		}
		else 
		{
			U_out=4;
		  DAC(U_out);
		  U_smg=U_out*100;
		}
	}
	
}
unsigned char sta_smg=0;
void SMGWork()
{
	switch(sta_smg)
	{
		case 0:
			Display_SMG(0,0xc6);
		  Display_SMG(4,SMGnotdotduanma[T/1000]);
		  Display_SMG(5,SMGdotduanma[T/100%10]); 
		  Display_SMG(6,SMGnotdotduanma[T/10%10]); 
		  Display_SMG(7,SMGnotdotduanma[T%10]); 
		break;
		case 1:
			Display_SMG(0,0x8c);
		  Display_SMG(6,SMGnotdotduanma[T_temp/10%10]); 
		  Display_SMG(7,SMGnotdotduanma[T_temp%10]); 
		break;
		case 2:
			Display_SMG(0,0x88);
		  Display_SMG(5,SMGdotduanma[U_smg/100%10]); 
		  Display_SMG(6,SMGnotdotduanma[U_smg/10%10]); 
		  Display_SMG(7,SMGnotdotduanma[U_smg%10]); 
		break;
	}
}
void Scan_KBD()//矩阵键盘扫描
{
	//扫描S4
	R2=0;
	R1=C1=C2=1;
	if(C1==0)
	{
		Delay(500);
		
			if(C1==0)//实现显示状态切换
			{
				if(sta_smg==0)
				{
					sta_smg=1;
				}
				else if(sta_smg==1)
				{
					sta_smg=2;
				T_stand=T_temp;
				}
				else 
				{
					sta_smg=0;
				}
				while(C1==0)
				{
				SMGWork();
				}
			}
		
	}
	//扫描S8
	R2=0;
	R1=C1=C2=1;
	if(C2==0)
	{
		Delay(500);
		if(C2==0)
		{
			if(sta_smg==1)
			{
			T_temp=T_temp-1;
				if(T_temp<0)
				
					T_temp=99;
				
				
			}
			while(C2==0)
				{
				SMGWork();
				}
		}
	}
	//扫描S9
	R1=0;
	R2=C1=C2=1;
	if(C2==0)
	{
		Delay(500);
		if(C2==0)
		{
			if(sta_smg==1)
			{
			T_temp=T_temp+1;
				if(T_temp>99)
				{
					T_temp=0;
				}
				
			}
				while(C2==0)
				{
				SMGWork();
				}
		}
	}
	//扫描S5
	R1=0;
	R2=C1=C2=1;
	if(C1==0)
	{
		Delay(500);
		if(C1==0)
		{
			if(sta_DAC==0)
			{
				sta_DAC=1;
			}
			else 
			{
				sta_DAC=0;
			}
			while(C1==0)
				{
				SMGWork();
				}
		}
	}
}
unsigned char sta_LED=0xff;
void LED()
{
	if(sta_DAC==0)
	{
		sta_LED &= ~0x01;
		HC573(4,sta_LED);
	}
	else
	{
		sta_LED |= 0x01;
		HC573(4,sta_LED);	
	}
	if(sta_smg==0)
	{
		sta_LED &= ~0x02;
		HC573(4,sta_LED);
	}
	else
	{
		sta_LED |= 0x02;
		HC573(4,sta_LED);
	}
		if(sta_smg==1)
	{
		sta_LED &= ~0x04;
		HC573(4,sta_LED);
	}
	else
	{
		sta_LED |= 0x04;
		HC573(4,sta_LED);
	}
		if(sta_smg==2)
	{
		sta_LED &= ~0x08;
		HC573(4,sta_LED);
	}
	else
	{
		sta_LED |= 0x08;
		HC573(4,sta_LED);
	}
}
void Inti_stsyem()
{
	HC573(4,0xff);
	HC573(5,0x00);
	Display_ALL(0xff);
	Init_18b20();
}
void main()
{
	Inti_stsyem();
	while(1)
	{
		Scan_KBD();
		Out_DAC();
		Read_T();
		SMGWork();
		LED();
		
	}
}

除了温度跟电压的区间线性变化内容较新外,并没有其他难点,明天做一做第二场看会不会难一点。

二,总结

这题做了不到2个小时,很多功能都可以延用之前的。明天开始客观题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值