我用
STM32F103做主I2C,用PCF8563做从I2C,用模拟I2C进行的
通信,但是主给从发送了数据之后,接收的到都是NACK信号,为什么接收不到ACK呢?代码如下
#include "stm32f10x.h"
#include "stm32f10x_i2c.h"
#include "stm32f10x_gpio.h"
#include "i2c_mgr.h"
#include "stm32f10x_it.h"
#include "rtc_mgr.h"
#include "
timer_mgr.h"
void I2C_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
//------------RTC_SDA->PB_11RTC_SCL->PB_10----------------------------------------
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//¿ªÂ©Êä³ö
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_11|GPIO_Pin_10);
}
void I2C_START(void)
{
SDA_OUT();
SCL_H();
SDA_H();
delay_us(5);
SDA_L();
delay_us(5);
}
void I2C_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
for(t=0;t<8;t++)
{
SCL_L();
delay_us(1);
if((txd&0x80)>>7)
{
SDA_H();
SCL_H();
delay_us(5);
txd<<=1;
}
else
{
SDA_L();
SCL_H();
delay_us(5);
txd<<=1;
}
}
SCL_L();
}
void I2C_STOP(void)
{
SDA_OUT();
SCL_L();
delay_us(5);
SDA_L();
delay_us(5);
SCL_H();
delay_us(5);
SDA_H();
delay_us(5);
}
u8 I2C_Wait_ACK(void)
{
u8 waitcnt = 0;
u8 slaveack = 0;
SCL_L();
SDA_IN();
//delay_us(5);
SCL_H();
delay_us(5);
if(READ_SDA())
{
SCL_L();
return 1;
}
SCL_L();
delay_us(5);
return 0;
}
void I2C_ACK(void)
{
SCL_L();
SDA_OUT();
SDA_L();
delay_us(5);
SCL_H();
delay_us(5);
SCL_L();
}
void I2C_NACK(void)
{
SCL_L();
SDA_OUT();
SDA_H();
delay_us(5);
SCL_H();
delay_us(5);
SCL_L();
}
u8 I2C_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();
for(i=0;i<8;i++ )
{
SCL_H();
delay_us(5);
receive<<=1;
if(READ_SDA())receive++;
delay_us(5);
SCL_L();
delay_us(5);
}
if (!ack)
I2C_NACK();
else
I2C_ACK();
return receive;
}
void I2C_Write(u8 WriteAddr,u8 Dat)
{
I2C_START();
I2C_Send_Byte(PCF8563_ADDR_W);
I2C_Wait_ACK();
I2C_Send_Byte(WriteAddr);
I2C_Wait_ACK();
I2C_Send_Byte(Dat);
I2C_Wait_ACK();
I2C_STOP();
}
u8 I2C_Read(u8 ReadAddr)
{
u8 ReData,t=0;
I2C_START( );
I2C_Send_Byte(PCF8563_ADDR_W);
I2C_Wait_ACK();
I2C_Send_Byte(ReadAddr);
I2C_Wait_ACK();
I2C_START();
I2C_Send_Byte(PCF8563_ADDR_R);
I2C_Wait_ACK();
ReData = I2C_Read_Byte(0);
I2C_STOP();
return ReData;
}
就是不用管IO的方向呗,我把我的设置IO方向的语句去掉,的确是可以接收到ACK的,但也有一条语句接收的是NACK,看这个样子是不用设置IO的方向,但是我之前参考了两三版程序都有设置IO的方向,那到底用不用设置IO的方向。我们这个IO的方向一直都配置的是输出啊
这个是我用逻辑分析仪抓到的数据,第二个写寄存器地址,收到的响应是NACK,这说明什么呢?
您说的这个STOP一下,应该不是发一个停止信号吧,因为I2C的时序不是发送从地址等待ACK,发送要写的数据等ACK,最后发STOP信号啊。还是你说的这个stop是把SDA和SCL都拉高呢?
一周热门 更多>