CY8CMBR3116的I2C通讯问题
本帖最后由 chushoujun 于 2015-11-11 16:21 编辑最近公司要使用这款CY8CMBR3116的触摸芯片,本人是软件初学者,在这款触摸芯片上碰壁了,前来请教下各位大神。为什么我的通讯写数据时读不到应答?我用的单片机是STM8S103F3,晶振内部16M,不分频,定时器250us。下面附上I2C通讯程序代码。
void I2C_Start(void)
{
GPIO_Out1(bI2C_SCL_ODR);//scl 1
GPIO_Out1(bI2C_SDA_ODR);//sda 1
Nop();
Nop();
Nop();
Nop();
GPIO_Out0(bI2C_SDA_ODR);//dsa 0
Nop();
Nop();
Nop();
Nop();
GPIO_Out0(bI2C_SCL_ODR);//scl 0
}
void I2C_Stop(void)
{
GPIO_Out0(bI2C_SCL_ODR);
GPIO_Out0(bI2C_SDA_ODR);
Nop();
Nop();
Nop();
Nop();
GPIO_Out1(bI2C_SCL_ODR);
Nop();
Nop();
Nop();
Nop();
GPIO_Out1(bI2C_SDA_ODR);
}
void I2C_Read_Ack(void)
{
GPIO_Out0(bI2C_SCL_ODR);
GPIO_Out0(bI2C_SDA_ODR);
Nop();
Nop();
Nop();
GPIO_Out1(bI2C_SCL_ODR);
Nop();
Nop();
Nop();
GPIO_Out0(bI2C_SCL_ODR);
}
void I2C_Read_No_Ack(void)
{
GPIO_Out0(bI2C_SCL_ODR);
GPIO_Out1(bI2C_SDA_ODR);
Nop();
Nop();
Nop();
GPIO_Out1(bI2C_SCL_ODR);
Nop();
Nop();
Nop();
GPIO_Out0(bI2C_SCL_ODR);
}
u8 I2C_Write_Byte(u8 data)
{
u8 i, ack;
for (i=0; i<8; i++)
{
if (TO_BITS(data).bit7)//从最高位开始写
{
GPIO_Out1(bI2C_SDA_ODR);//最高位为1,sda输出1
}
else
{
GPIO_Out0(bI2C_SDA_ODR);
}
data <<= 1;
GPIO_Out1(bI2C_SCL_ODR);//scl拉高发送数据
Nop();
Nop();
Nop();
GPIO_Out0(bI2C_SCL_ODR);
}
bI2C_SDA_DDR = 0;//sda改为输入方向
Nop();
Nop();
GPIO_Out1(bI2C_SCL_ODR);
ack = 0;
for (i=0; i<200; i++)
{
if (bI2C_SDA_IDR == 0)
{
ack = I2C_WRITE_SUCCESS;//I2C_WRITE_SUCCESS = 1
break;
} }
bI2C_SDA_DDR = 1;//sda恢复输出方向
GPIO_Out0(bI2C_SCL_ODR);
GPIO_Out0(bI2C_SDA_ODR);
return ack;
}
u8 I2c_Read_Byte(void)
{
u8 i, data;
bI2C_SDA_DDR = 0;
for (i=0; i<8; i++)
{
GPIO_Out1(bI2C_SCL_ODR);
Nop();
Nop();
if (bI2C_SDA_IDR == 0)
{
ClrBit(data,(7-i));//将该位清0再左移一位
}
else
{
SetBit(data,(7-i));//将该位置1再左移一位
}
GPIO_Out0(bI2C_SCL_ODR);
Nop();
}
bI2C_SDA_DDR = 1;
return data;
}
u8 Cy8cmbr3116_Write(u8 address, u16 data)//将数据写入
{
u8 temp;
u8 ack = 0;
I2C_Start();
temp = I2C_Write_Byte(0x6e);//0x37左移一位变为0x6e
nop();
if (temp == I2C_WRITE_SUCCESS)//如果成功写入ID
{
I2C_Write_Byte(address); //先写寄存器地址
temp = (u8)(data >> 8); //高8位送到低8位上,写进去
I2C_Write_Byte(temp);
I2C_Write_Byte((u8)data); //然后再发低8位
ack = 1; //成功应答标志置1
}
I2C_Stop();
return (ack);
}
u16 Cy8cmbr3116_Read(u8 address)
{
u16 data = 0;
I2C_Start();
I2C_Write_Byte(address);
data = (u16)I2c_Read_Byte();
I2C_Read_Ack();
data <<= 8;
data += I2c_Read_Byte();
I2C_Read_No_Ack();
I2C_Stop();
return data;
}
void Cy8cmbr3116_Control(void)
{
static u8 cy8mbr3116status = 0;
switch(cy8mbr3116status)
{
case 0:
nop();
Cy8cmbr3116_Write(0x00,0xffff); //第0个寄存器 使能触摸传感器
Cy8mbr3116TimeDelay = DELAY_50MS;
cy8mbr3116status ++;
break;
case 1:
if (Cy8mbr3116TimeDelay == 0)
{
KeyBuffer = Cy8cmbr3116_Read(0xaa); //读取按键值
cy8mbr3116status ++;
}
break;
case 2:
Cy8mbr3116TimeDelay = DELAY_50MS;
cy8mbr3116status = 1;
break;
default:
cy8mbr3116status = 0;
break;
}
}
用示波器 leijixiaomile 发表于 2015-11-12 00:02
用示波器
用示波器看过,SCL,SDA输出都是对的,SDA该输入的时候看寄存器表格也是输入方向,就是读的SDA始终是高电平 最低工作电压 (V): 1.71
最高工作电压 (V): 5.50
最低工作温度 (°C): -40
最高工作温度 (°C): 85 chushoujun 发表于 2015-11-12 09:20
用示波器看过,SCL,SDA输出都是对的,SDA该输入的时候看寄存器表格也是输入方向,就是读的SDA始终是高电 ...
楼主,你现在能实现i2c通信了吗?
我现在也在做这个,用你的代码在做调试。
hxgwd36 发表于 2015-11-26 18:19
楼主,你现在能实现i2c通信了吗?
我现在也在做这个,用你的代码在做调试。
...
通讯实现了,按键值也能读出来了,现在又遇到个问题,灵敏度调不了,哎,真是坑爹 按键值怎么实现?能不能截图一下 , 还有代码 , 我也在弄这个东东 acer280 发表于 2015-11-27 14:29
按键值怎么实现?能不能截图一下 , 还有代码 , 我也在弄这个东东
你可以加我QQ交流,794533041 学习了~! 灵敏度可以调呀~sensetivty,如果你选择400pf,则灵敏度是最低的,具体的,你可以去官网上面下载capsense design guide,如果你觉得这个很多功能被固定了,你可以选择PSoC4000~这样就比较灵活了~价格上面也很相似。 楼主,我也遇到了同样的问题,就是读的SDA始终是高电平,是什么原因导致的呢? 楼主,我也读出来是SDA高电平,请问是什么原因导致的? 楼主这款触摸芯片还用着吗?我刚接触有些问题向你请教 其实你可以直接通过EZ-Click 配置得到I2C的数据的,然后通过I2C直接把这些数据写到MBR3116里面就行了。 chushoujun 发表于 2015-11-28 17:56
你可以加我QQ交流,794533041
楼主分享下你你解决问题的方法 楼主,我用I2C接口写配置进去和在windows上用软件写配置,看到现象不一样(windows上配置一i个LED是亮的,用自己的I2C接口写进去,发现灯不亮) li703278714 发表于 2017-7-29 15:57
楼主,我用I2C接口写配置进去和在windows上用软件写配置,看到现象不一样(windows上配置一i个LED是亮的, ...
应该是你没配对 楼主,你的问题解决了吗?可否跟你学习一下。我最近也遇到了问题
页:
[1]