蓝桥杯-官方驱动修改

 其中//************************************      ***************************//包围的为添加的内容。


//DS1302时钟芯片驱动
//sbit SCLK = P1^7;
//sbit IO   = P2^3;
//sbit RST  = P1^3;

//写入数据之前要进行转换,否则会乱码
//*********************重点     //  十进制转换位BCD码
//num = (date/10<<4)|(date%10); //
//*********************重点     //

//读出数据也要进行转换,否则会乱码
//****************重点        //  BCD码转换位十进制
//dat1 = dat/16;     //
//dat2 = dat%16;     //
//dat = dat1*10+dat2;//
//*******************************************
//须在此语句后面加上IO=0;不然无法使用********
//*******************************************
//***************重点        //

//写入数据在偶数数据地址
//读出数据在奇数数据地址
//每次写入都要关闭读写保护  0x8e,0x00
//每次写完都要打开读写保护  0x8e,0x80

 

#ifndef __DS1302_H
#define __DS1302_H

#include<STC15F2K60S2.H>
#include<intrins.h>
	
sbit SDA=P1^3;
sbit RST=P2^3;
sbit SCK=P1^7;

unsigned char read(unsigned char add);
void writebyte(unsigned char dat);
void write(unsigned char add,unsigned char dat);
extern unsigned char TIME[7];	//加入全局变量

//**********************************
void DS1302_read_process();
void DS1302_write_process();
extern unsigned char ds1302_time[7];
//**********************************
#endif




//**************************************************************************************





#include "DS1302.h"

unsigned char TIME[7]={50,59,23,12,3,2,19};
                     //秒 分 时 天 月 周 年
unsigned char code write_add[7]={0X80,0X82,0X84,0X86,0X88,0X8A,0X8C};

unsigned char code read_add[7]={0X81,0X83,0X85,0X87,0X89,0X8b,0X8d};

unsigned char ds1302_time[7];   //接收时间

unsigned char read(unsigned char add)
{
	unsigned char i,temp,dat1,dat2;
	SDA=0;
	SCK=0;
	SDA=1;
	writebyte(add);
	for(i=0;i<8;i++)
	{
		SCK=0;
		temp>>=1;
		if(RST) temp|=0x80;
		SCK=1;
	}
	
	RST=0;
	
	dat1=temp/16;//0XFF 1111 1111
	dat2=temp%16;
	
	temp=dat1*10+dat2;
	
	return temp;
}

void writebyte(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		SCK=0;
		RST=dat&0x01;
		SCK=1;
		dat>>=1;
	}
}

void write(unsigned char add,unsigned char dat)
{
	unsigned char num;
	SDA=0;
	SCK=0;
	SDA=1;
	writebyte(add);
	num=(dat/10<<4)|(dat%10);// 55
	writebyte(num);
	SDA=0;
}
//**************************************
//**************************************
void DS1302_write_process()
{
	unsigned char i;
	write(0x8e,0x00);
	
	for(i=0;i<8;i++)
	{
		write(write_add[i],TIME[i]);
	}
	
	write(0x8e,0x80);
}
//
void DS1302_read_process()
{
	unsigned char i;
	write(0x8e,0x00);
	
	for(i=0;i<8;i++)
	{
		ds1302_time[i] = read(read_add[i]);
	}
	
	write(0x8e,0x80);
}
//**************************************
//**************************************

 其中//************************************      ***************************//包围的为添加的内

 

//DS18B20温度传感器驱动
//读取的温度需要用uint类型。
//sbit DQ = P1^4;
//延迟函数需要修改。
//需要注意DS18B20初始化时的时序延迟。

 

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

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

//******************************
unsigned int get_wendu();
//******************************
#endif




//***************************************************************************************




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

#include "onewire.h"

//单总线延时函数
void Delay_OneWire(unsigned int t)
{
	unsigned char 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 get_wendu()
{
	unsigned int date;
	unsigned char low,high;
	Init_DS18B20();
	Write_DS18B20(0xcc);   //跳过度序列号,说明只有一个DS18B20.
	Write_DS18B20(0x44);   //启动温度转换
	
	Init_DS18B20();
	Write_DS18B20(0xcc);   //跳过度序列号,说明只有一个DS18B20.
	Write_DS18B20(0xbe);   //发送读数据指令
	
	low  = Read_DS18B20();    //先接收低位
	high = Read_DS18B20();   //后接收高位
	
	date = high;//精准度为0.0625。也可以再乘以10以扩大显示。111*0.0625=6.9735    200*0.0625=12.5000
	date<<=8;//乘以十也可以设置精确到小数点后的位数,*10为小数点后1位   *100为小数点后2位
	date = date|low;
	date = (date*0.0625);
	return date;
}
//************************************
//************************************

 

其中//************************************      ***************************//包围的为添加的内容。

/I2C总线驱动
//sbit SCL = P2^0;
//sbit SDA = P2^1;

//add = 0xa0;0xa1为读取数据  为EEPROM的地址,cmd为存储地址,dat为存储数据
//add = 0x90;0x91为读取数据  为PCF8591A/D.D/A的地址,
//D7     未用写0
//D6     0为禁止D/A,1为允许D/A
//D5.D4  通常为00
//D3     未用写0
//D2     自动增益为通常为0,1也可以,无影响
//D1.D0  A/D通道选择,00为通道0,01为通道1,10为通道2,11为通道3。
//如果启用D/A转换,则只用write函数cmd = 0x40; dat为写入数据
//如果启用A/D转换,则只用read函数cmd为A/D转换通道,0x00;0x01;0x02;0x03;
//0x03为滑动变阻器Rb2,0x01为光敏电阻

 

#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_();}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

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

//函数声明
bit IIC_WaitAck(void);  
void IIC_Start(void); 
void IIC_Stop(void);  
void IIC_Ack(unsigned char ackbit); 
void IIC_SendByte(unsigned char byt); 
unsigned char IIC_RecByte(void); 

//******************************************************************************
unsigned char IIC_read_process(unsigned char addr,unsigned char cmd);
void IIC_write_process(unsigned char addr,unsigned char cmd,unsigned char date);
//******************************************************************************

#endif






//***************************************************************************************




/*
  程序说明: 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_process(unsigned char addr,unsigned char cmd,unsigned char date)
{
	IIC_Start();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_SendByte(cmd);
	IIC_WaitAck();
	IIC_SendByte(date);
	IIC_WaitAck();
	IIC_Stop();
}
//
unsigned char IIC_read_process(unsigned char addr,unsigned char cmd)
{
	unsigned char date;
	
	IIC_Start();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_SendByte(cmd);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(addr+1);
	IIC_WaitAck();
	date = IIC_RecByte();
	IIC_WaitAck();
	IIC_Stop();
	
	return date;
}
//*************************************
//*************************************

个人见解,感谢阅读。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值