📄 i2c.c
字号:
//**********************I2C标准代码**************************
/*****使用接口说明*****
1.在宏定义中修改GPIO口名称;
2.在宏定义中修改I2C_ADDR的值,该值是使用芯片的写地址;
3.单次读函数是i2c_read_byte,单次写函数是i2c_write_byte;
4.若要使用连续读方式,调用i2c_read_byte_cont。
读出数据放在全局变量整形数组i2c_read_result[CONT_READ_NUM]当中,
读寄存器的数目由宏定义CONT_READ_NUM确定,按需要修改;
5.若要使用连续写方式,调用i2c_write_byte_cont。
待写数据放在全局变量整形数组i2c_write_regdata[CONT_WRITE_NUM]当中,
写寄存器数的数目由宏定义CONT_WRITE_NUM确定,按需要修改。
*/
//************************宏定义*****************************
#define SDA_H M_DLGpioAssertLine(GPIO_9)
#define SDA_L M_DLGpioDeassertLine(GPIO_9)
#define SCL_H M_DLGpioAssertLine(GPIO_13)
#define SCL_L M_DLGpioDeassertLine(GPIO_13)
#define I2C_ADDR 0x20
#define SDA_INPUT_DATA DLGpioReadInputLine(GPIO_9)
#define SDA_INPUT_MODE DlGpioConfigure(GPIO_9, PIN_MODE_NORMAL, GPIO_INPUT, ACTIVE_HIGH)
#define SDA_OUTPUT_MODE DlGpioConfigure(GPIO_9, PIN_MODE_NORMAL, GPIO_OUTPUT, ACTIVE_HIGH)
#define SCL_OUTPUT_MODE DlGpioConfigure(GPIO_13, PIN_MODE_NORMAL, GPIO_OUTPUT, ACTIVE_HIGH)
#define CONT_WRITE_NUM 10
#define CONT_READ_NUM 10
//**************************************************************
//************************子函数列表****************************
void i2c_GPIO_init(void);
void i2c_start(void);
void i2c_stop(void);
Boolean i2c_getack(void);
void i2c_sendack(void);
void i2c_sendnoack(void);
void i2c_send(int iicd);
int i2c_read(void);
void i2c_delay(void);
//**************************************************************
//********************主调函数及全局读写数组列表****************
//**单次读写**
Boolean i2c_write_byte(int i2c_addr,int i2c_reg,int i2c_data); //单次写寄存器
int i2c_read_byte(int i2c_addr,int i2c_reg); //单次读寄存器
//**连续读写**
int i2c_write_regdata[CONT_WRITE_NUM]; //存贮待写的寄存器值
Boolean i2c_write_byte_cont(int i2c_addr,int i2c_base_reg,int num_reg); //连续写寄存器 未验证
int i2c_read_result[CONT_READ_NUM]; //存贮读出的寄存器值
void i2c_read_byte_cont(int i2c_addr,int i2c_base_reg,int num_reg); //连续读寄存器
//**************************************************************
//****************************函数名细**************************
/*********************************************************************
Name : i2c_GPIO_init
Function : I2C bus released, be ready to start bus
Input : void
Return : None
Time : 2005-08-30
*************************************************************************/
void i2c_GPIO_init(void)
{
SDA_OUTPUT_MODE;
SCL_OUTPUT_MODE;
i2c_stop();
}
/*********************************************************************
Name : i2c_write_byte
Function : write a byte to codec
Input : int i2c_addr,int i2c_reg,int i2c_data
Return : TRUE or FALSE
Time : 2005-08-30
*************************************************************************/
Boolean i2c_write_byte(int i2c_addr,int i2c_reg,int i2c_data)
{
i2c_start();
i2c_send(i2c_addr);
if(!i2c_getack())
{
i2c_send(i2c_reg);
if(!i2c_getack())
{
i2c_send(i2c_data);
if(!i2c_getack())
{
i2c_stop();
return(TRUE);
}
else
i2c_stop();
return(FALSE);
}
else
i2c_stop();
return(FALSE);
}
else
i2c_stop();
return(FALSE);
}
/*********************************************************************
Name : i2c_write_byte_cont 未验证
Function : write a byte to codec
Input : int i2c_addr,int i2c_base_reg,int* i2c_data,int num_reg
Return : TRUE or FALSE
Time : 2005-08-30
*************************************************************************/
Boolean i2c_write_byte_cont(int i2c_addr,int i2c_base_reg,int num_reg)
{
int i;
i2c_start();
i2c_send(i2c_addr);
if(!i2c_getack())
{
i2c_send(i2c_base_reg);
if(!i2c_getack())
{
for(i=0;i<num_reg;i++)
{
i2c_send(i2c_write_regdata[i]);
if(i2c_getack())
{
i2c_stop();
return(FALSE);
}
}
i2c_stop();
return(TRUE);
}
else
i2c_stop();
return(FALSE);
}
else
i2c_stop();
return(FALSE);
}
/*********************************************************************
Name : i2c_read_byte
Function : read a byte from codec
Input : int i2c_addr,int i2c_reg
Return : i2c_data
Time : 2005-08-30
*************************************************************************/
int i2c_read_byte(int i2c_addr,int i2c_reg)
{
int result;
i2c_start(); //START
i2c_send(i2c_addr); //写I2C写地址
i2c_getack();
i2c_send(i2c_reg);
i2c_getack();
i2c_start(); //RE-START
i2c_send((i2c_addr| 0x01)); //写I2C读地址
i2c_getack();
result=i2c_read();
i2c_sendnoack();
i2c_stop();
return(result);
}
/*********************************************************************
Name : i2c_read_byte_cont
Function : read continuous byte from codec
Input : int i2c_addr,int i2c_base_reg,int num_reg
Return : none
Time : 2005-08-30
*************************************************************************/
void i2c_read_byte_cont(int i2c_addr,int i2c_base_reg,int num_reg)
{
int i;
// int* p_temp = malloc(num_reg);
i2c_start(); //START
i2c_send(i2c_addr); //写I2C写地址
i2c_getack();
i2c_send(i2c_base_reg);
i2c_getack();
i2c_start(); //RE-START
i2c_send((i2c_addr| 0x01)); //写I2C读地址
i2c_getack();
for(i=0;i<num_reg;i++)
{
i2c_read_result[i] = i2c_read();
if(i==(num_reg-1))
{
i2c_sendnoack();
i2c_stop();
// free(p_temp);
return;
}
i2c_sendack();
}
}
/*********************************************************************
I2C timeing-production functions listed below
*************************************************************************/
void i2c_start()
{
SDA_H;
i2c_delay();
SCL_H;
i2c_delay();
SDA_L;
i2c_delay();
SCL_L;
}
void i2c_stop()
{
SDA_L;
i2c_delay();
SCL_H;
i2c_delay();
SDA_H;
}
Boolean i2c_getack()
{
Boolean i2c_ack;
SDA_INPUT_MODE;
SCL_H;
i2c_ack=SDA_INPUT_DATA;
/*调试用
if(i2c_ack==TRUE) //no answer
{
printf("no ACK");
}
else //answer
{
printf("ACK");
}
*/
SCL_L;
SDA_OUTPUT_MODE;
return(i2c_ack);
}
void i2c_sendack()
{
SDA_OUTPUT_MODE;
SDA_L;
i2c_delay();
SCL_H;
i2c_delay();
SCL_L;
SDA_INPUT_MODE;
}
void i2c_sendnoack()
{
SDA_OUTPUT_MODE;
SDA_H;
i2c_delay();
SCL_H;
i2c_delay();
SCL_L;
i2c_delay();
SDA_L;
}
void i2c_send(int i2c_data)
{
int i;
for(i=0;i<8;i++)
{
if(((i2c_data)& (0x80))>0) //send 1
{
SDA_H;
i2c_delay();
SCL_H;
i2c_delay();
SCL_L;
SDA_L; //不加此句会产生半高电平(原因是低电平响应位提前出现,会造成短时间短路)
}
else //send 0
{
SDA_L;
i2c_delay();
SCL_H;
i2c_delay();
SCL_L;
}
i2c_data<<=1; //RLC
}
}
int i2c_read(void)
{
int i,temp,result=0;
SDA_INPUT_MODE;
for(i=0;i<8;i++)
{
i2c_delay();
SCL_H;
i2c_delay();
temp=SDA_INPUT_DATA;
if(temp==1) //read 1
{
result<<=1;
result|=1;
i2c_delay();
SCL_L;
}
else // read 0
{
result<<=1;
i2c_delay();
SCL_L;
}
}
SDA_OUTPUT_MODE;
return(result);
}
void i2c_delay(void)
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -