我正在尝试将基于MCP23017 I2C的GPIO扩展器与nuvoton N76E003微控制器进行接口。我是在Keil C51开发的。
参考给出的例子和网上的一些参考资料,我编写了一个代码来控制MCP23017的功能。然而,我在I2C总线上没有得到任何响应。我用这个附加了我的代码。我被注释了代码,这样就更容易理解了。
我很高兴听到你们的积极评论和批评。谢谢。萨特
#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
#define regular_I2C_pins 0
#define alternate_I2C_pins 1
#define regular_I2C_GPIOs() do{P13_OpenDrain_Mode; P14_OpenDrain_Mode; clr_I2CPX;}while(0)
#define alternative_I2C_GPIOs() do{P02_OpenDrain_Mode; P16_OpenDrain_Mode; set_I2CPX;}while(0)
#define I2C_GPIO_Init(mode) do{if(mode != 0){alternative_I2C_GPIOs();}else{regular_I2C_GPIOs();}}while(0)
#define I2C_CLOCK 0x27
#define MCP23017_SLA 0x20
#define MCP23017_WR 0
#define MCP23017_RD 1
#define ERROR_CODE 0x78
void Init_I2C(void)
{
I2C_GPIO_Init(regular_I2C_pins);
I2CLK = I2C_CLOCK; //Set I2C clock rate
set_I2CEN; //Enable I2C hardware
}
void I2C_Error(void)
{
while (1);
}
void I2C_Process(void)
{
/* Step1 */
set_STA; /* Send Start bit to I2C device */
clr_SI;
while (!SI); //Check SI set or not
if (I2STAT != 0x08) //Check status value after every step
I2C_Error();
/* Step2 */
clr_STA; //STA=0
I2DAT = (MCP23017_SLA | MCP23017_WR);
clr_SI;
while (!SI); //Check SI set or not
if (I2STAT != 0x18)
I2C_Error();
/* Step3 */
I2DAT = 0x00; //address high for I2C EEPROM
clr_SI;
while (!SI); //Check SI set or not
if (I2STAT != 0x28)
I2C_Error();
/* Step4 */
I2DAT = 0x00; //address low for I2C EEPROM
clr_SI;
while (!SI); //Check SI set or not
if (I2STAT != 0x28)
I2C_Error();
/* Step5 */
I2DAT = (0x00); // Write to IODIRA register to declare port pins as output
clr_SI;
while (!SI);
if (I2STAT != 0x18)
I2C_Error();
I2DAT = (0x00); // Declare the pins as outputs
clr_SI;
while (!SI);
if (I2STAT != 0x18)
I2C_Error();
I2DAT = (0x00); // Write to IODIRB register to declare port pins as output
clr_SI;
while (!SI);
if (I2STAT != 0x18)
I2C_Error();
I2DAT = (0x00); // Declare the pins as outputs
clr_SI;
while (!SI);
if (I2STAT != 0x18)
I2C_Error();
I2DAT = (0x12); // Address port A
clr_SI;
while (!SI);
if (I2STAT != 0x18)
I2C_Error();
I2DAT = (0xFF); // Make port A pins high
clr_SI;
while (!SI);
if (I2STAT != 0x18)
I2C_Error();
I2DAT = (0x13); // Address port B
clr_SI;
while (!SI);
if (I2STAT != 0x18)
I2C_Error();
I2DAT = (0xFF); // Make port B pins high
clr_SI;
while (!SI);
if (I2STAT != 0x18)
I2C_Error();
/* Step6 */
do{
set_STO;
clr_SI;
set_STA; //Check if no ACK is returned by MCP23017
clr_SI;
while (!SI); //Check SI set or not
if (I2STAT != 0x08) //Check status value after every step
I2C_Error();
clr_STA;
I2DAT = (MCP23017_SLA | MCP23017_WR);
clr_SI;
while (!SI); //Check SI set or not
}while (I2STAT != 0x18);
/* Step7 */
set_STO;
clr_SI;
while (STO); /* Check STOP signal */
}
void main(void)
{
//Set_All_GPIO_Quasi_Mode;
Init_I2C(); //initial I2C circuit
I2C_Process();
while (1);
}发布于 2019-02-05 07:19:20
检查你的奴隶地址。应该是根据数据表,第15页
I2DAT = (((MCP23017_SLA | (A2 << 2) | (A1 << 1) | (A0 << 0)) << 1) | MCP23017_WR);https://stackoverflow.com/questions/54529282
复制相似问题