⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.c

📁 LED条屏显示程序,但是对初学者
💻 C
字号:
//ICC-AVR application builder : 2005-11-12 17:11:59
// Target : M16
// Crystal: 8.0000Mhz
// copyright:鲁军波(endylu)
// www.shop34612283.taobao.com
// www.adembed.com
#include <iom16v.h>
#include <macros.h>
#include "main.h"


//=======================================================================
//初始化端口
void I2C_Ini(void)
{
	i2c_ddr|=(1<<SCL);			//SCK为输出
	i2c_ddr|=(1<<SDA);		    //SDA为双向的,先设置为输出


}
//=======================================================================
//启动总线。根据IIC协议,SCL为1时,SDA从1转变为0。
void IICStart(void)
{   SCL_0;
	SDA_1;
	SCL_1;
	SDA_0;
	SCL_0;
}
//=======================================================================
//停止IIC总线。根据IIC协议,SCL为1时,SDA从0转变为1。
void IICStop(void)
{
	SCL_0;
	SDA_0;
	SCL_1;
	SDA_1;
	//SCL_0;
}
//=======================================================================
//检查应答位,向I2C写数据时,I2C设备(EEPROM)正常接受到数据后在第9周期发出0应答,
//如果不正常接受到数据,则不以0应答而进入待命状态。
//写数据后需检查I2C设备是否有0应答。
unsigned char IICRecAck(void)
{
	uint8 ack;

	SCL_0;
	SDA_0;
	SCL_1;
	
	i2c_ddr&=~(1<<SDA);			//设置SDA为输入
	i2c_port|=1<<SDA;			    //上拉
	ack=(i2c_pin & (1<<SDA));		//读SDA应答位
	i2c_ddr|=(1<<SDA);			    //恢复为输出
	
	SCL_0;
	return(ack);
}
//=======================================================================
//从IIC总线上读数据。
unsigned char IICReceiveByte(void)
{
	uint8 receivebyte=0,i=8;

	i2c_ddr&=~(1<<SDA);			    //设置SDA为输入
	i2c_port|=1<<SDA;		            //上拉
	i2c_port&=~(1<<SCL);
	
	while(i--)
	{
		SCL_1;
		receivebyte <<= 1;
		if(i2c_pin & (1<<SDA)) receivebyte |= 1;
		SCL_0;
	}
	
	i2c_ddr|=(1<<SDA);			       //恢复SDA为输出
	return(receivebyte);
}


//=======================================================================
//对IIC总线产生应答。读I2C设备时,如果下一步还要读则产生0应答。
void IICACK(void)
{
	SDA_0;
	SCL_1;
	SCL_0;
	SDA_1;
}
//=======================================================================
//不对IIC总线产生应答。读I2C设备时,如果下一步不需要读则产生1应答(即不应答)。
void IICNoAck(void)
{
	SDA_1;
	SCL_1;
	SCL_0;
}
//=======================================================================
//向IIC总线写数据。SCL=0时SDA的数据可改变,SCL=1时需保持SDA数据稳定。
void IICSendByte(unsigned char sendbyte)
{
	uint8 j=8;
	for(;j>0;j--)
	{
		SCL_0;
		
		if(sendbyte&0x80)	SDA_1		//SCL=0时写数据到SDA 
		else	            SDA_0
		  
		sendbyte<<=1;
		
		SCL_1;
	}
	SCL_0;
}

//=======================================================================
//通过I2C读STA013
unsigned char sta_ReadDevice(unsigned char subAddr,uint8 device)
{   
	uint8 data,ErrorCount=10;
	//Delay_us(1200);
	
	while(ErrorCount--)
	{
		IICStart();
		IICSendByte(device);
		
		if(IICRecAck()) continue;			//如果为非0应答,重复写
		
 		IICSendByte(subAddr);	
 		if(IICRecAck()) continue;	//如果为非0应答,重复写
      	IICStart();
		IICSendByte(device | 0x01);	
		if(IICRecAck()) continue;
		
		
		data=IICReceiveByte();        //读数据,并发出1应答,表示不再读。
		IICNoAck();
		break;
	}
	IICStop();	
	return data;
}

//=======================================================================
//通过I2C向STA013发送数据
void i2c_Write(unsigned char subAddr,unsigned char device,unsigned char data)
{
	uint8 ErrorCount=10;
	
	while(ErrorCount--)
	{
		IICStart();
		IICSendByte(device);	
		if(IICRecAck()) continue;			//如果为非0应答,重复写
 		IICSendByte(subAddr);	
 		if(IICRecAck()) continue;	//如果为非0应答,重复写
		
		IICSendByte(data);
   		IICACK();
   		
   		break;
    }
	
    IICStop();
	//Delay_us(1200);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -