📄 i2c.c
字号:
/************************* IC Card AC Characteristics *******************************************
Symbol Parameter 2.7-volt 5.0-volt Units
Min Max Min Max
fSCL Clock Frequency,SCL 100 400 kHz
tLOW Clock Pulse Width Low 4.7 1.2 μs
tHIGH Clock Pulse Width High 4.0 0.6 μs
tI Noise Suppression Time 100 50 ns
tAA Clock Low to DICATa Out 0.1 4.5 0.1 0.9 μs
Valid
tBUF Time the bus must be 4.7 1.2 μs
free before a new
transmission can start
tHD.STA Start Hold Time 4.0 0.6 μs
tSU.STA Start Setup Time 4.7 0.6 μs
tHD.DICAT DICATa In Hold Time 0 0 μs
tSU.DICAT DICATa In Setup Time 200 100 ns
tR Inputs Rise Time 1.0 0.3 μs
tF Inputs Fall Time 300 300 ns
tSU.STO Stop Setup Time 4.7 0.6 μs
tDH DICATa Out Hold Time 100 50 ns
tWR Write Cycle Time 10 10 ms
Endurance 5.0V,25℃,Page Mode 100K 100K Write Cycles
***************************************************************************************************/
unsigned int IC_Output(unsigned char b)
{
unsigned char i;
IC_CLK = 0;
i = 8;
while(i--)
{
IC_IO = (b & 0x80) >> 7;
b = b << 1;
delay(5);
IC_CLK = 1;
delay(5); //tHIGH
IC_CLK = 0;
}
//check ACK
IC_IO = 1;
delay(5);
IC_CLK = 1;
if ((IC_IO & 1) == 1) {
IC_CLK = 0;
return(0);
}
delay(5);
IC_CLK = 0;
return(1);
}
unsigned char IC_Input(unsigned char ack)
{
unsigned char b,i;
IC_CLK = 0;
IC_IO = 1; //release the bus
i = 8;
b = 0;
while(i--)
{
b = b << 1;
IC_CLK = 0;
delay(5); //tLOW
IC_CLK = 1;
delay(2); //none
if (IC_IO & 1) b = b | 1;
delay(5); //tHIGH
}
IC_CLK = 0;
IC_IO = ack; //give ACK or nonACK
delay(5);
IC_CLK = 1;
delay(5);
IC_CLK = 0;
return(b);
}
void IC_Start(void)
{
IC_CLK = 0;
IC_IO = 1;
delay(5); //tLOW
IC_CLK = 1;
delay(5); //tHD.STA
IC_IO = 0;
delay(5); //tSU.STA
IC_CLK = 0;
}
void IC_Stop(void)
{
IC_CLK = 0;
IC_IO = 0;
delay(5); //tLOW
IC_CLK = 1;
delay(5); //tHD.STO
IC_IO = 1;
delay(5); //tSU.STO
}
unsigned char IC_Read(unsigned short int addr,unsigned short int len,unsigned char *ptr)
{
unsigned short int i;
if (!IC_PROBE ) return(1);
if (len == 0) return(5);
IC_ENABLE; //上电
i = 0;
delay(100); //等待
// EA = 0;
IC_Rstart:
IC_Start();
//Set current address
if ( !IC_Output(0xa0) ) {/*EA = 1;*/IC_DISABLE;return(2);}
if ( !IC_Output( 0x1f & HIBYTE(addr+i) ) ) {/*EA = 1;*/IC_DISABLE;return(2);}
if ( !IC_Output( LOBYTE(addr+i) ) ) {/*EA = 1;*/IC_DISABLE;return(2);}
//Sequential Read
IC_Start();
if ( !IC_Output(0xa1) ) {/*EA = 1;*/IC_DISABLE;return(2);}
while(1)
{
if( (len == i + 1) || ( ((addr+i+1)&0x1f) == 0 ))
{
ptr[i] = IC_Input(1);
i++;
break;
}
else ptr[i] = IC_Input(0);
i++;
}
IC_Stop();
/*EA = 1;*/
if (len != i)
{
/*EA = 0;*/
goto IC_Rstart;
}
/*EA = 1;*/
IC_DISABLE;
return(0);
}
unsigned char IC_Write(unsigned short int addr,unsigned short int len,unsigned char *ptr)
{
unsigned short int i;
unsigned char t;
if (!IC_PROBE) return(1);
if (len == 0) return(5);
IC_ENABLE; //上电
i = 0;
delay(100); //等待
/*EA = 0;*/
IC_Wstart:
IC_Start();
//Set current address
if ( !IC_Output(0xa0) ) {/*EA = 1;*/IC_DISABLE;return(2);}
if ( !IC_Output( 0x1f & HIBYTE(addr+i) ) ) {/*EA = 1;*/IC_DISABLE;return(2);}
if ( !IC_Output( LOBYTE(addr+i) ) ) {/*EA = 1;*/IC_DISABLE;return(2);}
// t = 0;
do
{
if ( ! IC_Output(ptr[i]) ) {/*EA = 1;*/IC_DISABLE;return(2);}
i++;
}
while((len != i) && ( ((addr+i)&0x1f)!=0 ) );
IC_Stop();
//Stopped
/*EA = 1;*/
for (t = 0; t < 30;t++)
{
delay(550);//505us
}
//Wait for internal write cycle about 10ms
if (len != i)
{
/*EA = 0;*/
goto IC_Wstart;
}
/*EA = 1;*/
IC_DISABLE;
return(0);
}
void ICP(unsigned char i)
{
switch (i)
{
case 0:
//Dprintf("操作成功!");
break;
case 1:
//Dprintf("未检测到IC卡!");
break;
case 5:
//Dprintf("函数调用错误!");
break;
case 2:
//Dprintf("I/O错误,跳回");
break;
default:return;break;
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -