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

📄 i2c.c

📁 uccos2的的源码文件
💻 C
字号:
#define  IN_I2C
#include "S3C2410.h"
#include "Def2.h"


// I2C总线设置
//*********************************************************************
// register name: rIICCON
// -------------------------------------------------------------------
// description :
//
// multi-master IIC-BUS control register.
//
// 0x54000000,R/W,0x0x
// 7      6       5      4     3...0
// ENACK  CLKSRC  ENINT  PEND  TXCLK
// 0      0       0      0     xxxx
//
// ENACK: IIC-bus acknowledge enable bit. In Tx mode, the IICSDA is free
//        in the ack time. In Rx mode, the IICSDA is L in the ack time.
//        0 = Disable
//        1 = Enable
//
// CLKSRC: Source clock of IIC-bus transmit clock prescaler selection bit.
//         0 = IICCLK = fPCLK /16
//         1 = IICCLK = fPCLK /512
//
// ENINT: IIC-Bus Tx/Rx interrupt enable/disable bit.
//        0 = Disable
//        1 = Enable
//
// PEND: IIC-bus Tx/Rx interrupt pending flag. This bit cannot be written
//       to 1. When this bit is read as 1, the IICSCL is tied to L and the
//       IIC is stopped. To resume the operation, clear this bit as 0.
//       - when read:
//         0 = No interrupt pending
//         1 = Interrupt is pending
//       - when write:
//         0 = Clear pending condition and Resume the operation
//         1 = N/A (cannot be written to 1)
//
// TXCLK: IIC-Bus transmit clock prescaler. IIC-Bus transmit clock fre. is
//        determined by this 4-bit prescaler value, .i.e,
//        Tx clock = IICCLK/(IICCON[3:0]+1).
// -------------------------------------------------------------------
// setting:
// - enable ACK
// - IICCLK=PCLK/512=97,656.25Hz @ FCLK=200MHz,HCLK=100MHz,PCLK=50MHz
// - Tx clock = IICCLK/(3+1)= 24.414KHz @ IICCLK=PCLK/512=97,656.25Hz
// - enable interrupt
//*********************************************************************
#define   IICCON_DACK       ((1<<7) | (1<<6) | (1<<5) | (3<<0)) /* 使能ACK位,IICCLK=PCLK/512=97656.25 */
#define   IICCON_DNACK      ((0<<7) | (1<<6) | (1<<5) | (3<<0)) /* 中断使能(这样才能正确操作I2C) */


/*********************************************************************************************************
** Function name: InitI2C
** Descriptions : 初始化IIC总线
** Input : -
** Output: -
** Created Date : 2007-8-2 11:36上午
********************************************************************************************************/
void  InitI2C(void)
{
    // 设置管脚连接
    rGPECON = (rGPECON & 0x0FFFFFFF) | 0xA0000000;  // 设置I2C口使能
    rGPEUP = rGPEUP | 0xC000;                       // 禁止内部上拉电阻

    // 设置I2C控制寄存器 (使能ACK位时才能接收从机的应答位)
    rIICCON = IICCON_DACK;

    // 设置I2C为主机模式
    rIICSTAT = (3<<6)|(1<<4);

    // 从机地址 (作主机时没有用)
    rIICADD = 0x10;
}


/*********************************************************************************************************
** Function name: START_I2C
** Descriptions : 启动总线,发送从机地址
** Input : sla, 从机动地址(7bit)+R/W(1bit), 读写控制位是LSB.
** Output: 操作成功返回TRUE,仲载失败/无从机应答返回FALSE
** Created Date : 2007-8-2 12:59下午
********************************************************************************************************/
int  StartI2C(uint8 sla)
{
    uint32  i;

    rIICDS = sla;                           // 设置从机地址

    if(sla&0x01)                            // 写
    {
        rIICSTAT = (2<<6)|(1<<5)|(1<<4);    // 主接收模式,发送使能,启动总线
        rIICCON = IICCON_DACK;              // 若是重启总线,则需要有此操作
    }
    else                                    // 读
    {
        rIICSTAT = (3<<6)|(1<<5)|(1<<4);    // 主发送模式,发送使能,启动总线
    }

    while((rIICCON&0x10) == 0);             // 等待操作完成


    if((rIICSTAT&0x09) == 0)                // 判断操作是否成功 (总线仲裁和应答)
    {
        return(TRUE);
    }
    else                                    // 如果失败,则发送结束信号
    {
        if(sla&0x01) rIICSTAT = (2<<6)|(0<<5)|(1<<4);
          else  rIICSTAT = (3<<6)|(0<<5)|(1<<4);
        rIICCON = IICCON_DACK;

        for(i=0; i<5000; i++);              // 等待结束信号产生完毕
        return(FALSE);
    }
}



/*********************************************************************************************************
** Function name: I2C_SendByte
** Descriptions : 发送一字节数据,并接收应答位
** Input : dat,发送的数据
** Output: 操作成功返回TRUE,仲载失败/无从机应答返回FALSE
** Created Date : 2007-8-2 01:12下午
********************************************************************************************************/
int  I2C_SendByte(uint8 dat)
{
    uint32  i;

    rIICDS = dat;                           // 将数据写入I2C数据寄存器
    rIICCON = IICCON_DACK;                  // 清除中断标志,允许发送数据操作

    while((rIICCON&0x10) == 0);             // 等待操作完成

    
    if((rIICSTAT&0x09) == 0)                // 判断总线仲裁和从机应答
    {
        return(TRUE);
    }
    else                                    // 如果失败,则发送结束信号
    {
        rIICSTAT = (3<<6)|(0<<5)|(1<<4);
        rIICCON = IICCON_DACK;

        for(i=0; i<5000; i++);              // 等待结束信号产生完毕
        return(FALSE);
    }
}



/*********************************************************************************************************
** Function name: I2C_RcvByteNA
** Descriptions : 接上I2C总线上一字节数据,不发送应答位
** Input : dat, 用于接收数据的指针
** Output: 操作成功返回TRUE,仲载失败/无从机应答返回FALSE
** Created Date : 2007-8-2 01:18下午
********************************************************************************************************/
int  I2C_RcvByteNA(uint8 *dat)
{
    uint32  i;

    // 允许接收数据
    rIICCON = IICCON_DNACK;

    // 等待接收数据操作完成
    while((rIICCON&0x10) == 0);

    // 判断操作是否成功 (总线仲裁)
    if((rIICSTAT&0x08) != 0)
    {
        rIICSTAT = (2<<6)|(0<<5)|(1<<4);    // 发送结束信号
        rIICCON = IICCON_DACK;

        for(i=0; i<5000; i++);              // 等待结束信号产生完毕
        return(FALSE);
    }

    *dat = rIICDS;                          // 读取数据
    return(TRUE);
}



/*********************************************************************************************************
** Function name: I2C_RcvByteA
** Descriptions : 接上I2C总线上一字节数据,并发送应答位
** Input : dat, 用于接收数据的指针
** Output: 操作成功返回TRUE,仲载失败/无从机应答返回FALSE
** Created Date : 2007-8-2 01:29下午
********************************************************************************************************/
int  I2C_RcvByteA(uint8 *dat)
{
    uint32  i;

    // 允许接收数据
    rIICCON = IICCON_DACK;

    // 等待接收数据操作完成
    while((rIICCON&0x10) == 0);

    // 判断操作是否成功 (总线仲裁)
    if((rIICSTAT&0x08) != 0)
    {
        // 发送结束信号
        rIICSTAT = (2<<6)|(0<<5)|(1<<4);
        rIICCON = IICCON_DACK;

        for(i=0; i<5000; i++);      // 等待结束信号产生完毕
        return(FALSE);
    }

    *dat = rIICDS;      // 读取数据
    return(TRUE);
}



/*********************************************************************************************************
** Function name: STOP_I2C
** Descriptions : 结束总线
** Input : send, I2C当前模模式。主发送模式时为1,否则为0(主接收模式)
** Output: -
** Created Date: 2007-8-2 01:39下午
********************************************************************************************************/
void  StopI2C(uint8 send)
{
    uint32  i;

    if(send)
    {
        rIICSTAT = (3<<6)|(0<<5)|(1<<4);        // 发送结束信号
    }
    else
    {
        rIICSTAT = (2<<6)|(0<<5)|(1<<4);        // 发送结束信号
    }
    rIICCON = IICCON_DACK;
    for(i=0; i<5000; i++);                      // 等待结束信号产生完毕
}



/*********************************************************************************************************
** Function name: ISendStr
** Descriptions : 使用硬件I2C发送数据。
** Input : sla, 从机地址
**         suba, 器件子地址(第一字节用来表示子地址字节个数)
**         s, 发送数据缓冲区
**         no, 发送数据个数
** Output: 操作成功返回TRUE,仲载失败/无从机应答返回FALSE
** Created Date: 2007-8-2 01:51下午
********************************************************************************************************/
int  ISendStr(uint8 sla, uint8 *suba, uint8 *s, uint8 no)
{
    int  bak;

    sla = sla & 0xFE;
    if(!StartI2C(sla))
    {
        if(!StartI2C(sla)) return(FALSE);       // 启动总线,发送从机地址
    }

    // 发送器件子地址
    bak = *suba++;
    for(; bak>0; bak--)
    {
        if(!I2C_SendByte(*suba++)) return(FALSE);
    }

    // 发送数据
    for(; no>0; no--)
    {
        if(!I2C_SendByte(*s)) return(FALSE);
        s++;
    }

    StopI2C(1);     // 结束总线

    return(TRUE);
}



/*********************************************************************************************************
** Function name: IRcvStr
** Descriptions : 使用硬件I2C读取数据。
** Input : sla, 从机地址
*          suba, 器件子地址缓冲区指针(第一字节用来表示子地址字节个数)
*          s, 接收数据缓冲区
*          no, 接收数据个数
** Output: 操作成功返回TRUE,仲载失败/无从机应答返回FALSE
** Created Date : 2007-8-2 02:13下午
********************************************************************************************************/
int  IRcvStr(uint8 sla,uint8 *suba,uint8 *s,uint8 no)
{
    int  bak;

    bak = *suba++;  // 子地址个数
    if(bak > 0)
    {
        sla = sla & 0xFE;
        if(!StartI2C(sla))
        {
            if(!StartI2C(sla)) return(FALSE);   // 启动总线,发送从机地址(写)
        }

        // 发送器件子地址
        for(; bak>0; bak--)
        {
            if(!I2C_SendByte(*suba++)) return(FALSE);
        }
    }

    // 重启总线
    sla = sla | 0x01;
    if(!StartI2C(sla)) return(FALSE);       // 启动总线,发送从机地址(读)

    // 读取数据
    for(; no>1; no--)
    {
        if(!I2C_RcvByteA(s)) return(FALSE); // 发送数据
        s++;
    }
    if(!I2C_RcvByteNA(s)) return(FALSE);

    StopI2C(0);     // 结束总线

    return(TRUE);
}

/* end of file */

⌨️ 快捷键说明

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