半夏风 发表于 2013-9-3 21:58:02

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]
查看完整版本: ATmega16 IIC程序,通用