各位大侠,我现在做一个IIC的双机通信,从机上一直收不到信息。主机的程序通过示波器查看时钟信号和数据都是有发出来的,但是从机一直无法接收到信息,请大家帮忙分析一下:
主机程序:
#include <stdio.h>
#include "Driver\DrvGPIO.h"
#include "Driver\DrvI2C.h"
#include "Driver\DrvSYS.h"
#include "Driver\DrvUART.h"
/*---------------------------------------------------------------------------------------------------------*/
/* Global variables */
/*---------------------------------------------------------------------------------------------------------*/
uint8_t Device_Addr;
uint8_t Tx_Data[3];
uint8_t Rx_Data;
uint8_t DataLen;
volatile uint8_t EndFlag = 0;
/*---------------------------------------------------------------------------------------------------------*/
/* I2C Rx Callback Function */
/*---------------------------------------------------------------------------------------------------------*/
void I2C_Callback_Rx(uint32_t status)
{
if (status == 0x08) /* START has been transmitted and prepare SLA+W */
{
DrvI2C_WriteData(0x50);//(Device_Addr<<1);
DrvI2C_Ctrl(0, 0, 1, 0); //clear int flag
}
else if (status == 0x18) /* SLA+W has been transmitted and ACK has been received */
{
DrvI2C_WriteData(Tx_Data[DataLen++]);
DrvI2C_Ctrl(0, 0, 1, 0);
}
else if (status == 0x20) /* SLA+W has been transmitted and NACK has been received */
{
DrvI2C_Ctrl(1, 1, 1, 0);
}
else if (status == 0x28) /* DATA has been transmitted and ACK has been received */
{
if (DataLen != 2)
{
DrvI2C_WriteData(Tx_Data[DataLen++]);
DrvI2C_Ctrl(0, 0, 1, 0);
}
else
{
DrvI2C_Ctrl(1, 0, 1, 0);
}
}
else if (status == 0x10) /* Repeat START has been transmitted and prepare SLA+R */ // 重复
{
DrvI2C_WriteData(Device_Addr<<1 | 0x01);
DrvI2C_Ctrl(0, 0, 1, 0);
}
else if (status == 0x40) /* SLA+R has been transmitted and ACK has been received */
{
DrvI2C_Ctrl(0, 0, 1, 0);
}
else if (status == 0x58) /* DATA has been received and NACK has been returned */
{
Rx_Data = DrvI2C_ReadData();
DrvI2C_Ctrl(0, 1, 1, 0);
EndFlag = 1;
}
else
{
printf("Status 0x%x is NOT processed\n", status);
}
}
/*---------------------------------------------------------------------------------------------------------*/
/* I2C Tx Callback Function */
/*---------------------------------------------------------------------------------------------------------*/
void I2C_Callback_Tx(uint32_t status)
{
if (status == 0x08) /* START has been transmitted */
{
DrvI2C_WriteData(0x50<<1);//(Device_Addr<<1);
DrvI2C_Ctrl(0, 0, 1, 0);
}
else if (status == 0x18) /* SLA+W has been transmitted and ACK has been received */
{
DrvI2C_WriteData(Tx_Data[DataLen++]);
DrvI2C_Ctrl(0, 0, 1, 0);
}
else if (status == 0x20) /* SLA+W has been transmitted and NACK has been received */
{
DrvI2C_Ctrl(1, 1, 1, 0); //重新启动总线
}
else if (status == 0x28) /* DATA has been transmitted and ACK has been received */
{
if (DataLen != 3)
{
DrvI2C_WriteData(Tx_Data[DataLen++]);
DrvI2C_Ctrl(0, 0, 1, 0);
}
else
{
DrvI2C_Ctrl(0, 1, 1, 0);
EndFlag = 1;
}
}
else
{
printf("Status 0x%x is NOT processed\n", status);
}
}
void DELAY(void)
{
int a ;
for(a=0;a<10000;a++);
}
/*---------------------------------------------------------------------------------------------------------*/
/* Main Function */
/*---------------------------------------------------------------------------------------------------------*/
int32_t main (void)
{
uint32_t u32data, i;
STR_UART_T sParam;
UNLOCKREG();
// SYSCLK->PWRCON.XTL12M_EN = 1;
SYSCLK->PWRCON.OSC22M_EN = 1;
//
// /* Waiting for 12M Xtal stalble */
// while (DrvSYS_GetChipClockSourceStatus(E_SYS_XTL12M) != 1);
while (DrvSYS_GetChipClockSourceStatus(E_SYS_OSC22M) != 1);
/* Waiting for 12M Xtal stalble */
// while (DrvSYS_GetChipClockSourceStatus(E_SYS_XTL12M) != 1);
printf("+-------------------------------------------------------+\n");
printf("| M05xx I2C Driver Sample Code with EEPROM 24LC64 |\n");
printf("+------------------------------------------------------+\n");
/* Set I2C I/O */
DrvGPIO_InitFunction(E_FUNC_I2C);
/* Open I2C and set clock = 100Kbps */
DrvI2C_Open(100000);
/* Get I2C clock */
u32data = DrvI2C_GetClockFreq();
printf("I2C clock %d Hz\n", u32data);
/* Set I2C slave addresses */
DrvI2C_SetAddress(0, 0xa0, 0);
DrvI2C_SetAddress(1, 0x35, 0);
DrvI2C_SetAddress(2, 0x55, 0);
DrvI2C_SetAddress(3, 0x75, 0);
/* Enable I2C interrupt and set corresponding NVIC bit */
DrvI2C_EnableInt();
Device_Addr = 0x50;
while(1)
{
for (i = 0; i < 0x100; i++)
{
Tx_Data[0] = (uint8_t)((i & 0xFF00) >> 8);
Tx_Data[1] = (uint8_t)(i & 0x00FF);
Tx_Data[2] = (uint8_t)(Tx_Data[1] + 3);
DataLen = 0;
EndFlag = 0;
/* Install I2C call back function for write data to slave */
DrvI2C_InstallCallback(I2CFUNC, I2C_Callback_Tx);
/* I2C as master sends START signal */
DrvI2C_Ctrl(1, 0, 0, 0);
/* Wait I2C Tx Finish */
while (EndFlag == 0);
EndFlag = 0;
/* Uninstall I2C call back function for write data to slave */
DrvI2C_UninstallCallBack(I2CFUNC);
/* Install I2C call back function for read data from slave */
DrvI2C_InstallCallback(I2CFUNC, I2C_Callback_Rx);
DataLen = 0;
Device_Addr = 0x50;
DrvI2C_Ctrl(1, 0, 0, 0);
/* Wait I2C Rx Finish */
while (EndFlag == 0);
/* Compare data */
if (Rx_Data != Tx_Data[2])
{
printf("I2C Byte Write/Read Failed, Data 0x%x\n", Rx_Data);
return -1;
}
}
printf("I2C Access EEPROM Test OK\n");
/* Disable I2C interrupt and clear corresponding NVIC bit */
// DrvI2C_DisableInt();
/* Close I2C */
// DrvI2C_Close();
// return 0;
}
}
从机程序:
#include <stdio.h>
#include "Driver\DrvGPIO.h"
#include "Driver\DrvI2C.h"
#include "Driver\DrvSYS.h"
#define DBG
#ifdef DBG
#include "Driver\DrvUART.h"
#endif
/*---------------------------------------------------------------------------------------------------------*/
/* Global variables */
/*---------------------------------------------------------------------------------------------------------*/
uint8_t Device_Addr0;
volatile uint8_t EndFlag0 = 0;
volatile uint8_t EndFlag1 = 0;
uint8_t TransferBuffer[210] = {0};
uint8_t TransferIndex;
uint8_t ReceiveIndex;
extern uint8_t Receive_Buff[210];
extern void SysTimerDelay(uint32_t us);
extern uint32_t loaderImageBase;
extern uint32_t loaderImageLimit;
#define frameCNT 128
/*---------------------------------------------------------------------------------------------------------*/
/* I2C1 (Slave) Callback Function */
/*---------------------------------------------------------------------------------------------------------*/
void I2C1_Callback_Slave(uint32_t status)
{
printf("Slave Status 0x%x \n", status);
if ((status == 0x60) || (status == 0x68)) /* SLA+W has been received and ACK has been returned *///写EEPROM命令以收到,并且返回了ACK应答
{
DrvI2C_Ctrl( 0, 0, 1, 1);
}
else if (status == 0x80) /* DATA has been received and ACK has been returned *///数据以接收到 并返回了应答
{
DrvI2C_Ctrl( 0, 0, 1, 1);
}
else if ((status == 0xB0) || (status == 0xA8)) /* SLA+R has been received and ACK has been returned */ //读eeprom命令已经收到并返回应答
{
DrvI2C_WriteData(0x89);
DrvI2C_Ctrl( 0, 0, 1, 1);
}
else if (status == 0xB8) /* DATA has been transmitted and ACK has been received */ //数据以发送出去,并且应答已经收到
{
DrvI2C_WriteData(0X90);//(TransferBuffer[TransferIndex++]);
// if (TransferIndex >=(frameCNT+1))
// {
// TransferIndex = 0;
// EndFlag1=1;
// DrvI2C_Ctrl( 0, 0, 1, 0);
// }
// else
DrvI2C_Ctrl(0, 0, 1, 1);
}
else if (status == 0xC8) /*Last data has been transmited, ACK has been received*/
{
DrvI2C_Ctrl( 0, 0, 1, 1);
}
else if (status == 0x08)
{
DrvI2C_Ctrl( 0, 1, 1, 0);
}
else if (status == 0xC0) /* DATA has been transmitted and NACK has been received */
{
DrvI2C_Ctrl( 0, 0, 1, 1);
}
else if (status == 0xA0) /* STOP or Repeat START has been received */
{
DrvI2C_Ctrl( 0, 0, 1, 1);
}
else
{
printf("Slave Status 0x%x is NOT processed\n", status);
}
}
/*---------------------------------------------------------------------------------------------------------*/
/* Main Function */
/*---------------------------------------------------------------------------------------------------------*/
int32_t main (void)
{
uint32_t u32data, i;
UNLOCKREG();
SYSCLK->PWRCON.OSC22M_EN = 1;
while (DrvSYS_GetChipClockSourceStatus(E_SYS_OSC22M) != 1);
printf("+-------------------------------------------------------+\n");
printf("| M05xx I2C Driver Sample Code with EEPROM 24LC64 |\n");
printf("+------------------------------------------------------+\n");
/* Set I2C I/O */
DrvGPIO_InitFunction(E_FUNC_I2C);
printf("I2C clock %d Hz\n", u32data);
/* Set I2C slave addresses */
DrvI2C_SetAddress(0, 0xa0, 0);
// DrvI2C_SetAddress(1, 0x35, 0);
// DrvI2C_SetAddress(2, 0x55, 0);
// DrvI2C_SetAddress(3, 0x75, 0);
/* Enable I2C interrupt and set corresponding NVIC bit */
DrvI2C_EnableInt();
/* Set AA bit, I2C1 as slave (To simulate a 24LXX EEPROM) */
DrvI2C_Ctrl( 0, 0, 0, 1);
DrvI2C_EnableInt();
while(1)
{
u32data= DrvI2C_GetStatus();
printf("Slave Status 0x%x \n", u32data);
/* Enable I2C1 interrupt and set corresponding NVIC bit */
// DrvI2C_EnableInt();
/* Install I2C1 call back function for slave */
DrvI2C_InstallCallback( I2CFUNC, I2C1_Callback_Slave);
}
} |