蓝桥杯单片机第11届

 全部代码:主函数

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

typedef struct
{
	unsigned char b1:1;
	unsigned char b2:1;
	unsigned char b3:1;
	unsigned char b4:1;
	unsigned char b5:1;
	unsigned char b6:1;
	unsigned char b7:1;
	unsigned char b8:1;
}bits;

typedef union 
{
	unsigned char Hex;
	bits B;
}HexToBit;

HexToBit led_ctrl; // 控制led的字节


unsigned char code smg_duanma[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char smg[8];
unsigned char Tmax=30,Tmin=20;//退出参数界面后生效的参数。不用在数码管显示
unsigned char tTmax=30,tTmin=20;//在调整参数表界面使用


void vDevice_Process(unsigned char p2dat,unsigned char p0dat)
{
	P0=p0dat;
	P2 = (P2&0x1f)|p2dat;
	P2 = (P2&0x1f)|0x00;
}
//定时器2
void Timer2Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x04;		//定时器时钟1T模式
	T2L = 0x20;		//设置定时初值
	T2H = 0xD1;		//设置定时初值
	AUXR |= 0x10;		//定时器2开始计时
	EA=1;
	IE2 |= 0x04;
}

//读取温度
unsigned char temp;
void vRead_temp()
{
	temp = rd_temperature();
}


//数码管操作函数
bit mode_smg=0;   
bit mode_set=1;
unsigned int cnt_smg;
void vSMG_Process()
{
	if(mode_smg==0)//显示温度
	{
		smg[0]=0xc6;
		smg[1]=0xff;
		smg[2]=0xff;
		smg[3]=0xff;
		smg[4]=0xff;
		smg[5]=0xff;
		smg[6]=smg_duanma[temp/10];
		smg[7]=smg_duanma[temp%10];
	}
	
	if(mode_smg==1)//显示参数
	{
		if(mode_set==0)//设置上限
		{
			smg[0]=0x8c;
			smg[1]=0xff;
			smg[2]=0xff;
			if(cnt_smg<500)
			{
				smg[3]=smg_duanma[tTmax/10];
				smg[4]=smg_duanma[tTmax%10];
			}
			else if(cnt_smg<1000)
			{
				smg[3]=0xff;
				smg[4]=0xff;
			}
			else
			{
				cnt_smg=0;
			}			
			smg[5]=0xff;
			smg[6]=smg_duanma[tTmin/10];
			smg[7]=smg_duanma[tTmin%10];
		}
		
		if(mode_set==1)//设置下限
		{
			smg[0]=0x8c;
			smg[1]=0xff;
			smg[2]=0xff;
			smg[3]=smg_duanma[tTmax/10];
			smg[4]=smg_duanma[tTmax%10];		
			smg[5]=0xff;
			if(cnt_smg<500)
			{
				smg[6]=smg_duanma[tTmin/10];
				smg[7]=smg_duanma[tTmin%10];
			}
			else if(cnt_smg<1000)
			{
				smg[6]=0xff;
				smg[7]=0xff;
			}
			else
			{
				cnt_smg=0;
			}
		}
	}
}

//数码管显示
void vSMG_Show()
{
	static unsigned char i;
	vDevice_Process(0xc0,0x00);
	vDevice_Process(0xe0,smg[i]);
	vDevice_Process(0xc0,0x01<<i);
	i=(i+1)%8;
}

//独立按键BTN
unsigned char Trg,Cont;
void Three_Keys()
{
	unsigned char ReadData = P3^0xff;
	Trg = ReadData&(ReadData^Cont);
	Cont = ReadData;
}

//按键扫描
unsigned int cnt_key;
void vScan_Keys()
{
	if(cnt_key>=10)  //10ms扫描一次 消抖
	{
		cnt_key=0;
		Three_Keys();
		
		if(Trg&0x01)//S7
		{
			if(mode_smg==1)
			{
				if(mode_set==0)
				{
					if(tTmax>0)tTmax--;
				}
				else if(mode_set==1)
				{
					if(tTmin>0)tTmin--;
				}
			}
		}
		if(Trg&0x02)//S6
		{
			if(mode_smg==1)
			{
				if(mode_set==0)
				{
					if(tTmax<99)tTmax++;
				}
				else if(mode_set==1)
				{
					if(tTmin<99)tTmin++;
				}
			}
		}
		if(Trg&0x04)//S5
		{
			if(mode_smg==1)
			{
				mode_set=~mode_set;
			}			
		}
		if(Trg&0x08)//S4
		{
			mode_smg=!mode_smg;
			if(mode_smg==1)
			{
				mode_set=1;//进入设置时选择下限参数设置
				tTmax=Tmax;//将设置参数初始化为真实参数,避免显示上次保存的不合理参数
				tTmin=Tmin;
			}
			if(mode_smg==0)
			{
				if(tTmax>=tTmin)
				{
					Tmax=tTmax;
					Tmin=tTmin;
					led_ctrl.B.b4=1;
				}
				else
				{
					led_ctrl.B.b4=0;
				}
			}
		}
	}
}

//DAC输出
void vDAC_out()
{
	if(temp>Tmax)
	{
		DAC_out(204);  //255/5*4  4V
		led_ctrl.B.b1=0;//L1点亮
		led_ctrl.B.b2=1;
		led_ctrl.B.b3=1;
	}
	else if((temp<Tmax)&&(temp>Tmin))
	{
		DAC_out(153); //3V
		led_ctrl.B.b1=1;//L2点亮
		led_ctrl.B.b2=0;
		led_ctrl.B.b3=1;
	}
	else if(temp<Tmin)
	{
		DAC_out(102);  //2V
		led_ctrl.B.b1=1;//L3点亮
		led_ctrl.B.b2=1;
		led_ctrl.B.b3=0;		
	}
}

//初始化系统
void System_init()
{
	led_ctrl.Hex = 0xff;
	vDevice_Process(0x80, led_ctrl.Hex);
	vDevice_Process(0xa0, 0x00);
}

void main()
{
	System_init();
	Timer2Init();
	while(1)
	{
		vRead_temp();
		vSMG_Process();
		vScan_Keys();
		vDAC_out();
	}
}

//定时器服务
void time2_service() interrupt 12
{
	cnt_key++;
	cnt_smg++;
	vSMG_Show();
	vDevice_Process(0x80, led_ctrl.Hex);
}

官方iic驱动函数

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


//DAC输出
void DAC_out(unsigned char dat)
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}

官方单总线驱动函数 

#include "reg52.h"

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

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	t = t*12;
	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(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 rd_temperature()
{
	unsigned int temp;
	unsigned char lsb,msb;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	lsb = Read_DS18B20();
	msb = Read_DS18B20();
	
	temp = ((msb<<8)|lsb)*0.0625;
	return temp;
	
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值