TI中文支持网
TI专业的中文技术问题搜集分享网站

DSP28335通过I2C与外设进行通信时失败,SCL引脚无正常信号输出,求解

之前发帖子时发错了论坛分区了,经提醒后只能重新再这里发一下帖子,问题详细描述请移步步:e2echina.ti.com/…/523061

muscle li:

平台描述:

DSP28335,外部晶振30M,配置系统时钟150M,使能I2C时钟,I2Cmodule时钟为10M,配置通信波特率400K,采用硬件I2C通信方式,I2C的SCL和SDA硬件上拉4.7k,

外设为SHT30温湿度传感器模块,供电3.3V,,和DSP的I2C引脚直连,SHT30模块的ADDR引脚连接到VDD上,其设备地址为0x45

编译器版本CCS6.1,Win10

现状描述:

DSP通过I2C总线和外设SHT30进行通信,获取温度和湿度的数据。采用进行查询,判断状态为的方式进行,参考

http://bbs.eeworld.com.cn/thread-535531-1-1.html这个网站上的程序,虽然在写数据时在打印消息上没有看到有出错,但是通过示波器看波形却是不正常的,本来一发送一个字节就要有8个时钟脉冲,实际只有1~2个。且程序在写完后,接着的读取操作中卡住了。且卡住时,此时的SCL输出变为低电平了。

(上图为整个操作的波形)

(上图为前两次写的波形)

(上图为第二次写和第一次读的波形)

还有一个问题,关于DSP的I2C读取操作的。对于那些在读取数据前,不需要先发送指定的地址,直接读取就可以的的外设,怎么做?目前我网上看到的都是需要先发送一个地址之类的。如上面提到的SHT30、TDF8541等外设都不需要发送指定地址才能读的。但是如果不先写,好像就不能用ARDY判断当前是否可读了?

目前在google,查找TI等论坛后没有找到相关的解决方法,发帖求解各位TI工程师和论坛工程师。

源码如下:

1. 配置主时钟为150M:(外部晶振30M)

InitPll(DSP28_PLLCR,DSP28_DIVSEL);//#define DSP28_PLLCR   10,#define DSP28_DIVSEL     2

2. 使能I2C时钟:

SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1;   // I2C

3. 配置I2C的引脚:

InitI2CGpio()
{EALLOW;//// Enable internal pull-up for the selected pins// Pull-ups can be enabled or disabled disabled by the user.// This will enable the pullups for the specified pins.// Comment out other unwanted lines.//GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0;// Enable pull-up for GPIO32 (SDAA)GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0;// Enable pull-up for GPIO33 (SCLA)//// Set qualification for selected pins to asynch only// This will select asynch (no qualification) for the selected pins.// Comment out other unwanted lines.//GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3;// Asynch input GPIO32 (SDAA)GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3;// Asynch input GPIO33 (SCLA)//// Configure SCI pins using GPIO regs// This specifies which of the possible GPIO pins will be I2C functional// pins. Comment out other unwanted lines.//GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1;// Configure GPIO32 to SDAAGpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1;// Configure GPIO33 to SCLAEDIS;
}

4. I2C初始化

void I2CA_Init(Uint16 iSlaveAddress,CommunicateSpeed_Enum eCommunicateSpeed)
{//IRS must be 0 while you configure/reconfigure the i2c moduleI2caRegs.I2CMDR.bit.IRS = 0;// Initialize I2CI2caRegs.I2CSAR = iSlaveAddress;// Slave address// Configure I2C Module Clock#if (CPU_FRQ_150MHZ)// Default - For 150MHz SYSCLKOUTI2caRegs.I2CPSC.all = 13;// Prescaler - need 7-12 Mhz on module clk (150/15 = 10MHz)#endif#if (CPU_FRQ_100MHZ)// For 100 MHz SYSCLKOUTI2caRegs.I2CPSC.all = 9;// Prescaler - need 7-12 Mhz on module clk (100/10 = 10MHz)#endif// Configure Communicate Speedif ( CommunicateSpeed_100K == eCommunicateSpeed ){I2caRegs.I2CCLKL = 60;// NOTE: must be non zeroI2caRegs.I2CCLKH = 30;// NOTE: must be non zero}else if ( CommunicateSpeed_400K == eCommunicateSpeed ){I2caRegs.I2CCLKL = 10;// NOTE: must be non zeroI2caRegs.I2CCLKH = 5;// NOTE: must be non zero}else{printf("Current I2C Communicate Speed Not Support");}// Configure Interrupt Source EnableI2caRegs.I2CIER.all = 0x00;// Disable interruptsI2caRegs.I2CMDR.all = 0x0020;// Take I2C out of reset// Stop I2C when suspended//I2caRegs.I2CMDR.bit.IRS = 1;	// Take I2C out of reset// Stop I2C when suspendedI2caRegs.I2CFFTX.all = 0x0000;	// Disable FIFO mode and TXFIFOI2caRegs.I2CFFRX.all = 0x0000;	// Disable RXFIFO, clear RXFFINT,return;
}

5. I2C写参数

Uint16 WriteData(Uint16 iSlaveAddress,Uint16 *pTxData,Uint16 iTxDataLen)
{Uint16 i;// Wait until the STP bit is cleared from any previous master communication.// Clearing of this bit by the module is delayed until after the SCD bit is// set. If this bit is not checked prior to initiating a new message, the// I2C could get confused.while(I2caRegs.I2CMDR.bit.STP == 1);// Check if bus busywhile(I2caRegs.I2CSTR.bit.BB == 1);while(0 == I2caRegs.I2CSTR.bit.XRDY);I2caRegs.I2CSAR = iSlaveAddress;// Slave address;I2caRegs.I2CCNT = iTxDataLen;I2caRegs.I2CDXR = pTxData[0];I2caRegs.I2CMDR.all = 0x6E20;for (i=0; i<iTxDataLen-1; i++){printf("\r\n w1 here,I2CMDR:0x%04x,I2CSTR:0x%04x,I2CCNT:0x%04x,I2CDXR:0x%04x",I2caRegs.I2CMDR.all,I2caRegs.I2CSTR.all,I2caRegs.I2CCNT,I2caRegs.I2CDXR);while(0 == I2caRegs.I2CSTR.bit.XRDY);I2caRegs.I2CDXR = pTxData[i+1];if (I2caRegs.I2CSTR.bit.NACK == 1){printf("\r\n w busy here1");return I2C_BUS_BUSY_ERROR;}}return I2C_SUCCESS;}

6. I2C读函数

Uint16 ReadData(Uint16 iSlaveAddress,Uint16 *pTxData,Uint16 iTxDataLen,Uint16 *pRxData,Uint16 iRxDataLen)
{Uint16 i,Temp;// Wait until the STP bit is cleared from any previous master communication.// Clearing of this bit by the module is delayed until after the SCD bit is// set. If this bit is not checked prior to initiating a new message, the// I2C could get confused.while(I2caRegs.I2CMDR.bit.STP == 1);// Check if bus busywhile(I2caRegs.I2CSTR.bit.BB == 1);I2caRegs.I2CSAR = iSlaveAddress;// Slave address;;if ( (0 != iTxDataLen) && (NULL != pTxData) )	//判断是否需要在读取前先发送数据{while(0 == I2caRegs.I2CSTR.bit.XRDY);I2caRegs.I2CCNT = iTxDataLen;I2caRegs.I2CDXR = pTxData[0];I2caRegs.I2CMDR.all = 0x2620;if (I2caRegs.I2CSTR.bit.NACK == 1){return I2C_BUS_BUSY_ERROR;}for (i=0; i<iTxDataLen-1; i++){while(0 == I2caRegs.I2CSTR.bit.XRDY);I2caRegs.I2CDXR = pTxData[i+1];if (I2caRegs.I2CSTR.bit.NACK == 1){return I2C_BUS_BUSY_ERROR;}}DELAY_US(50);}printf("\r\n r here1,I2CMDR:0x%04x,I2CSTR:0x%04x",I2caRegs.I2CMDR.all,I2caRegs.I2CSTR.all);while(0 == I2caRegs.I2CSTR.bit.XRDY);	//判断这个是否合适??// Wait Register-access-ready//while(I2caRegs.I2CSTR.bit.ARDY == 0);	//如果不需要先写入的读取,用这个判断也不合适??I2caRegs.I2CCNT = iRxDataLen;I2caRegs.I2CMDR.all = 0x2C20;if (I2caRegs.I2CSTR.bit.NACK == 1){return I2C_BUS_BUSY_ERROR;}for(i=0; i<iRxDataLen; i++){printf("\r\n r here2,I2CMDR:0x%04x,I2CSTR:0x%04x",I2caRegs.I2CMDR.all,I2caRegs.I2CSTR.all);while(0 == I2caRegs.I2CSTR.bit.RRDY);	//卡在这里Temp = I2caRegs.I2CDRR;if (I2caRegs.I2CSTR.bit.NACK == 1){return I2C_BUS_BUSY_ERROR;}*pRxData = Temp;pRxData++;}return I2C_SUCCESS;
}

在while(0 == I2caRegs.I2CSTR.bit.RRDY);卡住,程序停止运行了。在其上一句调试信号为 r here2,I2CMDR:0x0c20,I2CSTR:0x3438

看sprg03b手册上说,在RSFULL=1或XMST=0时会将SCL拉低,但是在卡住的调试上看,这两个条件都不满足,但是SCL却输出低了。(将SCL断开和外设的连接,测试DSP侧的SCL信号,为低)

之前发帖子时发错了论坛分区了,经提醒后只能重新再这里发一下帖子,问题详细描述请移步步:e2echina.ti.com/…/523061

Shine:DSP28335属于C2000系列,请到C2000论坛咨询。
e2echina.ti.com/…/

之前发帖子时发错了论坛分区了,经提醒后只能重新再这里发一下帖子,问题详细描述请移步步:e2echina.ti.com/…/523061

yongqing wang:DSP28335 自带的IIC列程正常吗

之前发帖子时发错了论坛分区了,经提醒后只能重新再这里发一下帖子,问题详细描述请移步步:e2echina.ti.com/…/523061

muscle li:

回复 yongqing wang:

目前没有使用外置EEPROM,没有测试过control suite自带的eeprom的例程。

之前发帖子时发错了论坛分区了,经提醒后只能重新再这里发一下帖子,问题详细描述请移步步:e2echina.ti.com/…/523061

muscle li:目前的更新情况是,在使用另一个TEF6686的收音机芯片的I2C外设时,上面的程序中读写都没有问题,TEF6686的读取需要先指定要读取的地址的,所以上面关于读取部分的疑问就没有问题。
但是对于SHT32这个温湿度传感器,写入还是不行,还是和上面描述的情况一致。手上两个这个传感器都是这样的情况。
还有就是对于无地址写入的读取方式的I2C读取,还是没有调通。

之前发帖子时发错了论坛分区了,经提醒后只能重新再这里发一下帖子,问题详细描述请移步步:e2echina.ti.com/…/523061

muscle li:

回复 Shine:

谢谢指点,不说还没有留意。进错地了。已在C2000那边新建帖子后,链接过来。

之前发帖子时发错了论坛分区了,经提醒后只能重新再这里发一下帖子,问题详细描述请移步步:e2echina.ti.com/…/523061

mangui zhang:怎么能不接外部传感器看看时钟波形等不你的start沿能不能看到
排查一下是不是电平不匹配等原因或者上拉电阻不合理

赞(0)
未经允许不得转载:TI中文支持网 » DSP28335通过I2C与外设进行通信时失败,SCL引脚无正常信号输出,求解
分享到: 更多 (0)