0
点赞
收藏
分享

微信扫一扫

适用于89c52系列单片机的IIC代码

素锦时年_1b00 2022-02-18 阅读 53

介绍

IIC源码

软件用途

适用于89c52系列单片机的IIC代码。

实用环境

  1. 单片机晶振:11.0592MHz;
  2. 数据接口: 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
举报

相关推荐

0 条评论