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 + -
显示快捷键?