蓝桥杯单片机组国赛第十届(附源码

前言

        国赛第十届是有一定难度的,需要达到使用多个模块且不冲突,其中有超声波、温度、串口、eeprom等等。话不多说,直接开始。

题目:

解析(伪代码:        

        --> typedef unsigned char u8;
        --> typedef unsigned int u16;

       超声波模块:

/*定义tx,rx引脚*/
sbit tx = P1^0;
sbit rx = P1^1;

void Delay14us()//@12.000MHz
{
   //正常为12us,出现异常情况可以试试13us,14us
    unsigned char i;
	_nop_();
	_nop_();
	i = 38;
	while (--i);
}
void sendwave() 
{
	u8 i;
	for ( i=0; i<8; i++)
	{
		tx = 0;
		Delay14us();
		tx = 1;
		Delay14us();
	}
}

void dist_read()	//超声波测距
{
	u16 time;
	CMOD = 0x00;    //采用PCA(可自行查手册查看
	CH = CL = 0;
	EA = 0;        //在一定程度上减少误差
	sendwave();
	EA = 1; CR=1;
	while (rx && !CF);
	CR = 0;
	if (CF == 0)
	{
		time = CH;
		time = (time<<8)|CL;
		distance = time*0.017;
		if(distance>99)		distance=99;
	}else{
		CF = 0;
		distance = 99;
	}
}

         DS18B20:

/*
    导入官方onewire.c
    写出onewire.h
*/

void delay(u16 a)
{
	while(a--);
}
void ds18b20_init()
{
	u8 i;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	for ( i=0; i<8; i++ )
	{
		delay(60000);    //消除上电读到85
	}
}

void ds18b20_read()	//温度读取
{
	u8 MSB,LSB;
	u16 Data;
	if(temp_down_t)		return;
	temp_down_t = 1;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	LSB = Read_DS18B20();
	MSB = Read_DS18B20();
	Data = MSB;
	Data = (Data<<8)|LSB;
	if((Data&0xf800) == 0x00)	//判断温度是否大于0摄氏度
	{
		Temp_t = Data*0.0625;
		temp = Temp_t*100;
	}
}

DAC输出:

void DA_Output(unsigned char num) //DA转换
{       
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x40);
	I2CWaitAck();
	I2CSendByte(num);
	I2CWaitAck();
	I2CStop();
}
unsigned char AD_Input(unsigned char addr)    //AD转换输出
{
	unsigned char Data=0;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	Data = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	return Data;
}
//*****************************************
void dac_ouput()		//dac处理函数
{
	u8 Data;    //即要输出的值
	if(dac_output)
	{
		if(distance<=dist_para_t)
		{
			Data = 102;
		}else{
			Data = 204;
		}
		DA_Output(Data);    //输出
	}else{
		DA_Output(20.4);
	}
}

串口通信:

/*
  波特率发生器:定时器1
  isp生成串口函数;
  补充ES=1;EA=1;
*/
void UartInit(void)		//4800bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设定定时器1为16位自动重装方式
	TL1 = 0xCC;		//设定定时初值
	TH1 = 0xFF;		//设定定时初值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
	EA = 1;
	ES = 1;
}
void sendbyte(u8 Data) //发送一个字节
{
	SBUF = Data;
	while(TI==0);     //TI==1时,数据发送完成,退出循环
	TI = 0;
}
void send_string(char* str)  //发送字符串
{
	while(*str != '\0')
	{
		sendbyte(*str++);
	}
}
//********************************
xdata u8 rx_buff[12];//放置在xdata,减少ram占用
xdata u8 tx_buff[12];
u8 sys_cli=0;//如果为1,10ms计时
u8 uar_10ms=0;//接收中断、串口处理清0,超过10ms没接收数据 即处理指令

void uart_work()	//串口处理函数
{
	u8 i=0;
	if(!rx_cnt)		return;
	if(uar_10ms>=10)
	{
		sys_cli = 0;
		uar_10ms = 0;
		if(rx_buff[0]=='S' && rx_buff[1]=='T')    //接收字符串->判断
		{
			sprintf(tx_buff,"$%2d,%4.2f\r\n",distance,Temp_t);
		}else if(rx_buff[0]=='P' && rx_buff[1]=='A' && rx_buff[2]=='R' && rx_buff[3]=='A'){
			sprintf(tx_buff,"#%d,%d\r\n",(int)dist_para_t,(int)temp_para_t);
		}else{
			sprintf(tx_buff,"ERROR\r\n");
		}
		send_string(tx_buff);
		for(i=0; i<rx_cnt; i++)
		{
			rx_buff[i] = 0;
			tx_buff[i] = 0;
		}
		rx_cnt = 0;
	}
}


void Uart_Routine() interrupt 4    //串口中断
{
	if(RI==1)
	{
		sys_cli = 1;
		uar_10ms = 0;
		rx_buff[rx_cnt++] = SBUF;
		RI = 0;		
	}
}

EEPROM:

由于参数变动次数范围为0-65535,可以取高八位为一字节,低八位为一字节,保存到两个地址。

void at24c02_write(unsigned char addr,date)    //参数:地址,数据
{
	I2CStart();
	I2CSendByte(0xA0);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	I2CSendByte(date);
	I2CWaitAck();
	I2CStop();
}
void write_stock()
{
	u8 high,low;
	if(stoc_down_t)	 return;    //25ms写入一次
	stoc_down_t = 1;
	if(mode==1)
	{
		if((temp_para_t!=temp_para)||(dist_para_t!=dist_para))  //判断参数是否改变
		{
			temp_para_t = temp_para;
			dist_para_t = dist_para;
			bian_cnt++;
			high = (u8)(bian_cnt>>8);
			low  = (u8)bian_cnt;
			at24c02_write(0x01,high);
			at24c02_write(0x00,low);
			Delay5ms();	
		}
	}
}

长按的实现:

/*
    以按键S13为例子,实现长按
*/
u8 key_read()	//按键响应
{
	u8 temp=0;
	ET0 = 0;
	P35=0;P34=1;
	if(P32 == 0)	temp = 13;
	if(P33 == 0)	temp = 12;
	P35=1;P34=0;
	if(P32 == 0)	temp = 17;
	if(P33 == 0)	temp = 16;
	ET0 = 1;
	return temp;
}
void key_work()		//按键处理函数
{
	u8 high,low;
	if(key_down_t)	return;    //10ms进一次函数,消除按键抖动
	key_down_t = 1;
	key_val = key_read();
	key_down = key_val&(key_val^key_old);//下降沿
	key_up  = ~key_val&(key_val^key_old);
	key_old = key_val;

    if(key_down == 13)    //按键按下,标志为1
	{
		long_an = 1;
	}
    if(key_up == 13)       //按键抬起
	{
		long_an = 0;
		time1s = 0;
		if(!flag1s)        //判断flag1s是否为1
		{
			if(++mode==3)	mode=1;
			modepro = 1;
		}
		if(flag1s)
		{
			flag1s = 0;
			if(dac_output)	dac_output=0;else dac_output=1;
		}
	}
}
void Timer_Routine() interrupt 1
{
	if(++key_down_t == 10)		key_down_t = 0;
	if(long_an)		time1s++;    

	if(time1s>=1000)    //若时间超过1s,flag1s=1;
	{
		time1s=0;
		flag1s=1;
	}
}

完整源码:

main.c

#include <STC15F2K60S2.H>
#include "configure.h"
#include "onewire.h"
#include "iic.h"
#include "stdio.h"
//****************************
sbit tx = P1^0;
sbit rx = P1^1;
u8 temp_down_t = 0;
u8 smg_down_t = 0;
u8 csb_down_t = 0;
u8 key_down_t = 0;
u8 stoc_down_t = 0;
u8 key_val,key_old,key_down,key_up;//按键读取
u8 mode=1,modepro=1;
//-----
u16 temp;
float Temp_t;//读取温度浮点数保存
u16 distance;//读取距离
u16 bian_cnt = 0;//变动次数
u8 temp_para_t = 30,temp_para = 30;//参数值
u8 dist_para_t = 35,dist_para = 35;
u8 led_state=0xff;//led灯的状态
//----
u8 rx_cnt=0;
xdata u8 rx_buff[12];//放置在xdata,减少ram占用
xdata u8 tx_buff[12];
//-----
bit dac_output=1;//1为启动
bit long_an=0;//长按标志位
bit flag1s=0;//1s标志位
u16 time1s;
//-----
u8 sys_cli=0;//如果为1,10ms计时
u8 uar_10ms=0;//接收中断、串口处理清0,超过10ms没接收数据 即处理指令
//***********Init*****************
void delay(u16 a)
{
	while(a--);
}
void sendbyte(u8 Data)
{
	SBUF = Data;
	while(TI==0);
	TI = 0;
}
void send_string(char* str)//发送字符串
{
	while(*str != '\0')
	{
		sendbyte(*str++);
	}
}
u8 key_read()	//按键响应
{
	u8 temp=0;
	ET0 = 0;
	P35=0;P34=1;
	if(P32 == 0)	temp = 13;
	if(P33 == 0)	temp = 12;
	P35=1;P34=0;
	if(P32 == 0)	temp = 17;
	if(P33 == 0)	temp = 16;
	ET0 = 1;
	return temp;
}
void sendwave()
{
	u8 i;
	for ( i=0; i<8; i++)
	{
		tx = 0;
		Delay14us();
		tx = 1;
		Delay14us();
	}
}
void ds18b20_init()
{
	u8 i;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	for ( i=0; i<8; i++ )
	{
		delay(60000);
	}
}
//+++++++++++Work+++++++++++
//**************************
void uart_work()	//串口处理函数
{
	u8 i=0;
	if(!rx_cnt)		return;
	if(uar_10ms>=10)
	{
		sys_cli = 0;
		uar_10ms = 0;
		if(rx_buff[0]=='S' && rx_buff[1]=='T')
		{
			sprintf(tx_buff,"$%2d,%4.2f\r\n",distance,Temp_t);
		}else if(rx_buff[0]=='P' && rx_buff[1]=='A' && rx_buff[2]=='R' && rx_buff[3]=='A'){
			sprintf(tx_buff,"#%d,%d\r\n",(int)dist_para_t,(int)temp_para_t);
		}else{
			sprintf(tx_buff,"ERROR\r\n");
		}
		send_string(tx_buff);
		for(i=0; i<rx_cnt; i++)
		{
			rx_buff[i] = 0;
			tx_buff[i] = 0;
		}
		rx_cnt = 0;
	}

	
}
void led_work()
{
	if(temp>temp_para_t*100)
	{
		led_state &= 0xfe;
	}else{
		led_state |=~0xfe;
	}
	if(distance<dist_para_t)
	{
		led_state &= 0xfd;
	}else{
		led_state |=~0xfd;
	}
	if(dac_output)
	{
		led_state &= 0xfb;
	}else{
		led_state |=~0xfb;
	}
	HC138_Init(4,led_state);
}
void dac_ouput()		//dac处理函数
{
	u8 Data;
	if(dac_output)
	{
		if(distance<=dist_para_t)
		{
			Data = 102;
		}else{
			Data = 204;
		}
		DA_Output(Data);
	}else{
		DA_Output(20.4);
	}
}
void write_stock()
{
	u8 high,low;
	if(stoc_down_t)	 return;
	stoc_down_t = 1;
	if(mode==1)
	{
		if((temp_para_t!=temp_para)||(dist_para_t!=dist_para)) 
		{
			temp_para_t = temp_para;
			dist_para_t = dist_para;
			bian_cnt++;
			high = (u8)(bian_cnt>>8);
			low  = (u8)bian_cnt;
			at24c02_write(0x01,high);
			at24c02_write(0x00,low);
			Delay5ms();	
		}
	}
}
void dist_read()	//超声波测距
{
	u16 time;
	CMOD = 0x00;
	CH = CL = 0;
	EA = 0;
	sendwave();
	EA = 1; CR=1;
	while (rx && !CF);
	CR = 0;
	if (CF == 0)
	{
		time = CH;
		time = (time<<8)|CL;
		distance = time*0.017;
		if(distance>99)		distance=99;
	}else{
		CF = 0;
		distance = 99;
	}
}
void ds18b20_read()	//温度读取
{
	u8 MSB,LSB;
	u16 Data;
	if(temp_down_t)		return;
	temp_down_t = 1;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	LSB = Read_DS18B20();
	MSB = Read_DS18B20();
	Data = MSB;
	Data = (Data<<8)|LSB;
	if((Data&0xf800) == 0x00)	//判断温度是否大于0摄氏度
	{
		Temp_t = Data*0.0625;
		temp = Temp_t*100;
	}
}
void key_work()		//按键处理函数
{
	u8 high,low;
	if(key_down_t)	return;
	key_down_t = 1;
	key_val = key_read();
	key_down = key_val&(key_val^key_old);//下降沿
	key_up  = ~key_val&(key_val^key_old);
	key_old = key_val;

	if(key_down == 13)
	{
		long_an = 1;
	}
	if(key_up == 13)
	{
		long_an = 0;
		time1s = 0;
		if(!flag1s)
		{
			if(++mode==3)	mode=1;
			modepro = 1;
		}
		if(flag1s)
		{
			flag1s = 0;
			if(dac_output)	dac_output=0;else dac_output=1;
		}
	}
	if(key_down == 12)
	{
		long_an = 1;
	}
	if(key_up == 12)
	{
		long_an = 0;
		time1s = 0;
		if(!flag1s)
		{
			if(mode==1)
			{
				if(++modepro==4)	modepro=1;
			}
			if(mode==2)
			{
				if(++modepro==3)	modepro=1;
			}
		}
		if(flag1s)
		{
			flag1s = 0;
			bian_cnt = 0;
			
			high = (u8)(bian_cnt>>8);
			low  = (u8)bian_cnt;
			at24c02_write(0x01,high);
			at24c02_write(0x00,low);
			Delay5ms();	
		}
	}
	
	if(key_down == 16)	//减
	{
		if(mode==2)
		{
			if(modepro==1)
			{
				if(temp_para>=2)	temp_para -= 2;else temp_para = 0;
			}
			if(modepro==2)
			{
				if(dist_para>=5)	dist_para -= 5;else dist_para = 0;
			}
		}
	}
	if(key_down == 17)
	{
		if(mode==2)
		{
			if(modepro==1)
			{
				if(temp_para<=97)	temp_para += 2;else temp_para = 99;
			}
			if(modepro==2)
			{
				if(dist_para<=94)  dist_para += 5;else dist_para = 99;
			}
		}
	}
}
void smg_work()		//数码管显示函数
{
	static u8 dac=0;
	if(smg_down_t)	return;
	smg_down_t = 1;
	//******
	
	if(++csb_down_t == 25)
	{
		csb_down_t = 0;
		dist_read();
	}
	if(++dac==5)
	{
		dac = 0;
		dac_ouput();
	}
	//******
	if(mode == 1)		//数据界面
	{
		if(modepro == 1)	//温度
		{
			smg_data[0] = 0xc6; smg_data[1] = 0xff;
			smg_data[2] = 0xff; smg_data[3] = 0xff;
			smg_data[4] = SMG_NoDot[temp/1000];
			smg_data[5] = SMG_Dot[temp/100%10];
			smg_data[6] = SMG_NoDot[temp/10%10];
			smg_data[7] = SMG_NoDot[temp%10];
		}
		if(modepro == 2)	//距离
		{
			smg_data[0] = 0xc7; smg_data[1] = 0xff;
			smg_data[2] = 0xff; smg_data[3] = 0xff;
			smg_data[4] = 0Xff; smg_data[5] = 0xff;
			smg_data[6] = SMG_NoDot[distance/10];
			smg_data[7] = SMG_NoDot[distance%10];
		}
		if( modepro == 3)	//变更次数
		{
			smg_data[0] = 0xc8; smg_data[1] = 0xff;
			smg_data[2] = 0xff;
			if(bian_cnt>9999)	smg_data[3] = SMG_NoDot[bian_cnt/10000];else smg_data[3] = 0xff;
			if(bian_cnt>999)	smg_data[4] = SMG_NoDot[bian_cnt/1000%10];else smg_data[4] = 0xff;
			if(bian_cnt>99)		smg_data[5] = SMG_NoDot[bian_cnt/100%10];else smg_data[5] = 0xff;
			if(bian_cnt>9)		smg_data[6] = SMG_NoDot[bian_cnt/10%10];else smg_data[6] = 0xff;
			smg_data[7] = SMG_NoDot[bian_cnt%10];
		}
	}
	if(mode == 2)		//参数界面
	{
		if(modepro == 1)	//温度参数
		{
			smg_data[0] = 0x8c; smg_data[1] = 0xff;
			smg_data[2] = 0xff; smg_data[4] = 0xff;
			smg_data[5] = 0xff;
			smg_data[3] = SMG_NoDot[modepro];
			smg_data[6] = SMG_NoDot[temp_para/10];
			smg_data[7] = SMG_NoDot[temp_para%10];
		}
		if(modepro == 2)	//距离参数
		{
			smg_data[0] = 0x8c; smg_data[1] = 0xff;
			smg_data[2] = 0xff; smg_data[4] = 0xff;
			smg_data[5] = 0xff;
			smg_data[3] = SMG_NoDot[modepro];
			smg_data[6] = SMG_NoDot[dist_para/10];
			smg_data[7] = SMG_NoDot[dist_para%10];
		}
	}
}
void Timer0Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0 = 1;
	EA  = 1;
}
void UartInit(void)		//4800bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设定定时器1为16位自动重装方式
	TL1 = 0xCC;		//设定定时初值
	TH1 = 0xFF;		//设定定时初值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
	EA = 1;
	ES = 1;
}
void system_init()
{
	HC138_Init(4,0xff);
	HC138_Init(5,0x00);
	Timer0Init();
	UartInit();
	ds18b20_init();
}
void main()
{
	system_init();
	while(1)
	{
		ds18b20_read();
		write_stock();
		uart_work();
		key_work();
		smg_work();
	}
}
void Timer_Routine() interrupt 1
{
	if(++smg_down_t == 10)		smg_down_t = 0;
	if(++temp_down_t == 200)		temp_down_t = 0;
	if(++key_down_t == 10)		key_down_t = 0;
	if(++stoc_down_t==25)		stoc_down_t = 0;
	if(long_an)		time1s++;
	
	if(sys_cli)		uar_10ms++;
	
	if(time1s>=1000)
	{
		time1s=0;
		flag1s=1;
	}
	led_work();
	smg_bit();
}
void Uart_Routine() interrupt 4
{
	if(RI==1)
	{
		sys_cli = 1;
		uar_10ms = 0;
		rx_buff[rx_cnt++] = SBUF;
		RI = 0;		
	}
}

configure.c

#include <STC15F2K60S2.H>
#include "intrins.h"
typedef unsigned char u8;
typedef unsigned int u16;

code u8 SMG_NoDot[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
//1   2   3   4   5   6   7   8   9
code u8 SMG_Dot[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
// 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.
u8 smg_data[8]={255,255,255,255,255,255,255,255};

void Delay14us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 38;
	while (--i);
}
void Delay5ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 59;
	j = 90;
	do
	{
		while (--j);
	} while (--i);
}
void HC138_Init(u8 num1,num2)
{
	P2 = P2&0x1f;
	P0 = num2;
	switch(num1)
	{
		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;
	}
	P2 = P2&0x1f;
}
void smg_bit()
{
	static u8 pos=0;
	HC138_Init(7,0xff);
	HC138_Init(6,0x01<<pos);
	HC138_Init(7,smg_data[pos]);
	if(++pos==8)	pos=0;
}

configure.h

#ifndef  __CONFIGURE_H
#define  __CONFIGURE_H

typedef unsigned char u8;
typedef unsigned int u16;

extern code u8 SMG_NoDot[10];
extern code u8 SMG_Dot[10];
extern u8 smg_data[8];

void Delay14us();		//@12.000MHz
void Delay5ms();		//@12.000MHz

void HC138_Init(u8 num1,num2);
void smg_bit();

#endif

iic.c

/*	#   I2C代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <STC15F2K60S2.H>
#include "intrins.h"
#define DELAY_TIME	10
sbit sda=P2^1;
sbit scl=P2^0;

//
static void I2C_Delay(unsigned char n)
{
    do
    {
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();		
    }
    while(n--);      	
}

//
void I2CStart(void)
{
    sda = 1;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 0;
	I2C_Delay(DELAY_TIME);
    scl = 0;    
}

//
void I2CStop(void)
{
    sda = 0;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 1;
	I2C_Delay(DELAY_TIME);
}

//
void I2CSendByte(unsigned char byt)
{
    unsigned char i;
	
    for(i=0; i<8; i++){
        scl = 0;
		I2C_Delay(DELAY_TIME);
        if(byt & 0x80){
            sda = 1;
        }
        else{
            sda = 0;
        }
		I2C_Delay(DELAY_TIME);
        scl = 1;
        byt <<= 1;
		I2C_Delay(DELAY_TIME);
    }
	
    scl = 0;  
}

//
unsigned char I2CReceiveByte(void)
{
	unsigned char da;
	unsigned char i;
	for(i=0;i<8;i++){   
		scl = 1;
		I2C_Delay(DELAY_TIME);
		da <<= 1;
		if(sda) 
			da |= 0x01;
		scl = 0;
		I2C_Delay(DELAY_TIME);
	}
	return da;    
}

//
unsigned char I2CWaitAck(void)
{
	unsigned char ackbit;
	
    scl = 1;
	I2C_Delay(DELAY_TIME);
    ackbit = sda; 
    scl = 0;
	I2C_Delay(DELAY_TIME);
	
	return ackbit;
}

//
void I2CSendAck(unsigned char ackbit)
{
    scl = 0;
    sda = ackbit; 
	I2C_Delay(DELAY_TIME);
    scl = 1;
	I2C_Delay(DELAY_TIME);
    scl = 0; 
	sda = 1;
	I2C_Delay(DELAY_TIME);
}
void DA_Output(unsigned char num)
{
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x40);
	I2CWaitAck();
	I2CSendByte(num);
	I2CWaitAck();
	I2CStop();
}
unsigned char AD_Input(unsigned char addr)
{
	unsigned char Data=0;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	Data = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	return Data;
}
void at24c02_write(unsigned char addr,date)
{
	I2CStart();
	I2CSendByte(0xA0);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	I2CSendByte(date);
	I2CWaitAck();
	I2CStop();
}

iic.h

#ifndef __IIC_H
#define __IIC_H


void I2CStart(void);
void I2CStop(void);
void I2CSendByte(unsigned char byt);
unsigned char I2CReceiveByte(void);
unsigned char I2CWaitAck(void);
void I2CSendAck(unsigned char ackbit);

void DA_Output(unsigned char num);
unsigned char AD_Input(unsigned char addr);
void at24c02_write(unsigned char addr,date);


#endif

onewire.c

/*	# 	单总线代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <STC15F2K60S2.H>
sbit DQ=P1^4;
//
void Delay_OneWire(unsigned int t)  
{
	unsigned char i;
	while(t--){
		for(i=0;i<12;i++);
	}
}

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

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

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

onewire.h

#ifndef __ONEWIRE_H
#define __ONEWIRE_H

void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);



#endif

注:以上自己纯手搓,可能存在部分的问题,希望大家给予指正。

  • 24
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值