介绍
IIC源码
软件用途
适用于89c52系列单片机的IIC代码。
实用环境
- 单片机晶振:11.0592MHz;
- 数据接口: SCL P21; SDA P20
使用说明
1.void i2c_sendbyte(uchar bt);
//从单片机向IIC总线发送一个字节数据
2.uchar i2c_recbyte();
//单片机从IIC总线上接受一个字节数据
3.bit i2c_readbyte(uchar com,uchar *dat);
//从指定地址设备上读出一个字节数据 //调用之前需要在文件头的 **SLAVEADDR** 宏定义处指定设备地址
i2c.c
/*---------------I2C协议程序----------------------
* 平台:keil u5 + STC89C52RC + YF-K1学习板
* 晶振:11.0592MHZ
*------------------------------------------------*/
#include <intrins.h>
#include "i2c.h"
#define SLAVEADDR 0x90 //定义器件地址
#define nops() do{_nop_();_nop_();_nop_();_nop_();_nop_();} while(0) //定义空指令
void delay(uint n)
{
while(n--);
}
/*------------------------------------------------
* 函数:i2c_start()
* 功能:启动i2c 起始信号
-------------------------------------------------*/
void i2c_start()
{
SCL = 1;
nops();
SDA = 1;
nops();
SDA = 0;
nops();
SCL = 0;
}
/*------------------------------------------------
* 函数:i2c_stop()
* 功能:停止i2c
-------------------------------------------------*/
void i2c_stop()
{
SCL = 0;
nops();
SDA = 0;
nops();
SCL = 1;
nops();
SDA = 1;
nops();
}
/*------------------------------------------------
* 函数:i2c_ACK(bit ck)
* 功能:ck为1时,发送应答信号ACK
* ck为0时,不发送ACK
-------------------------------------------------*/
void i2c_ACK(bit ck)
{
SDA=ck?0:1;
nops();
SCL = 1;
nops();
SCL = 0;
nops();
SDA = 1;
nops();
}
/*------------------------------------------------
* 函数:i2c_waitACK()
* 功能:返回为0时收到ACK
* 返回为1时没有收到ACK
-------------------------------------------------*/
bit i2c_waitACK()
{
SDA = 1;
nops();
SCL = 1;
nops();
if (SDA)
{
SCL = 0;
i2c_stop();
return 1;
}
else
{
SCL = 0;
return 0;
}
}
/*-------------------------------------------------
* 函数: i2c_sendbyte(uint bt)
* 功能: 将输入的一字节数据bt发送
-------------------------------------------------*/
void i2c_sendbyte(uchar bt)
{
uint i;
for(i=0; i<8; i++)
{
if (bt & 0x80)
SDA = 1;
else
SDA = 0;
nops();
SCL = 1;
bt <<= 1;
nops();
SCL = 0;
}
}
/*-------------------------------------------------
* 函数: i2c_recbyte( )
* 功能: 从总线上接收1字节数据
--------------------------------------------------*/
uchar i2c_recbyte()
{
uint dee,i;
for (i=0; i<8; i++)
{
SCL = 1;
nops();
dee <<= 1;
if (SDA)
dee = dee | 0x01;
SCL = 0;
nops();
}
return dee;
}
/*-------------------------------------------------
* 函数: i2c_readbyte
* 输入: addr
* 功能: 读出一字节数据
* 返回值: 0->成功 1->失败
-------------------------------------------------*/
bit i2c_readbyte(uchar com,uchar *dat)
{
i2c_start();
i2c_sendbyte(SLAVEADDR); //地址
if (i2c_waitACK())
return 1;
i2c_sendbyte(com); //控制字节
if (i2c_waitACK())
return 1;
i2c_start();
i2c_sendbyte(SLAVEADDR+1); //地址
if (i2c_waitACK())
return 1;
*dat = i2c_recbyte(); //读数据
i2c_ACK(0); //因为只读一字节数据,不发送ACK信号
i2c_stop();
return 0;
}
i2c.h
#ifndef __I2C_H
#define __I2C_H
#include "stc89c5xrc.h"
#define uchar unsigned char
#define uint unsigned int
sbit SCL = P2^1; //I2C 时钟
sbit SDA = P2^0; //I2C 数据
void i2c_start(); //启动IIC总线
void i2c_stop(); //停止IIC总线
void i2c_ACK(bit ck); //应答IIC总线
bit i2c_waitACK(); //等待应答
void i2c_sendbyte(uchar bt); //发送一个字节
uchar i2c_recbyte(); //接受一个字节
bit i2c_readbyte(uchar com,uchar *dat);//读出一个字节数据
#endif