⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iicbusc.c

📁 用STC89LE52RC来模拟IIC总线对视频解码芯片SAA7114,多媒体数字信号编码器CS4272等进行初始化
💻 C
字号:
#include "52init.h"
#define iicnop 2
bit     bACK;
sbit	pSDA=P3^6;
sbit	pSCL=P3^7;

void iicdelay(uchar delay_num)  //22.1184 the loop time is 0.543us
   {
    uchar i,k;                //delay_num 8us/num
    for(i=delay_num;i>0;i--)
     {
      for(k=15;k>0;k--)
       {;}
      }
    }
void iicStart()
   {
    uchar i;
    pSDA=1;//发送起始条件的数据信号
    pSCL=1; //发送起始条件的时钟信号
    while(pSCL==0){;}
    for(i=0;i<iicnop;i++){_nop_();}//起始条件建立时间大于0.6us, 延时,看IIC 总线的datasheet 
    pSDA=0;
    for(i=0;i<iicnop;i++){_nop_();}
    pSCL=0;//钳定总线,开始发送数据
    }
void iicStop()
    {
     uchar i;
     pSDA=0;//发送结束条件的数据信号
     pSCL=1;//发送结束条件的时钟信号
     while(pSCL==0){;}
     pSDA=1;
     for(i=0;i<iicnop;i++){_nop_();}
     for(i=0;i<iicnop;i++){_nop_();}
     pSCL=0; 
     }
/**************对IIC总线产生应答******************/
void iicMack()
    {
     uchar i;
     pSDA=0;
     pSCL=1;
     for(i=0;i<iicnop;i++){_nop_();}
     pSCL=0;
     pSDA=1;       
      }
/**************不对IIC总线产生应答*******************/
void iicMnack()
    {
      uchar i;
      pSDA=1;
      pSCL=1;
      for(i=0;i<iicnop;i++){_nop_();}  
      pSCL=0;
      pSDA=0;   
      }
/**************检查应答位*******************/
void iicCack()  //8位发送完后释放数据线,准备接收应答位
     {
       uchar i;
       pSDA=1;
       pSCL=1; //在scl为1的时候等待sda值的变化,在器件接受到数据后会把sda拉低
       bACK=0;
       if(pSDA==0)//当从器件接受到了ack 就会将pSDA 置低
         {
           pSCL=0;
           for(i=0;i<iicnop;i++){_nop_();}            
           }
       else
         {//若pSDA=1表示从器件没有应答,
           bACK=1;//值非应答标志位为1
           pSCL=0;       
           for(i=0;i<iicnop;i++){_nop_();}  
           }
       }
void iicwrbyt0()//向某一位写0
     {
        uchar i;
        pSDA=0;
        pSCL=1;
        for(i=0;i<iicnop;i++){_nop_();} //保证时钟高电平周期大于0.6 μs
        pSCL=0;   //   SCL为低电平时,SDA才能改变 
       }
void iicwrbyt1()//向某一位写1
     {
        uchar i;
        pSDA=1;
        pSCL=1;
        for(i=0;i<iicnop;i++){_nop_();} //保证时钟高电平周期大于0.6 μs
        pSCL=0; //   SCL为低电平时,SDA才能改变
        pSDA=0;     
       }
void iicwrbyt(uchar WrData)//SDA线上的数据必须在时钟的高电平周期保持稳定
      {
        uchar i,j;
        if((WrData&0x80)>0)   //判断发送位是1还是0 ,是1 SDA置1 ,是0 SDA 置0
           {pSDA=1;}
        else
           {pSDA=0;}
        pSCL=1;  //置时钟线为高,通知被控器开始接收数据位
        while(pSCL==0){;}
        for(i=0;i<iicnop;i++){_nop_();}//保证时钟高电平周期大于0.6 μs
        pSCL=0;//SCL为低电平时,SDA才能改变
        pSDA=0;
        WrData=_crol_(WrData,1);
        for(j=1;j<8;j++)
         {
           if((WrData&0x80)>0)
              {iicwrbyt1();}
           else
              {iicwrbyt0();}
           WrData=_crol_(WrData,1);
           }  
        }
uchar iicrdbyt()
     {
       uchar RdData=0xff,j;
       for(j=0;j<8;j++)
         {
          pSDA=1;
          pSCL=1;
          if(pSDA==0)
            {
             RdData=RdData&0x7f;
             RdData=_crol_(RdData,1);
             pSCL=0;
              } 
          else
            {
             RdData=RdData|0x80;
             RdData=_crol_(RdData,1);
             pSCL=0; 
              }
          }
       return(RdData);
       }

void iic24cxxwr(uchar WrAddr,uchar WrData)
     {
	   do{
	      do{ 
             do{
	            iicStart();
		        iicwrbyt(0xa0);
		        iicCack();
	           }while(bACK==1);
		      iicwrbyt(WrAddr);
			  iicCack();
             }while(bACK==1);
		  iicwrbyt(WrData);
		  iicCack();
         }while(bACK==1);
		 iicStop();
	  }
void saa7114wr(uchar addr7114,uchar data7114)
  {
    	do{
		  do{
			 do{
				iicStart();//iic 启动
				iicwrbyt(0x40);//控制字节
				iicCack();//应答信号位,用来告诉发送器,已经收到了这个字节,传输成bACK值为0
			   }while(bACK==1);//如果应答位为1 ,说明接受器没有接受到此信号,数据传输失败
			    iicwrbyt(addr7114);//将要写入字节的地址
			    iicCack();
		    }while(bACK==1);//容错机制
		    iicwrbyt(data7114);//要写入的数据
		    iicCack();
	       }while(bACK==1);//容错机制
	   iicStop();//iic 停止
    }
uchar saa7114rd(uchar addr7114)
   {
     uchar temp;
        do{
		  do{
			 do{
				iicStart();
				iicwrbyt(0x40);//发送SAA7114 写地址
				iicCack();
			   }while(bACK==1);
		      iicwrbyt(addr7114);//发生SAA7114 子地址
			  iicCack();
		     }while(bACK==1);
		    iicStart();//如果是读要重新启动IIC 总线
		    iicwrbyt(0x41);//发送SAA7114 读地址
			iicCack();
	       }while(bACK==1);
	    temp=iicrdbyt();
	    iicStop();
	    return(temp);
     }
void saa7121wr(uchar addr7121,uchar data7121)
   {
       	do{
		  do{
			 do{
				iicStart();
				iicwrbyt(0x88);
				iicCack();
			    }while(bACK==1);
			    iicwrbyt(addr7121);
			    iicCack();
		      }while(bACK==1);
		    iicwrbyt(data7121);
		    iicCack();
	       }while(bACK==1);
	   iicStop();
     }
uchar saa7121rd(uchar addr7121)
   {
       uchar temp;
        do{
		  do{
			 do{
				iicStart();
				iicwrbyt(0x88);
				iicCack();
			   }while(bACK==1);
		      iicwrbyt(addr7121);
		   	  iicCack();
		     }while(bACK==1);
		      iicStart();
		      iicwrbyt(0x89);
			  iicCack();
	       }while(bACK==1);
	    temp=iicrdbyt();
	    iicStop();
	    return(temp);   
     }
void iic4272wr(uchar WrAddr,uchar WrData)
     {
	  	do{
		  do{
			 do{
				iicStart();
				iicwrbyt(0x20);
				iicCack();
			   }while(bACK==1);
			    iicwrbyt(WrAddr);
			    iicCack();
		    }while(bACK==1);
		    iicwrbyt(WrData);
		    iicCack();
	       }while(bACK==1);
	   iicStop();
	  }
uchar iic4272rd(uchar RdAddr)
     {
	  	uchar temp;
        do{
		  do{
			 do{
				iicStart();
				iicwrbyt(0x20);
				iicCack();
			   }while(bACK==1);
		      iicwrbyt(RdAddr);
			  iicCack();
		     }while(bACK==1);
		    iicStart();
		    iicwrbyt(0x21);
			iicCack();
	       }while(bACK==1);
	    temp=iicrdbyt();
	    iicStop();
	    return(temp);
	   }




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -