安 发表于 2018-2-27 09:56
407的我测试过可以的,过程和你的一样,103以前我用的是模拟I2C,硬件好像有点问题。不知道后来大家都是使 ...
我觉得我卡死在while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));里面是我写完7位地址后,没有应答,网上说是从设备慢的问题,但我不太清楚。您觉得是什么原因导致的呢?
楼主写的从设备地址是多少?8563应该是0xA2。
安 发表于 2018-2-27 10:10
楼主写的从设备地址是多少?8563应该是0xA2。
嗯嗯是的,:
#define PCF8563_ADDR_W 0xA2
#define PCF8563_ADDR_R 0xA3
安 发表于 2018-2-27 10:10
楼主写的从设备地址是多少?8563应该是0xA2。
我想问一下,是不是得写一个用于I2C接收应答的中断服务函数呢?因为我是参照书上的例程写的,没有看到中断服务函数,网上的例子也很少。
我用中断都是在前面通讯完成后,读取数据或者发送数据的时候用。最好用示波器看一下是设备是否应答。
安 发表于 2018-2-27 10:32
我用中断都是在前面通讯完成后,读取数据或者发送数据的时候用。最好用示波器看一下是设备是否应答。 ...
好的,谢谢。
可以先用IO模拟IIC试一下,确定一下硬件没有问题。
STM32下IO口模拟IIC通讯的代码:
#define SCL_PORT GPIOA
#define SCL_PIN GPIO_Pin_1
#define SCL_HIGH GPIOA->BSRR=(uint32_t)GPIO_Pin_1
#define SCL_LOW GPIOA->BRR=(uint32_t)GPIO_Pin_1
#define SDA_PORT GPIOA
#define SDA_PIN GPIO_Pin_2
#define SDA_HIGH GPIO_>BSRR=(uint32_t)GPIO_Pin_2
#define SDA_LOW GPIOA->BRR=(uint32_t)GPIO_Pin_2
#define SDA_READ (uint16_t)(GPIOA->ID&GPIO_Pin_2)
#define SDA_OUT GPIOA->MODER|=((uint32_t)GPIO_Mode_OUT)<<(2*2))
#define SDA_IN GPIOA->MODER&=(GPIO_MODER_MODERO)<<(2*2))
#define SCL_OUTH() SCL_HIGH
#define SCL_OUTL() SCL_LOW
#define SDA_OUTH() SDA_HIGH
#define SDA_OUTL() SDA_LOW
#define SDA_SETIN() SDA_IN
#define SDA_READ() SDA_READ
void I2C_Delay(void)
{
uint8_t i = 200;
while(i--);
}
void SDA_SETOUT(void)
{
SDA_IN;
SDA_OUT;
}
void I2C_Start(void)
{
SCL_OUTH();
SDA_OUTH();
I2C_Delay();
SDA_OUTL();
I2C_Delay();
SCL_OUTL();
I2C_Delay();
}
void I2C_Stop(void)
{
SCL_OUTL();
SDA_OUTL();
I2C_Delay();
SCL_OUTH();
I2C_Delay();
SDA_OUTH();
Delay(Delay5ms);//Delay() 为系统延时,用于确保数据传输正确
}
uint8_t I2C_WriteByte(uint8_t Data)
{
uint8_t i,bAck=0;
for(i=0;i<8;i++)
{
SCL_OUTL();
if(Data & 0x80)
SDA_OUTH();
else
SDA_OUTL();
I2C_Delay();
SCL_OUTH();
I2C_Delay();
Data <<=1;
}
SCL_OUTL();
I2C_Delay();
SCL_OUTH();
I2C_Delay();
SDA_SETIN();
if(SDA_READ())
bAck=1;
else
bAck=0;
SCL_OUTL();
SDA_SETOUT();
I2C_Delay();
return ((uint8_t)(!bAck));
}
uint8_t I2C_ReadByte(uint8_t bLSByte)
{
uint8_t i,Data=0;
SDA_SETIN();
for(i=8;i!=8;i--)
{
SCL_OUTL();
Data = Data<<1;
I2C_Delay();
SCL_OUTH();
I2C_Delay();
if(SDA_READ())
Data |=0x01;
else
Data &=0xFE;
}
SCL_OUTL();
SDA_SETOUT();
if(bLSByte)
SDA_OUTH();
else
SDA_OUTL();
I2C_Delay();
SCL_OUTH();
I2C_Delay();
SCL_OUTL();
I2C_Delay();
return(Data);
}
uint8_t DAC_Write_1byte(uint8_t Slave,uint8_t Regist_Addr,uint8_t Data)
{
uint8_t succ,time=0;
I2C_Start();
succ=I2C_ReadByte(Slave);
while((succ!=1)&&(time<3)) //从机没有响应,重试三次
{
I2C_Stop();
I2C_Start();
succ=I2C_WriteByte(Slave);
time++;
}
succ=I2C_WriteByte(Regist_Addr);//发送寄存器地址
succ=I2C_WriteByte(Data);//发送数据
I2C_Stop();
return succ;
}
uint8_t DAC_Read_1byte(uint8_t Slave,uint8_t,Regist_Addr)
{
uint8_t succ,time=0;
uint8_t dat;
I2C_Start();
succ=I2C_WriteByte(Slave+1)//加1表示读数据
while((succ!=1)&&(time<3))
{
I2C_Stop();
I2C_Start();
succ=I2C_WriteByte(Slave+1);
time++;
}
succ=I2C_WriteByte(Regist_Addr);
dat=I2C_ReadByte(0);
I2C_Stop();
return dat;
}
Angel_YY 发表于 2018-2-27 11:04
可以先用IO模拟IIC试一下,确定一下硬件没有问题。
STM32下IO口模拟IIC通讯的代码:
好的,非常感谢您
该贴的问题还没有解决,我最近有其他事要忙,如果问题解决了,我会再发贴说明的,谢谢大家,以后有问题再请教大家,非常感谢。
如果用IIC模拟都不行的话,估计是硬件问题了。
先上个原理图
中文资料
模拟IIC的驱动代码
https://wenku.baidu.com/view/3107b4be1a37f111f1855b77.html