zoukankan      html  css  js  c++  java
  • 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);                                                             //保持循环直到字符为''
    }
    
    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;
    }
    












  • 相关阅读:
    LIGHTSWITCH 的树控件设计!
    企业即时通信平台与在线办公!
    特殊符号网 http://www.teshufuhao.net/
    国内主要工作流厂商分析 (转)
    衣联网 http://www.eelly.com/ 中国最大的专业服装批发市场(广州)
    NET FrameWork & CLR & C# 运行基本原理
    通过负载均衡器+域名实现容灾切换(2)DNS解析过程理解
    SPAN和RSPAN概念
    【转】一张图看懂开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别
    SIP Recording(录制)相关协议
  • 原文地址:https://www.cnblogs.com/riskyer/p/3339401.html
Copyright © 2011-2022 走看看