1.TMS320F28035 IIC寄存器介绍
1.1 IIC模式寄存器定义如下:
作为从机编程我们需要关注的bit有 IRS,XA,BC,RM,MST;
IRS:IIC模块复位,在进行初始化时需要进行设置为复位模式。
XA: 拓展地址使能位,这里我用的是标准的地址位也就是7位。
BC:SDA引脚一个字节定义的bit数,这里设置为0即8bit.
RM:重复发送模式。这里使用不重复模式。
MST:IIC模块主从机设置,这里作为从机配置。
1.2 IIC中断寄存器定义如下
我们常用的IIC作为主机大部分工作在轮询模式,在从机编程这里如果用轮询很难捕捉到IIC的起始信号和终止信号,这里用这款芯片的中断来捕捉终止信号和主机请求接收数据和发送数据信号。
这里的中断我们需要开启的有以下三位:
RRDY:接收中断
XRDY:发送中断
SCD:停止条件中断
1.3 IIC中断源寄存器定义如下
从上面我们配置了IIC中断方式,接下来我们需要在中断函数中查询这个寄存器就可知道对应的当前IIC处于什么状态。
0h (R/W) = None
1h (R/W) = Arbitration lost
2h (R/W) = No-acknowledgment condition detected
3h (R/W) = Registers ready to be accessed
4h (R/W) = Receive data ready
5h (R/W) = Transmit data ready
6h (R/W) = Stop condition detected
7h (R/W) = Addressed as slave
这里重点关注4,5,6三个就行,中断使能就使能了这三个中断源。
1.4 IIC时钟配置不介绍,参考官方主机程序配置
1.5 IIC从机地址配置寄存器定义如下
该寄存器在从机模式下配置为当前设备的从机地址。
1.6 代码示例配置IIC从机模式
void Pmbus_Mode_Init()
{
EALLOW;
I2caRegs.I2CMDR.bit.IRS = 0;
I2caRegs.I2CMDR.bit.XA=0;
I2caRegs.I2CMDR.bit.BC= 0;
I2caRegs.I2CMDR.bit.RM = 0;
I2caRegs.I2CMDR.bit.MST= 0;
I2caRegs.I2CIER.bit.RRDY = 1;
I2caRegs.I2CIER.bit.XRDY = 1;
I2caRegs.I2CIER.bit.SCD = 1;
I2caRegs.I2CPSC.all = 5; //12MHZ
I2caRegs.I2CCLKL = SYSCLK/(I2caRegs.I2CPSC.all+1)/PMBUS_CLK/2-5;
I2caRegs.I2CCLKH = SYSCLK/(I2caRegs.I2CPSC.all+1)/PMBUS_CLK/2-5; //100KHZ
I2caRegs.I2CFFRX.bit.RXFFIENA = 0;
I2caRegs.I2CFFTX.bit.TXFFIENA = 0;
EDIS;
}
void Pmbus_Address_Set(unsigned char address )
{
EALLOW;
I2caRegs.I2COAR = address;
I2caRegs.I2CMDR.bit.IRS = 1;
EDIS;
}
2 中断函数编写
中断函数如下,直接贴代码了,不作解释。
__interrupt void i2c_interrupt(void)
{
pmbus_handle.pmbus_byte_count++; //用于确认读写字节数
Uint16 i =0 ;
pmbus_status = I2caRegs.I2CISRC.all;
printf("pmbus_status:%d\r\n",pmbus_status);
printf(" pmbus_handle.pmbus_byte_count:%d\r\n", pmbus_handle.pmbus_byte_count);
switch (pmbus_status)
{
case 0:
printf("IIC_00 ");
break;
case 1:
printf("IIC_01 ");
break;
case 2:
printf("IIC_02 ");
break;
case 3:
printf("IIC_03 ");
break;
case 4: //写入数据
pmbus_state = pmbus_write;
if(pmbus_handle.pmbus_receieve_index == 0)
pmbus_handle.pmbus_receieve_address = I2caRegs.I2CDRR ;
else
pmbus_buff[pmbus_handle.pmbus_receieve_index-1]= I2caRegs.I2CDRR;
if(pmbus_handle.pmbus_receieve_index > 0)
{
printf(" pmbus_buffer[pmbus_handle.pmbus_receieve_index-1] :%d\r\n",pmbus_buff[pmbus_handle.pmbus_receieve_index-1 ]);
}
printf("pmbus_handle.pmbus_receieve_address :%d\r\n",pmbus_handle.pmbus_receieve_address );
pmbus_handle.pmbus_receieve_index ++;
break;
case 5: //读数据
printf("pmbus_handle.pmbus_translate_index:%d\r\n",pmbus_handle.pmbus_translate_index );
if(pmbus_state == pmbus_write)
{
printf("GET address successful" );
readCommandTable[pmbus_handle.pmbus_receieve_address]();
}
pmbus_state = pmbus_read;
I2caRegs.I2CDXR = (unsigned char )pmbus_translate_buff[pmbus_handle.pmbus_translate_index];
pmbus_handle.pmbus_translate_index ++;
break;
case 6:
printf("IIC_06 ");
pmbus_state = idle;
pmbus_handle.pmbus_receieve_index = 0 ;
pmbus_handle.pmbus_translate_index = 0;
for(i=0;i <= pmbus_buff_length;i++)
{
pmbus_translate_buff[i] = 0xffff;
}
pmbus_handle.pmbus_byte_count = 0;
I2caRegs.I2CMDR.bit.IRS = 0;
I2caRegs.I2CMDR.bit.IRS = 1;
break;
case 7:
printf("IIC_07");
break;
}
PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;
}
3 效果展示
左边是串口打印的数据,主要是看中断的中断源属于哪个,右边为IIC转串口模块接收的数据和打印出来的BUFF数据一致。