simulatei2c.c

来自「用于监视I2C通信总线」· C语言 代码 · 共 372 行

C
372
字号

#include "define.h"
#include "stm32f10x_it.h"
#include "usb_lib.h"
#include "usb_istr.h"
#include "hw_config.h"
#include "stm32f10x_exti.h"

#define WINDOW_SIZE 30000

typedef enum _I2CSTAT
{
  WAITING,
  START,
  BUSY,
}I2CSTAT;

typedef struct _SI2C
{
  I2CSTAT status;
  uint8 data[WINDOW_SIZE];
  uint8 temp[1000];
  uint32 head;
  uint32 tail;
  uint32 windowcount;
  uint8 nowbyte;
  uint32 bitcount;
  uint8 flag;//0. data out control bit
  uint8 test;
  uint32 windowmaxcount;
}SI2C;

SI2C si2c1;

uint16 tempp1[2000];
uint16 tempp2[2000];
uint32 tempp_count1;
uint32 tempp_count2;
uint16 tempp_choise;


void SI2C_init(void);
uint8 data_to_ascii(uint8 data);
//void SCL_DET(void);
//void SDA_DET(void);
void I2C_To_USB_Send_Data(void);
void WINDOW_In(uint8 data);
uint8 WINDOW_Out(void);
void data_convert(void);
void SI2C_data_out_enable(void);

void SI2C_data_out_enable(void)
{
  BitSet(si2c1.flag,0);
}

void WINDOW_In(uint8 data)
{
  if(si2c1.windowcount<WINDOW_SIZE)
  {
    if(si2c1.head==WINDOW_SIZE-1)
    {
      si2c1.head=0;
    }
    else
    {
      si2c1.head++;
    }
    si2c1.data[si2c1.head]=data;
    si2c1.windowcount++;
  }
  else
  {
    si2c1.test=1;
  }
  if(si2c1.windowcount>si2c1.windowmaxcount)
  {
    si2c1.windowmaxcount=si2c1.windowcount;
  }
}

uint8 WINDOW_Out(void)
{
  uint8 data;
  if(si2c1.windowcount>0)
  {
    if(si2c1.tail==WINDOW_SIZE-1)
    {
      si2c1.tail=0;
    }
    else
    {
      si2c1.tail++;
    }
    data=si2c1.data[si2c1.tail];
    si2c1.windowcount--;
  }
  return(data);
}


void SI2C_init(void)
{
  si2c1.head=0;
  si2c1.tail=0;
  si2c1.status=WAITING;
  si2c1.nowbyte=0;
  si2c1.bitcount=0;
  si2c1.windowcount=0;
}

uint8 data_to_ascii(uint8 data)
{
  if(data<10)
  {
    return(data+0x30);
  }
  else
  {
    return(data-10+0x41);
  }
    
}

//void SCL_DET(void)//at exit 0,  pa 0
void EXTI0_IRQHandler(void)
{ 
  uint8 i;
  if(si2c1.status==BUSY)
  
  //if(1)
  {
    i=BitTst(GPIOA->IDR,1);
    if(si2c1.bitcount<8)
    {
      //if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1))//sda high
      if(i)
      {
        BitSet(si2c1.nowbyte,7-si2c1.bitcount);
      }
      else
      {
        BitClr(si2c1.nowbyte,7-si2c1.bitcount);
      }
      si2c1.bitcount++;
    }
    else
    {
      //WINDOW_In(data_to_ascii(si2c1.nowbyte>>4));
      //WINDOW_In(data_to_ascii(si2c1.nowbyte&0xf));
      if(!tempp_choise)
      {
        tempp1[tempp_count1++]=si2c1.nowbyte;
      }
      else
      {
        tempp2[tempp_count2++]=si2c1.nowbyte;
      }
     
      /*
      if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1))//sda high, nack
      {
        //WINDOW_In('n');
        //WINDOW_In(' ');
        if(!tempp_choise)
        {
          tempp1[tempp_count1++]=0x400;
        }
        else
        {
          tempp2[tempp_count2++]=0x400;
        }
      }
      else
      {
        //WINDOW_In('a');
        //WINDOW_In(' ');
        if(!tempp_choise)
        {
          tempp1[tempp_count1++]=0x300;
        }
        else
        {
          tempp2[tempp_count2++]=0x300;
        }
        
      }*/
      si2c1.bitcount=0;
    }
  }
  
  while (((EXTI->PR & 1)) && (EXTI->IMR & 1))
  { 
  //EXTI_ClearITPendingBit(EXTI_Line0);
   EXTI->PR = 1;
  }
}

//void SDA_DET(void)//at exit 1,pa 1
void EXTI1_IRQHandler(void)
{
  //sda low and scl high, det a start condition on i2c bus
    //if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0))
    if(BitTst(GPIOA->IDR,0))
    {
      //if((GPIO_ReadInputData(GPIOA)&0x3)==1)
      //if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1))
      if(!BitTst(GPIOA->IDR,1))
      {
        //si2c1.nowbyte=0;
        //si2c1.bitcount=0;
        if(!tempp_choise)
        {
          tempp1[tempp_count1++]=0x100;
        }
        else
        {
          tempp2[tempp_count2++]=0x100;
        }
        //WINDOW_In('s');
        //WINDOW_In('\n');
        si2c1.status=BUSY;
        BitClr(EXTI->FTSR,1);
        BitSet(EXTI->RTSR,1);
      }
      
      
      //sda high and scl high, det a stop condition on i2c bus
      
      //else if((GPIO_ReadInputData(GPIOA))&0x3==3)
      //else if((GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0))/*&&(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1))*/)
      else
      {
        //si2c1.nowbyte=0;
        si2c1.bitcount=0;
        if(!tempp_choise)
        {
          tempp1[tempp_count1++]=0x200;
        }
        else
        {
          tempp2[tempp_count2++]=0x200;
        }
        //WINDOW_In('\n');
        //WINDOW_In('p');
        //WINDOW_In('\n');
        si2c1.status=WAITING;
        BitClr(EXTI->RTSR,1);
        BitSet(EXTI->FTSR,1);
      }
    }

 while (((EXTI->PR & 2)) && (EXTI->IMR & 2))
 {
  //EXTI_ClearITPendingBit(EXTI_Line1);
   EXTI->PR = 2;
 }
}

void data_convert(void)
{
  int32 i;
  //data in
  if(!tempp_choise)
  {
    if((tempp_count1>=100)||(tempp1[tempp_count1-1]==0x200))//over 100 words or the last data is stop condition
    {
      tempp_count2=0;
      tempp_choise=1;//change the no
      for(i=0;i<tempp_count1;i++)
      {
        if(tempp1[i]==0x100)//the data is a start condition signal
        {
          WINDOW_In('s');
          WINDOW_In('\n');
        }
        else if(tempp1[i]==0x200)//the data is a stop condition signal
        {
          WINDOW_In('\n');
          WINDOW_In('p');
          WINDOW_In('\n');
        }
        else if(tempp1[i]==0x300)//the data is a ack signal
        {
          WINDOW_In('a');
          WINDOW_In(' ');
        }
        else if(tempp1[i]==0x400)//the data is a nack signal
        {
          WINDOW_In('n');
          WINDOW_In(' ');
        }
        else //it's a valid data
        {
          WINDOW_In(data_to_ascii((uint8)(tempp1[i]>>4)));
          WINDOW_In(data_to_ascii((uint8)(tempp1[i]&0xf)));
          WINDOW_In(' ');
        }
      }
    }
  }
  else
  {
    if((tempp_count2>=100)||(tempp2[tempp_count2-1]==0x200))//over 100 words or the last data is stop condition
    {
      tempp_count1=0;
      tempp_choise=0;//change the no
      for(i=0;i<tempp_count2;i++)
      {
        if(tempp2[i]==0x100)//the data is a start condition signal
        {
          WINDOW_In('s');
          WINDOW_In('\n');
        }
        else if(tempp2[i]==0x200)//the data is a stop condition signal
        {
          WINDOW_In('\n');
          WINDOW_In('p');
          WINDOW_In('\n');
        }
        else if(tempp2[i]==0x300)//the data is a ack signal
        {
          WINDOW_In('a');
          WINDOW_In(' ');
        }
        else if(tempp2[i]==0x400)//the data is a nack signal
        {
          WINDOW_In('n');
          WINDOW_In(' ');
        }
        else //it's a valid data
        {
          WINDOW_In(data_to_ascii((uint8)(tempp2[i]>>4)));
          WINDOW_In(data_to_ascii((uint8)(tempp2[i]&0xf)));
          WINDOW_In(' ');
        }
      }
    }
    
    
  }
}

void I2C_To_USB_Send_Data(void)
{
  uint32 i;
  uint32 count=100;
  if(BitTst(si2c1.flag,0))
  {
    if(si2c1.windowcount>100)
    {
      for(i=0;i<count;i++)
      {
        si2c1.temp[i]=WINDOW_Out();
      }
    }
    else
    {
      count=si2c1.windowcount;
      for(i=0;i<count;i++)
      {
        si2c1.temp[i]=WINDOW_Out();
      }
    }
    UserToPMABufferCopy(si2c1.temp, ENDP1_TXADDR, count);
    SetEPTxCount(ENDP1, count);
    SetEPTxValid(ENDP1);
    BitClr(si2c1.flag,0); 
  }
} 

⌨️ 快捷键说明

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