我用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_11\RTC_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; } |
(txd&0x80>>7)
一会儿左移:
txd<<=1;
貌似无法得到正确的应答信号。
评分
查看全部评分
for(t=0;t<8;t++)
{
IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
(txd&0x80)>>7是为了取txd的最高位, txd<<=1; 是将下一位数据移位到最高位,就可以(txd&0x80)>>7取走最高位
* 函数名: static void I2C_Stop(void)
* 描述 : 终止信号
* 输入 : 无
* 输出 : 无
* 说明 :
*/
static void I2C_Stop(void)
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SDA_H;
I2C_delay();
}
每一步都收不到应答,我在想是不是从设备没有收到我给的数据
用示波器看看引脚的波形,
I2C时序对不对
I2C从设备地址对不对
评分
查看全部评分
贴个工程上来。
评分
查看全部评分
我是用逻辑分析仪抓的,时序和地址发的没有问题
不好意思,工程不方便贴,我这个程序还没有调试到主循环中,只是main函数中的初始化,我觉得其他模块应该不影响它,我的从设备是PCF8563,我觉得它是不是没有收到数据啊
评分
查看全部评分
知道第一个字节发送的时候没收到ACK意味着什么吗?
就是说,在这个地址就没找到有I2C设备。如果确定你的8563地址没错,那看看前面一个干扰脉冲怎么回事。
那个干扰脉冲有影响吗?因为我在初始化IO口后,IO口的电平都是拉低的,然后我在初始化中加了一句“ GPIO_SetBits(GPIOB,GPIO_Pin_11|GPIO_Pin_10);”之后,就会有前面的那个低脉冲了
硬件地址没有问题,其“从地址 读 0A3H;写 0A2H”,手册上说的
http://blog.csdn.net/xiayufeng520/article/details/46292755
我看了一下您的程序,我先问一下,您的程序中没有对SDA方向进行控制吗,当等ACK的时候SDA的方向不应该是输入吗