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

关于使用6713的I2C,SCLK被锁定的问题,请帮忙各位帮忙解答

使用I2C通信,设置的用自发自收模式,应该是循环发送,结果发完一次后,SCLK就被锁定了,详细状况可见附图(逻辑分析仪抓取的),以下是代码

void I2C0_Init()
{
puts("HI,I2C Init!");

//进入复位 IRS = 0
I2C0_MDR &= ~0x20; //配置寄存器 //系统时钟 预分频器 225MHz / (21 + 1) = 10.25 MHz I2C0_PSC = (0x15);

//I2C 时钟分频器 10.25 / (50) = 200KHz
I2C0_CLKL = (0x0013); //19+6 = 25
I2C0_CLKH = (0x0013); //19+6 = 25
//退出复位
I2C0_MDR |= (0x20); //IRS = 1 //5-配置主机地址
I2C0_OAR = 0x05;

//中断设置 — 接收产生中断
// I2C0_IER = (1 << 3);
}

int I2C_WriteData(char addr, char *array, int count)
{
// int i;
char *p;
p = array;

//先前是否发送完成 检查SST位是否为1
if((I2C0_MDR & (0x01<<11)) == 1)
{
puts("previous not finished!");
return 0;
}

//从机地址
I2C0_SAR = addr;
I2C0_STR |= (1<<12);

//检查总线是否空闲 1:表示忙
if((I2C0_STR & (1<<12)))
{
return 0;
}

//计数器
I2C0_CNT = 2;

//发送开启
//进入复位 IRS = 0
I2C0_MDR |= 0x6E60;

//发送数据
while(I2C0_STR & (0x01<<1)); //ASK
while(!(I2C0_STR & (0x1<<4))); //ICXRDY
I2C0_DXR = *p++;

while(I2C0_STR & (0x01<<1));
while(!(I2C0_STR & (0x1<<4)));
I2C0_DXR = *p++;

//I2C0_MDR |= (0x1<<11);

return p-array;
}

主函数

void main()
{
// int i;
char data[2] = {5, 2};

I2C0_Init();
while(1)
{
I2C_WriteData(0x0F, data, 2);
}
}

dadi zeng:

关于停止位消失的问题,已经解决,应该是发送完最后一个字节,要延迟一会,才能产生,因为停止位有时序要求。

但是,后面的数组还是没出来,SCLK继续被锁定

修改的代码:

//发送数据 while(I2C0_STR & (0x01<<1)); //ASK while(!(I2C0_STR & (0x1<<4))); //ICXRDY I2C0_DXR = *p++;

while(I2C0_STR & (0x01<<1)); while(!(I2C0_STR & (0x1<<4))); I2C0_DXR = *p++;

for(i=0; i<3200; i++);    //增加的

修改后:

Shine:

回复 dadi zeng:

试试附件DSK6713 I2C DLB例程, 看能不能在你板子上运行.

dadi zeng:

回复 Shine:

Zhang,

    示例工程文件不能直接打开,我重新建立工程,出现如下错误

undefined first referenced symbol in file——— —————-_I2C_start C:\\CCStudio_v3.1\\MyProjects\\i2c\\Debug\\i2c_define.obj_I2C_rrdy C:\\CCStudio_v3.1\\MyProjects\\i2c\\Debug\\i2c_define.obj_I2C_xrdy C:\\CCStudio_v3.1\\MyProjects\\i2c\\Debug\\i2c_define.obj_I2C_readByte C:\\CCStudio_v3.1\\MyProjects\\i2c\\Debug\\i2c_define.obj_I2C_bb C:\\CCStudio_v3.1\\MyProjects\\i2c\\Debug\\i2c_define.obj_I2C_writeByte C:\\CCStudio_v3.1\\MyProjects\\i2c\\Debug\\i2c_define.obj_I2C_open C:\\CCStudio_v3.1\\MyProjects\\i2c\\Debug\\main.obj_PLL_deassert C:\\CCStudio_v3.1\\MyProjects\\i2c\\Debug\\main.obj_PLL_enable C:\\CCStudio_v3.1\\MyProjects\\i2c\\Debug\\main.obj_PLL_bypass C:\\CCStudio_v3.1\\MyProjects\\i2c\\Debug\\main.obj_PLL_reset C:\\CCStudio_v3.1\\MyProjects\\i2c\\Debug\\main.obj_I2C_sendStop C:\\CCStudio_v3.1\\MyProjects\\i2c\\Debug\\main.obj_I2C_configArgs C:\\CCStudio_v3.1\\MyProjects\\i2c\\Debug\\main.obj_I2C_close C:\\CCStudio_v3.1\\MyProjects\\i2c\\Debug\\main.obj

我把头文件的放到C:\CCStudio_v3.1\C6000\cgtools\include  下还是不行,请问如何解决,多谢!

dadi zeng:

回复 dadi zeng:

Zhang,

   不好意思,忘记加csl6713.lib了,示例文件能够运行,我研究下代码

Shine:

回复 dadi zeng:

嗯, 例程能运行可以排除硬件问题了, 你对比一下代码, 有问题欢迎继续探讨

dadi zeng:

回复 Shine:

终于搞出来了,总结起来有如下几点,也不知道对不对:

1.两次发送之间的间隔要保证,因为起始位和停止位都有最短的脉冲宽度要求

2.每次发送完之后也有类似的要求

3.每次发送前,要把机器进入复位,把上次的状态清掉

4.如果是循环发送,要把接收寄存器的内容读走

 更改后的程序如下

#include <stdio.h>#include "i2c.h"

void I2C0_Init(){ puts("HI,I2C Init!");

//进入复位 IRS = 0 I2C0_MDR &= ~0x20; //配置寄存器 //系统时钟 预分频器 225MHz / (21 + 1) = 10.25 MHz I2C0_PSC = (0x15);

//I2C 时钟分频器 10.25 / (50) = 200KHz I2C0_CLKL = (0x0013); //19+6 = 25 I2C0_CLKH = (0x0013); //19+6 = 25 //退出复位 IRS = 1 I2C0_MDR |= (0x20); //配置主机地址 I2C0_OAR = 0x05;

//中断设置 — 接收产生中断// I2C0_IER = (1 << 3);}

void I2C_EdmaInit(void){

}

int I2C_WriteData(char addr, char *array, int count){ int i; char *p,*in_p; static char input[2]; p = array; in_p = input;

//保证起始位及停止位的时序 for(i=0; i<3200; i++);

//进入复位,目的是清空I2CO_STR的标志位,不然有些标志位会一直占住I2C模块 I2C0_MDR &= ~0x20;

//先前是否发送完成 检查SST位是否为1 if((I2C0_MDR & (0x01<<11)) == 1) { puts("previous not finished!"); return 0; }

//从机地址 I2C0_SAR = addr; I2C0_STR |= (1<<12);

//检查总线是否空闲 1:表示忙 while((I2C0_STR & (1<<12)));

//计数器 I2C0_CNT = 2;

//发送开启 //进入复位 IRS = 0 I2C0_MDR |= 0x6E60;

//发送数据 while(I2C0_STR & (0x01<<1)); //ASK while(!(I2C0_STR & (0x1<<4))); //ICXRDY I2C0_DXR = *p++;

//获取得到的数据 while(I2C0_STR & (0x01<<11)) { *in_p++ = I2C0_DRR; } //发送数据 while(I2C0_STR & (0x01<<1)); while(!(I2C0_STR & (0x1<<4))); I2C0_DXR = *p++;

//获取得到的数据 while(I2C0_STR & (0x01<<11)) { *in_p++ = I2C0_DRR; } //停止位时序,去掉的话没有停止位 for(i=0; i<3000; i++);

//获取得到的数据 while(I2C0_STR & (0x01<<11)) { *in_p++ = I2C0_DRR; } return p-array;}

char I2C_ReadDirRegister(int DirId, int reg){ return 0;}

void i2c0_int(){ puts("received!");}

赞(0)
未经允许不得转载:TI中文支持网 » 关于使用6713的I2C,SCLK被锁定的问题,请帮忙各位帮忙解答
分享到: 更多 (0)