ATmega16 IIC程序,通用
本帖最后由 半夏风 于 2013-9-3 22:00 编辑#ifndef _IIC_H_
#define _IIC_H_
/*--------------------------- H E A D E R S----------------------------*/
#include "../Headers/Global.h" //包含头文件,自己创建下
/*模拟IIC端口输出输入定义*/
#define IIC_SCL (2)
#define IIC_SDA (3)
//#define IIC_INT (2)
#define IIC_PORT PORTB
#define IIC_DDR DDRB
#define IIC_PIN PINB
#define IIC_SDA_HIGH SetBit(IIC_PORT,IIC_SDA)
#define IIC_SDA_LOW ClrBit(IIC_PORT,IIC_SDA)
#define IIC_SCL_HIGH SetBit(IIC_PORT,IIC_SCL)
#define IIC_SCL_LOW ClrBit(IIC_PORT,IIC_SCL)
#define IIC_SDA_Read (IIC_PIN & (1<<IIC_SDA))
#define IIC_SCL_Read (IIC_PIN & (1<<IIC_SCL))
/*---------------------------F U N C T I O N S----------------------------*/
void IIC_Init(void);
extern unsigned char IIC_Start(void);
extern void IIC_Stop(void);
extern void IIC_Ack(void);
extern void IIC_NoAck(void);
extern unsigned char IIC_WaitAck(void);
extern void IIC_SendByte(unsigned char SendByte); //数据从高位到低位//
extern unsigned char IIC_ReadByte(void);
extern unsigned char IIC_SingleWrite(UINT8 Slave_Address,UINT8 REG_Address,UINT8 REG_data);
extern unsigned char IIC_SingleRead(UINT8 Slave_Address,unsigned char REG_Address);
#endif
/*********************.C程序********************************/
#include "IIC.h"
/**********************************************************
Function Name: IIC_Init
Description: IIC初始化
Inputs: None
Outputs: None
Notes:
***********************************************************/
void IIC_Init(void)
{
//ClrBit(IIC_DDR, IIC_INT); //中断端口输入
SetBit(IIC_DDR, IIC_SCL); //时钟线输出
SetBit(IIC_DDR, IIC_SDA); //数据线输出
SetBit(IIC_PORT,IIC_SCL); //时钟线拉高
SetBit(IIC_PORT,IIC_SDA); //数据线拉高
}
/**********************************************************
Function Name: Start
Description: IIC开始
Inputs:None
Outputs: None
Notes:
当SCL为高电平时,SDA由高变低表示开始
***********************************************************/
unsigned char IIC_Start(void)
{
IIC_SDA_HIGH; //SDA先拉低
IIC_SCL_HIGH;
Delay_us(10);
if (!IIC_SDA_Read) return FALSE; //SDA线为低电平则总线忙,退出
IIC_SDA_LOW; //SDA再拉低
Delay_us(10);
if (IIC_SDA_Read) return FALSE; //SDA线为高电平则总线出错,退出
IIC_SCL_LOW; //SCL再拉低
Delay_us(10);
return TRUE;
}
/**********************************************************
Function Name: Stop
Description: IIC结束
Inputs:None
Outputs: None
Notes:
当SCL为高电平时,SDA由低到高表示终止
***********************************************************/
void IIC_Stop(void)
{
//IIC_SCL_LOW; //SCL先拉低
//Delay_us(10);
IIC_SDA_LOW; //SDA拉低
Delay_us(10);
IIC_SCL_HIGH; //SCL拉高
Delay_us(10);
IIC_SDA_HIGH; //SDA拉高,表示终止
Delay_us(10);
}
/**********************************************************
Function Name: IIC_Ack
Description:主机发送应答信号
Inputs:None
Outputs:None
***********************************************************/
void IIC_Ack(void)
{
IIC_SCL_LOW;
Delay_us(10);
IIC_SDA_LOW;
Delay_us(10);
IIC_SCL_HIGH;
Delay_us(10);
IIC_SCL_LOW;
Delay_us(10);
}
/***********************************************************
Function Name: IIC_NoAck
Description:主机发送非应答信号
Inputs:None
Outputs:None
***********************************************************/
void IIC_NoAck(void)
{
IIC_SCL_LOW;
Delay_us(10);
IIC_SDA_HIGH;
Delay_us(10);
IIC_SCL_HIGH;
Delay_us(10);
IIC_SCL_LOW;
Delay_us(10);
}
/**********************************************************
Function Name: IIC_WaitAck
Description:主机等待从机发送应答信号
Inputs:None
Outputs:None
Return:主机是否接收到从机应答,返回为:=1有ACK,=0无ACK
***********************************************************/
unsigned char IIC_WaitAck(void)
{
IIC_SCL_LOW; //SCL为低,由低变高读应答
Delay_us(10);
IIC_SDA_HIGH; //接收模式先把SDA拉高
Delay_us(10);
ClrBit(IIC_DDR,IIC_SDA); //把SDA改变为输入
Delay_us(10);
IIC_SCL_HIGH; //SCL变为高
Delay_us(10);
if (IIC_SDA_Read)
{
IIC_SCL_LOW;
Delay_us(10);
return FALSE;
}
IIC_SCL_LOW;
Delay_us(10);
SetBit(IIC_DDR,IIC_SDA); //把SDA改变为输出
Delay_us(10);
return TRUE;
}
/**********************************************************
Function Name: IIC_SendByte
Description: 主机发送一个字节给从机
Inputs:要发送的字节
Outputs: None
Notes:
***********************************************************/
void IIC_SendByte(unsigned char SendByte) //数据从高位到低位//
{
unsigned char i=8;
while (i--)
{
IIC_SCL_LOW;
Delay_us(10);
if (SendByte & 0x80)
IIC_SDA_HIGH;
else
IIC_SDA_LOW;
SendByte <<=1;
Delay_us(10);
IIC_SCL_HIGH;
Delay_us(10);
}
IIC_SCL_LOW;
}
/**********************************************************
Function Name: ReadByte
Description: 主机从从机读一个字节
Inputs:None
Outputs: 读回的数据
Notes:
从总线读取一个字节的数据,数据从高位到低位
***********************************************************/
unsigned char IIC_ReadByte(void)
{
unsigned char i=8;
unsigned char rec_byte=0;
IIC_SDA_HIGH; //接收模式先把SDA拉高
while (i--)
{
rec_byte <<=1;
IIC_SCL_LOW;
Delay_us(10);
IIC_SCL_HIGH;
Delay_us(10);
if (IIC_SDA_Read)
{
rec_byte |=0x01;
}
}
IIC_SCL_LOW;
return rec_byte;
}
/**********************************************************
Function Name: IIC_SingleWrite
Description: IIC 单字节写入
Inputs:UINT8 Slave_Address,UINT8 REG_Address,UINT8 REG_data
Outputs: None
Notes:
IIC向目标从机发送一个字节的数据
Slave_Address 从机地址
reg_add 目标从机寄存器
out_bye 发送的数据
***********************************************************/
unsigned char IIC_SingleWrite(UINT8 Slave_Address,UINT8 REG_Address,UINT8 REG_data)
{
if (!IIC_Start()) return FALSE;
IIC_SendByte(Slave_Address); //发送设备地址+写信号//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址
if (!IIC_WaitAck()) {IIC_Stop();return FALSE;}
IIC_SendByte(REG_Address); //设置低起始地址
IIC_WaitAck();
IIC_SendByte(REG_data);
IIC_WaitAck();
IIC_Stop();
Delay_us(10);
return TRUE;
}
/**********************************************************
Function Name: IIC_SingleRead
Description: IIC 单字节读取
Inputs:UINT8 Slave_Address,UINT8 REG_Address,UINT8 REG_data
Outputs: None
Notes:
IIC向目标从机读取一个字节的数据
Slave_Address 从机地址
reg_add 目标从机寄存器
out_bye 发送的数据
***********************************************************/
unsigned char IIC_SingleRead(UINT8 Slave_Address,unsigned char REG_Address)
{
unsigned char REG_data;
if (!IIC_Start()) return FALSE;
IIC_SendByte(Slave_Address); //发送设备地址+写信号//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址 if (!IIC_WaitAck()) {IIC_Stop(); return FALSE;}''
if (!IIC_WaitAck()) {IIC_Stop();return FALSE;}
IIC_SendByte(REG_Address); //设置低起始地址// Test=0
IIC_WaitAck();
IIC_Start();
IIC_SendByte(Slave_Address+1);/**从机读地址比写地址多1**/
IIC_WaitAck();
REG_data = IIC_ReadByte();
IIC_NoAck();
IIC_Stop();
Delay_us(10);
return REG_data;
}
页:
[1]