本帖最后由 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;
}
}
|