/****************************************Copyright (c)**************************************************
**                               广州周立功单片机发展有限公司
**                                     研    究    所
**                                        产品一部
**
**                                 http://www.zlgmcu.com
**
**--------------文件信息--------------------------------------------------------------------------------
**文   件   名: I2c.c
**创   建   人: 陈明计
**最后修改日期: 2003年7月21日
**描        述: μCOS-II下LPC210x的I2c主模式底层驱动
**
**--------------历史版本信息----------------------------------------------------------------------------
** 创建人: 陈明计
** 版  本: v1.0
** 日 期: 2003年7月8日
** 描 述: 原始版本
**
**------------------------------------------------------------------------------------------------------
** 修改人: 陈明计
** 版  本: v1.1
** 日 期: 2003年7月21日
** 描 述: 根据正式文档更改寄存器名
**
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人:
** 日 期:
** 描 述:
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/   

#define IN_I2C
#include "config.h"
static uint8 *I2cBuf;
static OS_EVENT *I2cSem;
static OS_EVENT *I2cMbox;
static int16 I2cNbyte;
static uint8 I2cAddr;   

#define I2C_WRITE_END       1           /* 写完成   */
#define I2C_READ_END        2           /* 读完成   */
#define I2C_NOT_GET_BUS     4           /* 丢失仲裁 */
#define I2C_ACK_ERR         8           /* 接收ACK错误 */    

/*********************************************************************************************************
** 函数名称: I2cInit
** 功能描述: 初始化I2c(主模式)
** 输 入: FI2c:I2c总线频率
**
** 输 出:TRUE  :成功
**        FALSE:失败
** 全局变量: I2cSem,I2cMbox
** 调用模块: OSSemCreate
**
** 作 者: 陈明计
** 日 期: 2003年7月8日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陈明计
** 日 期: 2003年7月10日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陈明计
** 日 期: 2003年7月21日
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 I2cInit(uint32 FI2c)
{
    VICIntEnClr =  << ;                           /* 禁止能I2c中断 */
    )
    {
        PINSEL0 = (PINSEL0 & 0xffffff0f) | 0x50;    /* 选择管脚为I2c */
        I2CONCLR = 0x6C;                            /* 清除控制寄存器 */
        I2SCLH = (Fpclk / FI2c + ) / ;            /* 设置高电平时间 */
        I2SCLL = (Fpclk / FI2c) / ;                /* 设置低电平时间 */
        I2cSem = OSSemCreate();                    /* 信号量用于互斥操作总线 */
        I2cMbox = OSMboxCreate(NULL);               /* 消息邮箱用于中断向任务传递操作结果 */
        if (I2cMbox == NULL)
        {
            return FALSE;
        }
        if (I2cSem != NULL)
        {
            return TRUE;
        }
    }
    return FALSE;
}   

/*********************************************************************************************************
** 函数名称: __I2cWrite
** 功能描述: 读I2C,但不发送STOP信号
** 输 入: Addr:从机地址
**        Data:将要写的数据
**        写的数据数目
** 输 出:发送的数据字节数
**
** 全局变量: I2cAddr,I2cNbyte,I2cBuf
** 调用模块: OSMboxPend
**
** 作 者: 陈明计
** 日 期: 2003年7月8日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陈明计
** 日 期: 2003年7月21日
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 __I2cWrite(uint8 Addr, uint8 *Data, int16 NByte)
{
    uint8 err;
    unsigned int Rt;   

    I2cAddr = Addr & 0xfe;                              /* 存储发送地址 */
    I2cNbyte = NByte;                                   /* 存储写字节数 */
    I2cBuf = Data;                                      /* 存储写的数据的指针 */
    I2CONSET = 0x24;                                    /* 设置为主机,并启动总线 */   

    Rt = (unsigned , &err);   /* 等待操作结束 */
    return Rt;
}   

/*********************************************************************************************************
** 函数名称: I2cWrite
** 功能描述: 向I2C从器件写数据
** 输 入: Addr:从机地址
**        Data:指向将要写的数据的指针
**        NByte:写的数据数目
** 输 出:发送的数据字节数
**
** 全局变量: I2cSem,I2cNbyte
** 调用模块: OSSemPend,__I2cWrite,OSSemPost
**
** 作 者: 陈明计
** 日 期: 2003年7月8日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陈明计
** 日 期: 2003年7月10日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陈明计
** 日 期: 2003年7月21日
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint16 I2cWrite(uint8 Addr, uint8 *Data, int16 NByte)
{
    uint8 err;   

    OSSemPend(I2cSem, , &err);   

    I2CONCLR = 0x6C;
    I2CONSET = 0x40;                            /* 使能I2c */
    VICIntEnable =  << ;                      /* 使能I2c中断 */   

    if (__I2cWrite(Addr, Data, NByte) == I2C_WRITE_END)
    {
        I2CONSET =  << ;                      /* 发送停止信号 */
        I2CONCLR = 0x28;                        /* 清除标志 */
    }   

    VICIntEnClr =  << ;                       /* 禁止能I2c中断 */   

    OSSemPost(I2cSem);
    return (NByte - I2cNbyte);
}   

/*********************************************************************************************************
** 函数名称: I2cRead
** 功能描述: 从I2c从器件读数据
** 输 入: Addr:从机地址
**        Ret:指向返回数据存储位置的指针
**        Eaddr:扩展地址存储位置
**        EaddrNByte:扩展地址字节数,0为无
**        ReadNbyte:将要读取的字节数目
** 输 出:已读取的字节数
**
** 全局变量: I2cSem,I2cAddr,I2cNbyte,I2cBuf
** 调用模块: OSSemPend,__I2cWrite,OSMboxPend,OSSemPost
**
** 作 者: 陈明计
** 日 期: 2003年7月8日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陈明计
** 日 期: 2003年7月21日
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int16 I2cRead(uint8 Addr, uint8 *Ret, uint8 *Eaddr, int16 EaddrNByte, int16 ReadNbyte)
{
    uint8 err;   

    OSSemPend(I2cSem, , &err);   

    I2CONCLR = 0x6C;
    I2CONSET = 0x40;                            /* 使能I2c */
    VICIntEnable =  << ;                      /* 使能I2c中断 */   

    )
    {
        if (__I2cWrite(Addr, Eaddr, EaddrNByte) != I2C_WRITE_END)
        {
            ;
        }
    }   

    I2cAddr = Addr | 0x01;                      /* 存储发送地址 */
    I2cNbyte = ReadNbyte;                       /* 存储读字节数 */
    I2cBuf = Ret;                               /* 存储读到的数据 */
    I2CONCLR = 0x28;
    I2CONSET = 0x24;                            /* 设置为主机,并启动总线 */
    VICIntEnable =  << ;                      /* 使能I2c中断 */   

    OSMboxPend(I2cMbox, , &err);               /* 等待操作结束 */   

    VICIntEnClr =  << ;                       /* 禁止能I2c中断 */
    OSSemPost(I2cSem);
    return (ReadNbyte - I2cNbyte);
}   

/*********************************************************************************************************
** 函数名称: I2c_Exception
** 功能描述: I2c中断服务程序
** 输 入: 无
**
** 输 出: 无
**
** 全局变量: I2cAddr,I2cBuf,I2cNbyte,I2cMbox
** 调用模块: OSMboxPost
**
** 作 者: 陈明计
** 日 期: 2003年7月8日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陈明计
** 日 期: 2003年7月21日
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void I2c_Exception(void)
{
    OS_ENTER_CRITICAL();
    switch(I2STAT & 0xf8)
    {
        case  0x08:                     /* 已发送起始条件,与0x18相同处理 */
//            break;
        case  0x10:                     /* 已发送重复起始条件 */
            I2DAT = I2cAddr;            /* 发送地址 */
            I2CONCLR = 0x28;            /* 清除标志 */
            break;
        case  0x18:                     /* 已发送SLA+W,并已接收应答 */
            I2DAT = *I2cBuf++;
            I2cNbyte--;
            I2CONCLR = 0x28;            /* 清除标志 */
            break;
        case  0x28:                     /* 已发送I2C数据,并接收到应答 */
            )
            {
                I2DAT = *I2cBuf++;
                I2cNbyte--;
                I2CONCLR = 0x28;        /* 清除标志 */
            }
            else
            {
                OSMboxPost(I2cMbox, (void *)I2C_WRITE_END);
                VICIntEnClr =  << ;   /* 禁止能I2c中断 */
            }
            break;
        case  0x20:                     /* 已发送SLA+W;已接收非ACK, 与0x48处理相同 */
//            break;
        case  0x30:                     /* 已发送I2DAT中的数据字节;已接收非ACK, 与0x48处理相同 */
//            break;
        case  0x48:                     /* 已发送SLA+R;已接收非ACK */
            I2CONSET =  << ;          /* 发送停止信号 */
            OSMboxPost(I2cMbox, (void *)I2C_ACK_ERR);
            I2CONCLR = 0x28;            /* 清除标志 */
            break;
        case  0x38:                     /* 在SLA+R/W或数据字节中丢失仲裁 */
            OSMboxPost(I2cMbox, (void *)I2C_NOT_GET_BUS);
            I2CONCLR = 0x28;            /* 清除标志 */
            break;
        case  0x40:                     /* 已发送SLA+R;已接收ACK */
            )
            {
                I2CONCLR =  << ;      /* 下次发送非应答信号 */
            }
            else
            {
                I2CONSET=  << ;       /* 下次发送应答信号 */
            }
            I2CONCLR = 0x28;            /* 清除标志 */
            break;
        case  0x50:                     /* 已接收数据字节;已发送ACK */
            *I2cBuf++ = I2DAT;          /* 接收数据 */
            I2cNbyte--;
            )
            {
                I2CONCLR =  << ;      /* 下次发送非应答信号 */
            }
            I2CONCLR = 0x28;            /* 清除标志 */
            break;
        case  0x58:                     /* 已接收数据字节;已返发送ACK */
            *I2cBuf = I2DAT;            /* 接收数据 */
            I2cNbyte--;
            I2CONSET=  << ;           /* 结束总线 */
            OSMboxPost(I2cMbox, (void *)I2C_READ_END);
            I2CONCLR = 0x28;            /* 清除标志 */
            break;
        default:
            I2CONCLR = 0x28;            /* 清除标志 */
            break;
    }   

    VICVectAddr = ;                    /* 通知中断控制器中断结束 */
    OS_EXIT_CRITICAL();
}
/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

I2C_周立功标准驱动程序_c代码的更多相关文章

  1. java-IO流-字节流-概述及分类、FileInputStream、FileOutputStream、available()方法、定义小数组、BufferedInputStream、BufferedOutputStream、flush和close方法的区别、流的标准处理异常代码

    1.IO流概述及其分类 * 1.概念      * IO流用来处理设备之间的数据传输      * Java对数据的操作是通过流的方式      * Java用于操作流的类都在IO包中      *  ...

  2. 周立功USBCAN-II 上位机开发(MFC)

    使用的USB转CAN的设备是周立功的USBCAN-II,在购买的时候,会有上位机二次开发的库文件.例程和API文档等材料,可以参考. 1.库函数的调用 首先,把库函数文件都放在工作目录下.库函数文件总 ...

  3. 将UBB编码转成标准的HTML代码

    /// <summary> /// 将UBB编码转成标准的HTML代码 /// </summary> /// <param name="argString&qu ...

  4. Python基于周立功ZCANPRO开发刷写脚本

    一.概述 1.背景 本文章主要是记录用Python基于周立功ZCANPRO开发VIN和SN码刷写工具. 2.环境搭建 Python3.8.10 32位(必须) 周立功上位机:ZCANPRO 周立功CA ...

  5. HihoCoder第五周:标准动态规划

    这周的题目是最标准最简单的动态规划了,自己一直以来对动态规划都不是很理解,这次也是好好记录一下. 题目1 :数字三角形 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 问题描述 ...

  6. 【Web前端开发最佳实践系列】标准的HTML代码

    一.验证代码是否符合标准 优点: 标准的页面会保证浏览器正确的渲染 网页能更容易被搜索引擎搜索,提高网站的搜索排名 提高网站的易用性 网页更好维护和扩展 常用工具: W3 Validator HTML ...

  7. 删除DriverStore\FileRepository文件夹后,设备驱动无法安装,提示“没有为设备信息集或元素选择驱动程序(代码 28)”的解决办法

    前言: 我前几天手贱,整个FileRepository删除掉了,之后重启就出现了让人蛋疼的这个问题,因为出于各种原因不想重装系统,百度轮番换搜索词无果,虽然驱动装上了但新设备依然无法自动安装驱动等“一 ...

  8. python__标准库 : 测试代码运行时间(timeit)

    用 timeit.Timer.timeit() 方法来测试代码的运行时间: from timeit import Timer def t1(): li = [] ): li.append(i) def ...

  9. 20190626_二次开发BarTender打印机_C#代码_一边读取TID_一边打印_打印机POSTEK

    demo代码如下: private void btnPrint_Click(object sender, EventArgs e) { if (this.btnPrint.Text == " ...

随机推荐

  1. cf D. Alternating Current

    http://codeforces.com/contest/344/problem/D #include <cstdio> #include <cstring> #includ ...

  2. ZOJ3229 Shoot the Bullet

    http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20756 思路:就讲一下有源汇上下界最大流的做法吧!对于所有的边,就按照无源汇 ...

  3. 10.1.5 Connection Character Sets and Collations

    10.1.5 Connection Character Sets and Collations Several character set and collation system variables ...

  4. Linux——oracle数据库实例启动关闭(转)

    -->Oracle 数据库实例启动关闭过程 --================================ [root@robinson ~]# su - oracle --查看未启动实例 ...

  5. nyoj 234 吃土豆

    描述 Bean-eating * grid. Now you want to eat the beans and collect the qualities, but everyone must ob ...

  6. hdu 3635 Dragon Balls(并查集应用)

    Problem Description Five hundred years later, the number of dragon balls will increase unexpectedly, ...

  7. C# Datatable导出Excel方法

    C# 导出Excel方法  先引用下System.IO;System.data; 具体函数如下: public static bool ExportCSV(DataTable dt, string f ...

  8. php的一些特殊用法

    php ruturn的另一个用法 database.php <?php return array ( 'hostname' => 'localhost', 'database' => ...

  9. 注册界面的优化之ActionBar组件的应用之(二)ActionBar组件的事件处理

    开发步骤: 重写父类中的一个方法onOptionsItemSelected实现ActionBar中的选项单击事件 //Register_Activity.java public class Regis ...

  10. 提示框的优化之自定义Toast组件之(一)Toast组件的布局实现

    开发步骤:  在res下layout下创建一个Toast的布局资源文件toast_customer.xml  在最外层布局组件中为该布局添加android:id属性  //toast_custo ...