加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
iic.c 3.42 KB
一键复制 编辑 原始数据 按行查看 历史
dk鲁晓东 提交于 2020-02-24 19:50 . IIC驱动
#include "iic.h"
/////////////////////////////////////
//延时根据实际情况来调
void IIC_delay(void)// 时序的需要,IIC对信号持续时间有要求
{
u8 i=(Main_Fosc_KHZ/1000)+1; //i=22+1=23这里可以优化速度,经测试最低到5还能写入
while(i--) //该结构为12,个T+5*(i=23)*T=130T=5us
{
NOP5(); //时间可以修改
}
}
/**********************************************
//IIC Start
SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号
**********************************************/
u8 IIC_Start(void)
{
SDA_H;
SCL_L;
IIC_delay();//初始状态
SCL_H;
IIC_delay();//CLK拉高后,大于4.7us,SDA仍“1”,否则算总线忙
if(!SDA_read)return FALSE; //SDA线为低电平则总线忙,退出
SDA_L;//给下降沿,拉低数据
IIC_delay();//大于4us后,SDA仍然为0 这里延时为5us,否则不能启动
if(SDA_read) return FALSE; //SDA线为高电平则总线出错,退出
SCL_L;// 间隔下一个脉冲时间大于4us
IIC_delay();
return TRUE;
}
/**********************************************
//IIC Stop
//SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号
**********************************************/
void IIC_Stop(void)
{
SCL_H;//CLK为高电平
SDA_L;
IIC_delay();//数据线为低电平4.7us
SDA_H; //给上升沿
IIC_delay();//高电平持续4.7us
SCL_L;
IIC_delay();//CLK为低电平结束
// SCL = low;
// delay_us(1);
// SDA = low;//初始状态
//
// SCL = high; // 高电平期间
// delay_us(5);// 15us >> 4.7us
// SDA = high;//上升沿
//
// delay_us(3);
//
}
/////////////////////////////////////
//I2C应答,在CLK高电平4.7us时间内,SDA=0稳定
void IIC_Ack(void)
{
SDA_L;
SCL_H;//clk高电平大于4.7us期间SDA稳定
IIC_delay();
SCL_L;
SDA_H; //释放总线
}
/////////////////////////////////////
//I2C不应答
void IIC_NoAck(void)
{
SDA_H;
SCL_H;//clk高电平大于4.7us期间SDA稳定
IIC_delay();
SCL_L;
SDA_L;
}
/////////////////////////////////////
//I2C询问ACK
bit IIC_WaitAck(void) //返回为:=1有ACK,=0无ACK
{
SDA_H; //防止被线与
SCL_H; //高电平期间
IIC_delay();
if(SDA_read)
{
SCL_L;
return FALSE;
}
SCL_L;
return TRUE;
}
/////////////////////////////////////
//数据从高位到低位 写
bit IIC_SendByte(u8 SendByte)
{
bit sendok=0;
u8 i=8;
while(i--)
{ if(SendByte&0x80)//先传输高位
SDA_H;
else
SDA_L;
SendByte<<=1;//左移,下一个准备
SCL_H; //CLK高电平
IIC_delay();//持续4.7us
SCL_L;//
IIC_delay();
}
sendok=IIC_WaitAck();
// SDA=1;//释放数据 //如果不需要waitack
// delay_us(3);
// SCL=1;// 从机回复ACK的条件
// delay_us(3);
// SCL=0;// 释放CLK
// delay_us(6);
return sendok;
}
/////////////////////////////////////
//数据从高位到低位 读
u8 IIC_ReceiveByte(void)
{
u8 i=8;
u8 ReceiveByte=0;
SDA_H; //防止线与
while(i--)
{
ReceiveByte<<=1; //最高位进来,依次左移
SCL_H;
IIC_delay(); //高电平期间读数据
if(SDA_read)
{
ReceiveByte|=0x01;
}
SCL_L;//结束1位传送
IIC_delay();
}
SDA_H;
//随后发应答,考虑到多个数据
IIC_Ack();
return ReceiveByte;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化