This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
工具/软件:Code Composer Studio
大家好、我正在尝试在两个 Piccolo TMS320F28035 I2C 通信之间进行 I2C 通信。 我被困在了从机侧、该文档解释不多。 我很感谢你们的帮助。我很确定我做了一些错误的事情,但我不知道是什么。
P.S. :我现在不使用诸如轮询 BB、XRDY、RRDY 或 NACK 位之类的中断,只是为了使其保持简单。
以下是我的代码:
########## 主代码(只写)##############################
#define I2C_SLAVE_ADDR 0x0055
void main (void)
{
InitSysCtrl();
InitI2CGpio();\
bool 标志= true;
I2CA_Init_master ();
for (;;)
{
while (GpioDataRegs.GPBDAT.bit.GPIO44 ==0 &&标志)
{
GREENLED_ON;
I2CA_WriteData();
GREENLED_OFF;
flag = false;
//delay_US (1000000);
}
}
void I2CA_Init_master (void)
{
I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //从器件地址-
I2caRegs.I2CPSC.all = 6; //预分频器-模块时需要7-12MHz
I2caRegs.I2CCLKL = 10; //注意:必须为非零
I2caRegs.I2CCLKH = 5; //注意:必须为非零
I2caRegs.I2CIER.ALL = 0;
I2caRegs.I2CMDR.ALL = 0x0020; //使 I2C 退出复位
I2caRegs.I2CFFTX.ALL = 0x6000; //启用 FIFO 模式和 TXFIFO
I2caRegs.I2CFFRX.ALL = 0x2040; //启用 RXFIFO、清除 RXFFINT、
DELAY_US (10);
返回;
}
void I2CA_WriteData (void){
uint16 i;
// while (I2caRegs.I2CMDR.bit.STP = 1)
// {
// };
I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //从地址寄存器
I2caRegs.I2CCNT = I2C_NUMBYTES; //数据计数为4字节
I2caRegs.I2CFFTX.ALL = 0x6000;//启用 FIFO 模式并复位 TX FIFO
I2caRegs.I2CDXR = 0xf0;
I2caRegs.I2CMDR.bit.TRX = 1;
I2caRegs.I2CMDR.bit.MST = 1;
I2caRegs.I2CMDR.bit.FREE = 1;
I2caRegs.I2CMDR.bit.STP= 1;//创建一个停止条件将释放总线、从而使 BB = 0。
I2caRegs.I2CMDR.bit.STT = 1;//一旦启动起始位、BB = 1再次变为繁忙状态。
返回;
}
############################ 从机代码(只读)########################
void main (void){
InitSysCtrl();
InitI2CGpio();
I2CASlave_init();
DELAY_US (1000000);
for (;;)
{
I2CA_ReceiveData();
}
}
void I2CASlave_init (void)
{
I2caRegs.I2COAR = I2C_SLAVE_ADDR; //从地址
I2caRegs.I2CPSC.all = 6; //预分频器-模块时需要7-12MHz
I2caRegs.I2CCLKL = 10; //注意:必须为非零
I2caRegs.I2CCLKH = 5; //注意:必须为非零
I2caRegs.I2CIER.ALL = 0x00; //启用 SCD、XRDY、RRDY、ARDY、 NACK 中断...抱歉、不启用任何内容
I2caRegs.I2CMDR.bit.MST = 0;//进入从机模式
I2caRegs.I2CMDR.bit.TRX = 0; //接收模式
I2caRegs.I2CMDR.bit.FREE = 1 ;//在自由模式下运行,将它设置为零,当数据被接收时将停止。l
I2caRegs.I2CMDR.ALL = 0x0020; //启用 IRS
// I2caRegs.I2CFFTX.ALL = 0x6000; //启用 FIFO 模式和 TXFIFO
// I2caRegs.I2CFFRX.ALL = 0x2040; //启用 RXFIFO、清除 RXFFINT、
返回;
}
空 I2CA_ReceiveData (空)
{
I2caRegs.I2COAR = I2C_SLAVE_ADDR; //从地址- EEPROM 控制代码
I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //从地址寄存器
I2caRegs.I2CCNT = 1;//接收计数到4个字节
//while (I2cRegs.I2CSTR.bit.RRDY = 0){};
Receive_Data[0]= I2caRegs.I2CDRR;
返回;
}
为此,我很抱歉,实际上我只是想发送1个字节。所以主设备的工作方式是:
1.检查按钮是否被按下(GPIO44) {使用标志、以便程序只运行一次}
2.运行 LOOP /发送数据1字节
3.停止
因此、我不需要检查 FIFO 是否已满、如果我不使用 FIFO、我不应该初始化 FIFO、所以我将其取出。
***** 大师****
就主器件而言,我能够看到9个时钟脉冲,即一个开始条件,后跟7位地址,然后是 R/W。 但之后、我的时钟会挂起低电平、因为它会等待我的 Oscilloscope.e2e.ti.com/.../2703.Master.txt 上的 ACK (从未从器件处获得)
***** 从设备*****
对于从器件侧、请找到代码 attached.e2e.ti.com/.../5873.Slave-RX.txt
就从器件而言、我现在只是尝试接收。所以我将地址轮询为从器件位中断标志。 即 AAS 以检查是否需要它的1,它告诉我从属设备已与主设备建立联系,并且能够验证自己是否为从设备。 变量中的增量将有助于我验证相同的值。
我知道我的代码有很多错误,但如果您能给我一个关于从代码的头,我将不胜感激。 我不知道我是否在正确的轨道上、因为从端的文档或示例很少。
*下面是我针对从器件的更新代码。 这只包含 I2C_Slave_init() 和 I2C_ReceiveData()。我没有包含主 器件,因为它是相同的。
*我很确定我的程序没有设置 AAS 标志、因为如果执行了该操作、变量"i"会递增、绿色 LED 会至少亮起一秒钟(这不是)。
*是的、我的 BB 在一个开始位和发送的地址后被置位。 当主器件等待一个 ACK 时、时钟被拉至低电平并且 I2CSTR.bit.BB = 1、这表示总线忙。
* STR 标志位 XSMT 和 XRDY 在之后置位、I2C 使能。 (发送前)
*但是,发送一个字节后置1的 STR 位是 NACK、ARDY、 XSMT、BB,即全部为1,其余为0。(发送后)
*对于外部上拉,SDA 和 SCL 线路上都有4.7K 电阻器。
################################ MASTER_Transmit ()############################################
void I2CA_WriteData (void){
I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //从地址寄存器
//检查是否忙
while (I2cRegs.I2CSTR.bit.BB = 1) {};
I2caRegs.I2CCNT = 1; //数据计数为1字节
I2caRegs.I2CDXR = DataTransmit[1]; //数据传输是一个包含一些数据的数组
I2caRegs.I2CMDR.bit.TRX = 1;
I2caRegs.I2CMDR.bit.MST = 1;
I2caRegs.I2CMDR.bit.FREE = 1;
I2caRegs.I2CMDR.bit.STP= 1; //创建一个停止条件将释放总线、从而使 BB = 0。
I2caRegs.I2CMDR.bit.STT = 1; //一旦启动起始位、BB = 1再次变为繁忙状态。
返回;
}
********* 从机端 Init 和接收代码
void I2C_Slave_init (void)
{
I2caRegs.I2COAR = I2C_SLAVE_OAL_ADDR; //从地址-
I2caRegs.I2CPSC.all = 6; //预分频器-模块时需要7-12MHz
I2caRegs.I2CCLKL = 10; //注意:必须为非零
I2caRegs.I2CCLKH = 5; //注意:必须为非零
I2caRegs.I2CIER.bit.XRDY =1;
I2caRegs.I2CIER.bit.RRDY=1;
I2caRegs.I2CIER.bit.ARDY = 1;
I2caRegs.I2CIER.bit.AAS = 1; //仅启用寻址作为从机中断。
I2caRegs.I2CMDR.bit.MST = 0;//进入从机模式//如果 MST = 0且 FDF = 0 TRX 是无关的。依赖 主机模块的命令作为一个 Rx 或 Tx 进行响应。
//I2caRegs.I2CMDR.bit.TRX = 0; //receive mode ->注释、因为它处于无关状态、请参阅 I2C 的表7
//I2caRegs.I2CMDR.bit.FREE = 1; //在自由模式下运行,将其设置为零,当数据被接收时将停止。l
I2caRegs.I2CMDR.bit.IRS = 1; //启用 IRS
I2caRegs.I2CSTR.ALL = 0;
返回;
}
空 I2CA_ReceiveData (空)
{
uint16 i = 0;
//while (!I2cRegs.I2CSTR.bit.RRDY);
I2caRegs.I2COAR = I2C_SLAVE_OAL_ADDR; //从地址
I2caRegs.I2CCNT = 1;//接收计数到1个字节这一点无关紧要,因为它处于从接收器模式
I2caRegs.I2CMDR.bit.MST = 0;
I2caRegs.I2CMDR.bit.NACKMOD = 0;
while (I2cRegs.I2CSTR.bit.AAS = 1){
i++;
Receive_Data[0]= I2caRegs.I2CDRR;
GREENLED_ON;
REDLED_OFF;
Delay_cycles (FSYSCLK); //等待1秒
}
(二
在这个问题上有什么进展?
编辑:由于我没有听到您的反馈、我将假定您已经解决了问题。 但是、如果情况并非如此、请随时拒绝回答并向主题添加新的回复!
惠特尼