51操作各种demo 驱动


24C02

 

bit  write=0;           //写24C02的标志;

sbit sda=P2^0;                         

sbit scl=P2^1;

void delay0()

{ ;; }

void start()  //开始信号

{	

	sda=1;

	delay0();

	scl=1;

	delay0();

	sda=0;

	delay0();

}

void stop()   //停止

{

	sda=0;

	delay0();

	scl=1;

	delay0();

	sda=1;

	delay0();

}

void respons()  //应答

{

	uchar i;

	scl=1;

	delay0();

	while((sda==1)&&(i<250))i++;

	scl=0;

	delay0();

}

void init_24c02()//IIC初始化函数

{

	sda=1;

	delay0();

	scl=1;

	delay0();

}

void write_byte(uchar date)//写一个字节函数

{

	uchar i,temp;

	temp=date;

	for(i=0;i<8;i++)

	{

		temp=temp<<1;

		scl=0;

	    delay0();

		sda=CY;

		delay0();

		scl=1;

		delay0();

	}

	scl=0;

	delay0();

	sda=1;

	delay0();

}

uchar read_byte()//读一个字节函数

{

	uchar i,k;

	scl=0;

	delay0();

	sda=1;

	delay0();

	for(i=0;i<8;i++)

	{

		scl=1;

		delay0();	

		k=(k<<1)|sda;

		scl=0;

		delay0();	

	}

	return k;

}

void write_add(uchar address,uchar date)//指定地址写一个字节

{

	start();

	write_byte(0xa0);

	respons();

	write_byte(address);

	respons();

	write_byte(date);

	respons();

	stop();

}

char read_add(uchar address)//指定地址读一个字节

{

	uchar date;

	start();

	write_byte(0xa0);

	respons();

	write_byte(address);

	respons();

	start();

	write_byte(0xa1);

	respons();

	date=read_byte();

	stop();

	return date;

}

 

DS12C887

 

 

#include<reg52.h>

#include<define.h>

void delay(uint z)//延时函数

{

	uint x,y;

	for(x=z;x>0;x--)

		for(y=110;y>0;y--);

}

void di() //蜂鸣器报警声音

{

	beep=0;

	delay(100);

	beep=1;

}

void write_com(uchar com)

{//写液晶命令函数

	rs=0;

	lcden=0;

	P0=com;

	delay(3);

	lcden=1;

	delay(3);

	lcden=0;	

}

void write_date(uchar date)

{//写液晶数据函数

	rs=1;

	lcden=0;

	P0=date;

	delay(3);

	lcden=1;

	delay(3);

	lcden=0;	

}

void init()

{//初始化函数

	uchar num;

	EA=1;//打开总中断

	EX1=1;//开外部中断1

	IT1=1;//设置负跳变沿触发中断

	flag1=0;//变量初始化

	t0_num=0;

	s1num=0;

	week=1;

	dula=0;//关闭数码管显示

	wela=0;

	lcden=0;

	rd=0;

/*以下几行在首次设置DS12C887时使用,以后不必再写入

	write_ds(0x0A,0x20);//打开振荡器

	write_ds(0x0B,0x26);//设置24小时模式,数据二进制格式

						//开启闹铃中断

	set_time();//设置上电默认时间

-----------------------------------------------------*/

	write_com(0x38);//1602液晶初始化

	write_com(0x0c);

	write_com(0x06);

	write_com(0x01);

	write_com(0x80);

	for(num=0;num<15;num++)//写入液晶固定部分显示

		{

			write_date(table[num]);

			delay(1);

		}

	write_com(0x80+0x40);

	for(num=0;num<11;num++)

		{

			write_date(table1[num]);

			delay(1);

		}

}

void write_sfm(uchar add,char date)

{//1602液晶刷新时分秒函数4为时,7为分,10为秒

	char shi,ge;

	shi=date/10;

	ge=date%10;

	write_com(0x80+0x40+add);

	write_date(0x30+shi);

	write_date(0x30+ge);

}

void write_nyr(uchar add,char date)

{//1602液晶刷新年月日函数3为年,6为分,9为秒

	char shi,ge;

	shi=date/10;

	ge=date%10;

	write_com(0x80+add);

	write_date(0x30+shi);

	write_date(0x30+ge);

}

void write_week(char we)

{//写液晶星期显示函数

	write_com(0x80+12);

	switch(we)

	{

		case 1:	write_date('M');delay(5);

				write_date('O');delay(5);

				write_date('N');

				break;

		case 2:	write_date('T');delay(5);

				write_date('U');delay(5);

				write_date('E');

				break;

		case 3:	write_date('W');delay(5);

				write_date('E');delay(5);

				write_date('D');

				break;

		case 4:	write_date('T');delay(5);

				write_date('H');delay(5);

				write_date('U');

				break;

		case 5:	write_date('F');delay(5);

				write_date('R');delay(5);

				write_date('I');

				break;

		case 6:	write_date('S');delay(5);

				write_date('A');delay(5);

				write_date('T');

				break;

		case 7:	write_date('S');delay(5);

				write_date('U');delay(5);

				write_date('N');

				break;

	}

}

void keyscan()

{

	if(flag_ri==1)

	{//这里用来取消闹钟报警,任一键取消报警

		if((s1==0)||(s2==0)||(s3==0)||(s4==0))

		{	

			delay(5);

			if((s1==0)||(s2==0)||(s3==0)||(s4==0))

			{

				while(!(s1&&s2&&s3&&s4));

                di();

				flag_ri=0;//清除报警标志

			}	 	

		}

	}	

	if(s1==0)//检测S1

	{

		delay(5);

		if(s1==0)

		{	

			s1num++;//记录按下次数

			if(flag1==1)

				if(s1num==4)

					s1num=1;

			flag=1;

			while(!s1);di();

			switch(s1num)

			{//光标闪烁点定位

				case 1: write_com(0x80+0x40+10);

					    write_com(0x0f);

						break;

				case 2: write_com(0x80+0x40+7);

						break;

				case 3: write_com(0x80+0x40+4);

						break;

				case 4: write_com(0x80+12);

						break;

				case 5: write_com(0x80+9);

						break;

				case 6: write_com(0x80+6);

						break;

				case 7: write_com(0x80+3);

						break;

				case 8: s1num=0;

						write_com(0x0c);

						flag=0;

						write_ds(0,miao);

						write_ds(2,fen);

						write_ds(4,shi);

						write_ds(6,week);

						write_ds(7,day);

						write_ds(8,month);

						write_ds(9,year);

						break;

			}	

		}

	}

	if(s1num!=0)//只有当S1按下后,才检测S2和S3

	{

		if(s2==0)

		{

			delay(1);

			if(s2==0)

			{

				while(!s2);di();

				switch(s1num)

				{//根据功能键次数调节相应数值

					case 1:	miao++;

							if(miao==60)

								miao=0;

							write_sfm(10,miao);

							write_com(0x80+0x40+10); 

							break;

					case 2:	fen++;

							if(fen==60)

								fen=0;

							write_sfm(7,fen);

							write_com(0x80+0x40+7); 

							break;

					case 3:	shi++;

							if(shi==24)

								shi=0;

							write_sfm(4,shi);

							write_com(0x80+0x40+4); 

							break;

					case 4:	week++;

							if(week==8)

								week=1;

							write_week(week);

							write_com(0x80+12);

							break;

					case 5:	day++;

							if(day==32)

								day=1;

							write_nyr(9,day);

							write_com(0x80+9);

							break;

					case 6:	month++;

							if(month==13)

								month=1;

							write_nyr(6,month);

							write_com(0x80+6);

							break;

					case 7:	year++;

							if(year==100)

								year=0;

							write_nyr(3,year);

							write_com(0x80+3);

							break;

				}

			}

		}

		if(s3==0)

		{

			delay(1);

			if(s3==0)

			{

				while(!s3);di();

				switch(s1num)

				{//根据功能键次数调节相应数值

					case 1:	miao--;

							if(miao==-1)

								miao=59;

							write_sfm(10,miao);

							write_com(0x80+0x40+10);

							break; 

					case 2:	fen--;

							if(fen==-1)

								fen=59;

							write_sfm(7,fen);

							write_com(0x80+0x40+7);

							break;

					case 3:	shi--;

							if(shi==-1)

								shi=23;

							write_sfm(4,shi);

							write_com(0x80+0x40+4);

							break;

					case 4:	week--;

							if(week==0)

								week=7;

							write_week(week);

							write_com(0x80+12);

							break;

					case 5:	day--;

							if(day==0)

								day=31;

							write_nyr(9,day);

							write_com(0x80+9);

							break;

					case 6:	month--;

							if(month==0)

								month=12;

							write_nyr(6,month);

							write_com(0x80+6);

							break;

					case 7:	year--;

							if(year==-1)

								year=99;

							write_nyr(3,year);

							write_com(0x80+3);

							break;

				}

			}

		}

	}

	if(s4==0)//检测S4

	{

		delay(5);

		if(s4==0)

		{	

			flag1=~flag1;

			while(!s4);di();

			if(flag1==0)

			{//退出闹钟设置时保存数值

				flag=0;

				write_com(0x80+0x40);

				write_date(' ');

				write_date(' ');

				write_com(0x0c);

				write_ds(1,miao);

				write_ds(3,fen);

				write_ds(5,shi);				

			}

			else

			{//进入闹钟设置

				read_alarm();//读取原始数据

				miao=amiao;//重新赋值用以按键调节

				fen=afen;

				shi=ashi;

				write_com(0x80+0x40);

				write_date('R');//显示标志

				write_date('i');

				write_com(0x80+0x40+3);

				write_sfm(4,ashi);//送液晶显示闹钟时间

				write_sfm(7,afen);

				write_sfm(10,amiao);

			}			

		}

	}

}



void write_ds(uchar add,uchar date)

{//写12C887函数

	dscs=0;

	dsas=1;

	dsds=1;

	dsrw=1;

	P0=add;//先写地址

	dsas=0;

	dsrw=0;

	P0=date;//再写数据

	dsrw=1;

	dsas=1;

	dscs=1;				

}



uchar read_ds(uchar add)

{//读12C887函数

 	uchar ds_date;

	dsas=1;

	dsds=1;

	dsrw=1;

	dscs=0;

	P0=add;//先写地址

	dsas=0;

	dsds=0;

	P0=0xff;

	ds_date=P0;//再读数据

	dsds=1;

	dsas=1;

	dscs=1;

	return ds_date;	

}

/*---首次操作12C887时给予寄存器初始化---

void set_time()

{//首次上电初始化时间函数

	write_ds(0,0);

	write_ds(1,0);

	write_ds(2,0);

	write_ds(3,0);

	write_ds(4,0);

	write_ds(5,0);

	write_ds(6,0);

	write_ds(7,0);

	write_ds(8,0);

	write_ds(9,0);	

}

----------------------------------------*/

void read_alarm()

{//读取12C887闹钟值

	amiao=read_ds(1);

	afen=read_ds(3);

	ashi=read_ds(5);

}

void main()//主函数

{

	init();//调用初始化函数

	while(1)

	{

		keyscan();//按键扫描

		if(flag_ri==1)//当闹钟中断时进入这里

		{

			di();

			delay(100);

			di();

			delay(500);

		}	

		if(flag==0&&flag1==0)//正常工作时进入这里

		{

			keyscan();//按键扫描

			year=read_ds(9);//读取12C887数据

			month=read_ds(8);	

			day=read_ds(7);

			week=read_ds(6);

			shi=read_ds(4);

			fen=read_ds(2);

			miao=read_ds(0);	

			write_sfm(10,miao);//送液晶显示

			write_sfm(7,fen);

			write_sfm(4,shi);

			write_week(week);

			write_nyr(3,year);

			write_nyr(6,month);

			write_nyr(9,day);

		}

	}

}



void exter() interrupt 2//外部中断1服务程序

{	uchar c; //进入中断表示闹钟时间到,

	flag_ri=1; //设置标志位,用以大程序中报警提示

	c=read_ds(0x0c);//读取12C887的C寄存器表示响应了中断

}





 

DS18B20

 

 

#include <reg52.h>

#include <stdio.h>

#define  uchar unsigned char

#define  uint  unsigned int

sbit ds=P2^2;     //温度传感器信号线

sbit dula=P2^6;   //数码管段选线

sbit wela=P2^7;   //数码管位选线

sbit beep=P2^3;   //蜂鸣器



uint temp;

float f_temp;

uint warn_l1=260;

uint warn_l2=250;

uint warn_h1=300;

uint warn_h2=320;



sbit led0=P1^0;

sbit led1=P1^1;

sbit led2=P1^2;

sbit led3=P1^3;



unsigned char code table[]={

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0xbf,0x86,

0xdb,0xcf,0xe6,0xed,

0xfd,0x87,0xff,0xef};     //不带小数点的编码



void delay(uint z)//延时函数

{

	uint x,y;

	for(x=z;x>0;x--)

		for(y=110;y>0;y--);

}







void dsreset(void)    //18B20复位,初始化函数

{

  uint i;

  ds=0;

  i=103;

  while(i>0)i--;

  ds=1;

  i=4;

  while(i>0)i--;

}



bit tempreadbit(void)   //读1位函数

{

   uint i;

   bit dat;

   ds=0;i++;          //i++ 起延时作用

   ds=1;i++;i++;

   dat=ds;

   i=8;while(i>0)i--;

   return (dat);

}



uchar tempread(void)   //读1个字节

{

  uchar i,j,dat;

  dat=0;

  for(i=1;i<=8;i++)

  {

    j=tempreadbit();

    dat=(j<<7)|(dat>>1);   //读出的数据最低位在最前面,这样刚好一个字节在DAT里

  }

  return(dat);

}



void tempwritebyte(uchar dat)   //向18B20写一个字节数据

{

  uint i;

  uchar j;

  bit testb;

  for(j=1;j<=8;j++)

  {

    testb=dat&0x01;

    dat=dat>>1;

    if(testb)     //写 1

    {

      ds=0;

      i++;i++;

      ds=1;

      i=8;while(i>0)i--;

    }

    else

    {

      ds=0;       //写 0

      i=8;while(i>0)i--;

      ds=1;

      i++;i++;

    }



  }

}



void tempchange(void)  //DS18B20 开始获取温度并转换

{

  dsreset();

  delay(1);

  tempwritebyte(0xcc);  // 写跳过读ROM指令

  tempwritebyte(0x44);  // 写温度转换指令

}



uint get_temp()         //读取寄存器中存储的温度数据

{

  uchar a,b;



  dsreset();

  delay(1);

  tempwritebyte(0xcc);

  tempwritebyte(0xbe);

  a=tempread();         //读低8位

  b=tempread();         //读高8位

  temp=b;

  temp<<=8;            //两个字节组合为1个字

  temp=temp|a;

  f_temp=temp*0.0625;      //温度在寄存器中为12位 分辨率位0.0625°

  temp=f_temp*10+0.5;    //乘以10表示小数点后面只取1位,加0.5是四舍五入

  f_temp=f_temp+0.05; 

  return temp;         //temp是整型

}





////////////////////显示程序//////////////////////////

void display(uchar num,uchar dat)

{

  uchar i;

  dula=0;

  P0=table[dat];

  dula=1;

  dula=0;



  wela=0;

  i=0XFF;

  i=i&(~((0X01)<<(num)));

  P0=i;

  wela=1;

  wela=0;    

  delay(1);

}



void dis_temp(uint t)

{

  uchar i;

  i=t/100;

  display(0,i);

  i=t%100/10;

  display(1,i+10);

  i=t%100%10;

  display(2,i);

}

//////////////////////////////////////////////

void warn(uint s,uchar led)   //蜂鸣器报警声音 ,s控制音调

{

    uchar i;i=s;

    dula=0;

    wela=0;

 

	beep=0;

    P1=~(led);

    while(i--)

    {

      dis_temp(get_temp());

    }   

	beep=1;

    P1=0XFF;  

    i=s;  

     while(i--)

    {

      dis_temp(get_temp());

    }  

}

void deal(uint t)

{

  uchar i;

  if((t>warn_l2)&&(t<=warn_l1)) //大于25度小于27度

	{

       warn(40,0x01);

       

	}

  else if(t<=warn_l2)                   //小于25度 

	{

       warn(10,0x03);

	}

  else if((t<warn_h2)&&(t>=warn_h1)) //小于32度大于30度

    {

       warn(40,0x04);

	}

  else if(t>=warn_h2)                   //大于32度

	{

       warn(10,0x0c);

	}

  else

    {

       i=40;

       while(i--)

       {

        dis_temp(get_temp());

       } 

    }

}



void init_com(void)

{

     TMOD = 0x20;

     PCON = 0x00;

     SCON = 0x50;

     TH1 = 0xFd;

     TL1 = 0xFd;

     TR1 = 1;

}



void comm(char *parr)         

{

	do

	{

	 SBUF = *parr++;                                                           //发送数据                          

     while(!TI);                                                               //等待发送完成标志为1

	 TI =0;                                                                    //标志清零

	}while(*parr);                                                             //保持循环直到字符为'\0'

}



void main()

{

  uchar buff[4],i;

  dula=0;

  wela=0;

  init_com();

  while(1)

 {    

      tempchange();

      for(i=10;i>0;i--)

     {

      dis_temp(get_temp());}

      deal(temp); 



      sprintf(buff,"%f",f_temp);



    for(i=10;i>0;i--)

     {

      dis_temp(get_temp());}



      comm(buff);



     for(i=10;i>0;i--)

     {

      dis_temp(get_temp());}

    

 }

}

 

EEPROM

 

 

/*

extern void SectorErase(uint sector_addr);	// 扇区擦除

extern uchar byte_read(uint byte_addr);		// byte读

extern void byte_write(uint byte_addr, uchar original_data);	// byte写

extern uchar byte_write_verify(uint byte_addr, uchar original_data);// byte写并校验

extern uchar ArrayWrite(uint begin_addr, uint len, uchar code *array);	// byte数组写并校验

extern void ArrayRead(uint begin_addr, uchar len);		// 读出, 保存在Ttotal[]中

*/

#define RdCommand		0x01

#define PrgCommand		0x02

#define EraseCommand     	0x03

#define Error   1

#define Ok      0

#define WaitTime	0x01

#define PerSector		512

/* ================ 打开 ISP,IAP 功能 ================= */

void ISP_IAP_enable(void)

{

	EA	=	0;							/* 关中断 		*/

	ISP_CONTR =	ISP_CONTR & 0x18;       /* 0001,1000	*/

	ISP_CONTR =	ISP_CONTR | WaitTime;	/* 写入硬件延时	*/

	ISP_CONTR =	ISP_CONTR | 0x80;       /* ISPEN=1		*/

}

/* =============== 关闭 ISP,IAP 功能 ================== */

void ISP_IAP_disable(void)

{

	ISP_CONTR	=	ISP_CONTR & 0x7f;	/* ISPEN = 0 */

	ISP_TRIG	=	0x00;

	EA			=   1;			/* 开中断 */

}

/* ================ 公用的触发代码 ==================== */

void ISPgoon(void)

{

	ISP_IAP_enable();			/* 打开 ISP,IAP 功能	*/

	ISP_TRIG	=	0x46;		/* 触发ISP_IAP命令字节1	*/

	ISP_TRIG	=	0xb9;		/* 触发ISP_IAP命令字节2	*/

	_nop_();

}

/* ==================== 字节读 ======================== */

unsigned char byte_read(unsigned int byte_addr)

{

	ISP_ADDRH = (unsigned char)(byte_addr >> 8);	/* 地址赋值	*/

	ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);



	ISP_CMD   = ISP_CMD	& 0xf8;			/* 清除低3位 	*/

	ISP_CMD   = ISP_CMD	| RdCommand;	/* 写入读命令	*/



	ISPgoon();							/* 触发执行		*/

	ISP_IAP_disable();				/* 关闭ISP,IAP功能	*/



	return (ISP_DATA);				/* 返回读到的数据	*/

}

/* ================== 扇区擦除 ======================== */

void sectorerase(unsigned int sector_addr)

{

	unsigned int iSectorAddr;

	iSectorAddr = (sector_addr & 0xfe00); /* 取扇区地址 */

	ISP_ADDRH = (unsigned char)(iSectorAddr >> 8);

	ISP_ADDRL = 0x00;



	ISP_CMD	= ISP_CMD & 0xf8;			/* 清空低3位 	*/

	ISP_CMD	= ISP_CMD | EraseCommand;	/* 擦除命令3 	*/



	ISPgoon();							/* 触发执行		*/

	ISP_IAP_disable();				/* 关闭ISP,IAP功能	*/



}

/* ==================== 字节写 ======================== */

void byte_write(unsigned int byte_addr, unsigned char original_data)

{

	ISP_ADDRH =	(unsigned char)(byte_addr >> 8); 	/* 取地址 	*/

	ISP_ADDRL =	(unsigned char)(byte_addr & 0x00ff);



	ISP_CMD	 = ISP_CMD & 0xf8;				/* 清低3位	*/

	ISP_CMD  = ISP_CMD | PrgCommand;		/* 写命令2	*/

	ISP_DATA = original_data;			/* 写入数据准备	*/



	ISPgoon();							/* 触发执行		*/

	ISP_IAP_disable();					/* 关闭IAP功能	*/

}

void write_eep(float eep_data,uint add)

{

	uchar fcdh,fcdl;

	fcdh=(uint)(eep_data*100)/256;

	fcdl=(uint)(eep_data*100)%256;

	byte_write(add,fcdh);//写入浮充电电压高8位

	byte_write(add+1,fcdl);//写入浮充电电压低8位

}

float read_eep(uint add)

{

	float date_re;

	uchar dateh,datel;

	dateh=byte_read(add);

	datel=byte_read(add+1);

	date_re=(dateh*256+datel)/100.0;

	return date_re;

}


 











 

你可能感兴趣的:(demo)