/*****************************************************************************
FileName : iic.c
Function : IIC通信协议
Author : mike
Email : [email protected]
Version : V1.0
Date : 2019-07-12
Note :
*****************************************************************************/
#include "iic.h"
void iic_delay(void)
{
u8 i = 10;
for (; i!=0; i--)
{
asm("nop");
}
}
void iic_delay_2(void)
{
u8 i = 15;
for (; i!=0; i--)
{
asm("nop");
}
}
void iic_start(void)
{
IIC_DATA_CLK_OUT();
IIC_DATA_CLK_HIGH();
iic_delay();
IIC_DATA_LOW();
iic_delay();
IIC_CLK_LOW();
}
//结束一次IIC通信
void iic_stop(void)
{
IIC_DATA_OUT();
IIC_DATA_LOW();
iic_delay_2();
IIC_CLK_HIGH();
iic_delay();
IIC_DATA_HIGH();
}
//IIC总线发送1byte
void iic_sendbyte(u8 val)
{
u8 i;
IIC_DATA_OUT();
for (i=8; i!=0; i--) {
if (val & BIT(7)) {
IIC_DATA_HIGH();
} else {
IIC_DATA_LOW();
}
iic_delay_2();
IIC_CLK_HIGH();
iic_delay();
IIC_CLK_LOW();
val <<= 1;
}
}
//IIC总线接收1byte
u8 iic_getbyte(void)
{
u8 i;
u8 val = 0;
IIC_DATA_IN();
for (i=8; i!=0; i--) {
iic_delay_2();
IIC_CLK_HIGH();
iic_delay();
val <<= 1;
if (IIC_DATA_IS_HIGH()) {
val |= BIT(0);
}
IIC_CLK_LOW();
}
return val;
}
//IIC总线发送ACK
void iic_sendack(void)
{
IIC_DATA_OUT();
IIC_DATA_LOW();
iic_delay_2();
IIC_CLK_HIGH();
iic_delay();
IIC_CLK_LOW();
}
//IIC总线发送NACK
void iic_sendnack(void)
{
IIC_DATA_OUT();
IIC_DATA_HIGH();
iic_delay_2();
IIC_CLK_HIGH();
iic_delay();
IIC_CLK_LOW();
}
//IIC总线获取ACK状态
bool iic_getack(void)
{
bool ack = false;
IIC_DATA_IN();
iic_delay_2();
IIC_CLK_HIGH();
iic_delay();
if (!IIC_DATA_IS_HIGH()) {
ack = true;
}
IIC_CLK_LOW();
return ack;
}
#ifndef IIC_H
#define IIC_H
#define IIC_IO_SET
#define IIC_DATA 6 //P16
#define IIC_CLK 3 //P33
#define IIC_DATA_CLK_OUT() //设为输出,关闭上拉 delay(10)
#define IIC_DATA_IN() //设为输入,打开上拉
#define IIC_DATA_OUT() //设为输出,打开上拉
#define IIC_DATA_CLK_HIGH() P1 |= BIT(IIC_DATA);P3 |= BIT(IIC_CLK);
#define IIC_DATA_HIGH() P1 |= BIT(IIC_DATA)
#define IIC_DATA_LOW() P1 &= ~BIT(IIC_DATA)
#define IIC_CLK_HIGH() P3 |= BIT(IIC_CLK)
#define IIC_CLK_LOW() P3 &= ~BIT(IIC_CLK)
#define IIC_DATA_IS_HIGH() (P1 & BIT(IIC_DATA))
void iic_start(void);
void iic_stop(void);
void iic_sendbyte(u8 val);
u8 iic_getbyte(void);
void iic_sendack(void);
void iic_sendnack(void);
bool iic_getack(void);
#endif