📄 per.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 + -