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

📄 per.c

📁 对显示器LCD的读写和I2C的控制程序
💻 C
字号:
#include  "config.h"


uint8  I2C_sla;           // 从机地址
uint8  I2C_suba;          // 子地址
uint8  *I2C_buf;          // 数据缓冲区指针 (读操作时会被更改)
uint8  I2C_num;           // 操作数据个数 (会被更改)
uint8  I2C_end;           // 操作结束标志,为1时表示操作结束,为0xFF时表示操作失败 (会被设置)
uint8  I2C_suba_en;       // 子地址使能控制,读操作时请设置为1,写操作时请设置为2 (会被更改)


void  __irq  IRQ_I2C(void)
{  uint8  sta;

   sta = I2STAT;                    // 读出I2C状态字
   switch(sta)
   {  case  0x08://B00001000                   // 己发送起始条件
            if(1==I2C_suba_en) I2DAT = I2C_sla&0xFE;    // 指定子地址读时,先写入地址
              else I2DAT = I2C_sla;                     // 否则直接发送从机地址
            I2CONCLR = 0x28;        // SI=0,STA=0
            break;
            
      case  0x10://B00010000
            I2DAT = I2C_sla;        // 重启动总线后,发送从地址
            I2CONCLR = 0x28;        // SI=0,STA=0
            break;
   
      case  0x18://B00011000                   // 已发送SLA+W,并已接收应答
            if(0==I2C_suba_en)      // 无子地址,则直接发送数据
            {  if(I2C_num>0)
               {  I2DAT = *I2C_buf++;
                  I2CONCLR = 0x28; 
                  I2C_num--;
               }
               else
               {  I2CONSET = 0x10;  // 无数据发送,结束总线
                  I2CONCLR = 0x28;  // SI=0,STA=0
                  I2C_end = 1;      // 设置总线操作结束标志
               }
               break;
            }
            if(1==I2C_suba_en)      // 发送子地址
            {  I2DAT = I2C_suba;
               I2CONCLR = 0x28;     // SI=0,STA=0
            }
            if(2==I2C_suba_en)
            {  I2DAT = I2C_suba;
               I2CONCLR = 0x28;     // SI=0,STA=0
               I2C_suba_en = 0;     // 子地址己处理
            }
            break;
            
      case  0x28: //B00101000                  // 已发送I2C数据,并接收到应答
            if(0==I2C_suba_en)      // 无子地址,则直接发送数据
            {  if(I2C_num>0)
               {  I2DAT = *I2C_buf++;
                  I2CONCLR = 0x28;   // SI=0,STA=0
                  I2C_num--;
               }
               else
               {  I2CONSET = 0x10;  // 无数据发送,结束总线
                  I2CONCLR = 0x28;  // SI=0,STA=0
                  I2C_end = 1; 
               }
               break;
            }
            if(1==I2C_suba_en)      // 若是指定地址读,则重新启动总线
            {  I2CONSET = 0x20;
               I2CONCLR = 0x08;      // SI=0,STA=0
               I2C_suba_en = 0;     // 子地址己处理
            }
            break;
   
   
      case  0x20://B00100000
      case  0x30://B00110000
      case  0x38://B00111000
            I2CONCLR = 0x28;        // 总线进入不可寻址从模式
            I2C_end = 0xFF;         // 总线出错,设置标志
            break;
   
   
      case  0x40://B01000000                   // 己发送SLA+R,并已接收到应答
            if(1==I2C_num)          // 最后一字节,接收数据后发送非应答信号
            {  I2CONCLR = 0x2C;     // AA=0,接收到数据后产生非应答
            }
            else                    // 接收数据并发送应答信号
            {  I2CONSET = 0x04;     // AA=1,接收到数据后产生应答
               I2CONCLR = 0x28;
            }
            break;
            
      case  0x50://01010000
            *I2C_buf++ = I2DAT;     // 读取数据
            I2C_num--;
            if(1==I2C_num)
            {  I2CONCLR = 0x2C;     // AA=0,接收到数据后产生非应答
            }
            else
            {  I2CONSET = 0x04;     // AA=1,接收到数据后产生应答
               I2CONCLR = 0x28;
            }
            break;
      
      case  0x58://01011000
            *I2C_buf++ = I2DAT;     // 读取最后一字节数据
            I2CONSET = 0x10;        // 结束总线
            I2CONCLR = 0x28;
            I2C_end = 1; 
            break;
      
      case  0x48://01001000
            I2CONCLR = 0x28;        // 总线进入不可寻址从模式
            I2C_end = 0xFF; 
            break;
            
      default: 
            break;
   }
   

   VICVectAddr = 0x00;              // 中断处理结束
}

void DelayNS(uint32 dly)
{
	uint32 i;uint32 j;
	for(j=0;j<dly;j++)
	{
		for(i=0;i<9;i++);
	}
}



void UART0_SendByte(uint8 data)
{
  while((U0LSR&0x40)==0)
  U0THR=data;
 }


uint8 ISendStr(uint8 suba, uint8 *s, uint8 num)
{
  I2C_suba=suba;
  I2C_sla=0xa0;
  I2C_num=num;
  I2C_buf=s;
  I2C_suba_en=2;
  I2C_end=0;

  I2CONCLR=0x2c;
  I2CONSET=0x60;

  while(0==I2C_end);
   if(1==I2C_end) return(1);
     else return(0);
  /*DelayNS(2);
  while(I2C_num)
    {
	  
	  I2ADR=I2C_suba;
	  I2DAT=*I2C_buf;
	  DelayNS(2);
	  I2C_buf+=8;
	  I2C_num--;
	  I2C_suba+=8;
	  DelayNS(2);
	 }*/
  
 }
  
	   
void  ee_write(uint8 address,uint16 value)
{
   uint8 k=2;
   uint8 data_buf[2];
   data_buf[0]=value;
   data_buf[1]=value>>8;
	ISendStr(address,data_buf,k);
}
uint8 IRcvStr(uint8 suba,uint8 *s,uint8 num)
{
  I2C_sla=0xa1;
  I2C_suba=suba;
  I2C_buf=s;
  I2C_num=num;
  I2C_suba_en=1;
  I2C_end=0;

  I2ADR=I2C_suba;
  I2CONSET=0x44;

   while(0==I2C_end);
   if(1==I2C_end) return(1);
     else return(0);
/*
  for(l=0;l<I2C_num;l++)
  {
    *I2C_buf=I2DAT;
	DelayNS(2);
	rdata_buf[l]=I2DAT;
	DelayNS(2);
	l++;
	I2C_suba+=8;
   }
   revalue=(rdata_buf[1]<<8)|rdata_buf[0];
   return(revalue);  */
}



uint16 ee_read(uint8 address)
{
   uint8 read_buf[2];
   uint16 readvalue;
   read_buf[0]=0;
   read_buf[1]=0;
   IRcvStr(address,read_buf,2);
   readvalue=(read_buf[1]<<8)|read_buf[0];
   return(readvalue);
}
	   
void i2ctest(void)
{
  uint8 testvalue[2];
  ee_write(0x10,0x385E);
  testvalue[0]=ee_read(0x10);
  testvalue[1]=ee_read(0x10)>>8;
  while(1)
  {
    UART0_SendByte(testvalue[0]);
	UART0_SendByte(testvalue[1]);
	DelayNS(2);
   }
}




       

⌨️ 快捷键说明

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