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

📄 landzo

📁 【开源】线性CCD自适应性算法攻略
💻
字号:
/******************** (C) COPYRIGHT 2011 野火嵌入式开发工作室\蓝宙电子工作室 ********************
 * 文件名       :i2c.c
 * 描述         :i2c驱动函数
 * 备注         :修改自官方例程
 *
 * 实验平台     :野火kinetis开发板
 * 库版本       :
 * 嵌入系统     :
 *
 * 作者         :
 * 淘宝店       :http://landzo.taobao.com/
**********************************************************************************/


#include "common.h"
#include "i2c.h"


unsigned char MasterTransmission;
unsigned char SlaveID;

volatile struct I2C_MemMap *I2Cx[2] = {I2C0_BASE_PTR, I2C1_BASE_PTR}; //定义两个指针数组保存 I2Cx 的地址


/*************************************************************************
*                             野火嵌入式开发工作室\蓝宙电子工作室
*
*  函数名称:I2C_init
*  功能说明:I2C初始化,设置波特率和启动I2C
*  参数说明:I2Cn        模块号(I2C0、I2C1)
*  函数返回:无
*  修改时间:2012-1-20
*  备    注:
*************************************************************************/
void I2C_init(I2Cn i2cn)
{
    u8 mult;
    if(bus_clk_khz <= 50000)mult = 0;         //bus 一分频
    else  if(bus_clk_khz <= 100000)mult = 1;  //bus 二分频
    else      mult = 2;                       //bus 四分频

    if(i2cn == I2C0)
    {
        /* 开启时钟 */
        SIM_SCGC4 |= SIM_SCGC4_I2C0_MASK;         //开启 I2C0时钟

        /* 配置 I2C0功能的 GPIO 接口 */
        if(I2C0_SCL == PTB0)
            PORTB_PCR0 = PORT_PCR_MUX(2);
        else if(I2C0_SCL == PTB2)
            PORTB_PCR2 = PORT_PCR_MUX(2);
        else if(I2C0_SCL == PTD8)
            PORTD_PCR8 = PORT_PCR_MUX(2);
        else
            assert_failed(__FILE__, __LINE__);                   //设置管脚有误?

        if(I2C0_SDA == PTB1)
            PORTB_PCR1 = PORT_PCR_MUX(2);
        else if(I2C0_SDA == PTB3)
            PORTB_PCR3 = PORT_PCR_MUX(2);
        else if(I2C0_SDA == PTD9)
            PORTD_PCR9 = PORT_PCR_MUX(2);
        else
            assert_failed(__FILE__, __LINE__);                   //设置管脚有误?
    }
    else
    {
        /* 开启时钟 */
        SIM_SCGC4 |= SIM_SCGC4_I2C1_MASK;         //开启 I2C1时钟

        /* 配置 I2C1功能的 GPIO 接口 */
        if(I2C1_SCL == PTE1)
            PORTE_PCR1 = PORT_PCR_MUX(6);
        else if(I2C1_SCL == PTC10)
            PORTC_PCR10 = PORT_PCR_MUX(2);
        else
            assert_failed(__FILE__, __LINE__);                   //设置管脚有误?

        if(I2C1_SDA == PTE0)
            PORTE_PCR0 = PORT_PCR_MUX(6);
        else if (I2C1_SDA == PTC11)
            PORTC_PCR11 = PORT_PCR_MUX(2);
        else
            assert_failed(__FILE__, __LINE__);                   //设置管脚有误?

    }

    /* 设置频率 */
    I2C_F_REG(I2Cx[i2cn])  = I2C_F_MULT(mult) | I2C_F_ICR(17) ;  // I2C Frequency Divider register (I2Cx_F)  I2C分频寄存器   I2C最大波特率为 400k
    // MULT=00  即  mul = 1
    // ICR =14  ICR为Clock rate时钟频率
    // 从《k16 reference manual.pdf》P1460 可得:
    // ICR    SCL Divider   SDA Hold Value    SCL Hold (Start) Value    SCL Hold (Stop) Value
    //  14        80              17                   34                         41
    //  17       128              21                   58                         65
    // I2C baud rate = bus speed (Hz)/(mul × SCL divider)  即这里 50MHz/(1 ×128)=390.625kHz
    // SDA hold time = bus period (s) × mul × SDA hold value
    // SCL start hold time = bus period (s) × mul × SCL start hold value
    // SCL stop hold time = bus period (s) × mul × SCL stop hold value

    /* 使能 IIC1 */
    I2C_C1_REG(I2Cx[i2cn]) = I2C_C1_IICEN_MASK;
}

/*************************************************************************
*                             野火嵌入式开发工作室\蓝宙电子工作室
*
*  函数名称:I2C_StartTransmission
*  功能说明:启动 I2C 传输
*  参数说明:I2Cn        模块号(I2C0、I2C1)
*            SlaveID     7位从机地址
*            MSmode      读写模式( MWSR 或 MRSW )
*  函数返回:无
*  修改时间:2012-1-20
*  备    注:
*************************************************************************/
void I2C_StartTransmission (I2Cn i2cn, u8 SlaveID, MSmode Mode)
{

    //ASSERT(Mode == MWSR || Mode == MRSW);         //使用断言,检测 Mode 是否为 读 或 写

    SlaveID = ( SlaveID << 1 ) | Mode ;            //确定写地址和读地址

    /* send start signal */
    i2c_Start(i2cn);

    /* send ID with W/R bit */
    i2c_write_byte(i2cn, SlaveID);
}

/*************************************************************************
*                             野火嵌入式开发工作室\蓝宙电子工作室
*
*  函数名称:Pause
*  功能说明:延时,I2C读写后,需要延时一下
*  参数说明:无
*  函数返回:无
*  修改时间:2012-1-20
*  备    注:在官方基础上增大延时数
*************************************************************************/
void Pause(void)
{
    u16 n;
    for(n = 1; n < 50000; n++)      //注意,这个数据太小,会导致读取错误。
    {
        asm("nop");
    }
}

/*************************************************************************
*                             野火嵌入式开发工作室\蓝宙电子工作室
*
*  函数名称:I2C_ReadAddr
*  功能说明:读取I2C设备指定地址寄存器的数据
*  参数说明:I2Cn        模块号(I2C0、I2C1)
*            SlaveID     7位从机地址
*            Addr        从机的寄存器地址
*  函数返回:从机寄存器的数据
*  修改时间:2012-1-20
*  备    注:
*************************************************************************/
u8 I2C_ReadAddr(I2Cn i2cn, u8 SlaveID, u8 Addr)
{
    u8 result;

    /* Send Slave Address */
    I2C_StartTransmission (i2cn, SlaveID, MWSR);
    i2c_Wait(i2cn);

    /* Write Register Address */
    i2c_write_byte(i2cn, Addr);
    i2c_Wait(i2cn);

    /* Do a repeated start */
    i2c_RepeatedStart(i2cn);

    /* Send Slave Address */
    i2c_write_byte(i2cn, ( SlaveID << 1) | MRSW );
    i2c_Wait(i2cn);

    /* Put in Rx Mode */
    i2c_PutinRxMode(i2cn);

    /* Turn off ACK since this is second to last byte being read*/
    i2c_DisableAck(i2cn); //不应答

    /* Dummy read 虚假读取*/
    result = I2C_D_REG(I2Cx[i2cn]);
    i2c_Wait(i2cn);

    /* Send stop since about to read last byte */
    i2c_Stop(i2cn);

    /* Read byte */
    result = I2C_D_REG(I2Cx[i2cn]);

    return result;
}


/*************************************************************************
*                             野火嵌入式开发工作室\蓝宙电子工作室
*
*  函数名称:I2C_WriteAddr
*  功能说明:写入一个字节数据到I2C设备指定寄存器地址
*  参数说明:I2Cn        模块号(I2C0、I2C1)
*            SlaveID     7位从机地址
*            Addr        从机的寄存器地址
*            Data        数据
*  函数返回:无
*  修改时间:2012-1-20
*  备    注:
*************************************************************************/
void I2C_WriteAddr(I2Cn i2cn, u8 SlaveID, u8 Addr, u8 Data)
{
    /* send data to slave */
    I2C_StartTransmission(i2cn, SlaveID, MWSR);    //启动传输
    i2c_Wait(i2cn);

    i2c_write_byte(i2cn, Addr);                    //写地址
    i2c_Wait(i2cn);

    i2c_write_byte(i2cn, Data);                    //写数据
    i2c_Wait(i2cn);

    i2c_Stop(i2cn);

    Pause();                                        //延时太短的话,可能写出错
}

⌨️ 快捷键说明

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