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

📄 hardi2c.c

📁 周立功的EasyARM1138互联I2C的例程
💻 C
字号:
// 包含头文件
#include "hw_memmap.h"
#include "hw_types.h"
#include "hw_ints.h"
#include "hw_i2c.h"
#include "sysctl.h"
#include "gpio.h"
#include "i2c.h"
#include "UART_GetPut.H"
#include "stdio.h"
#include "interrupt.h"
#include "HardI2C.h"


// 定义I2C中断操作所用到的全局变量
unsigned char  GucStat  = STAT_IDLE;    // I2C工作状态标志
unsigned char  GucSLA   = 0x00;         // 主机从地址
unsigned char *GpucData = (void *)0;    // 保存接收到的数据
unsigned char  GucSize  = 0x00;         // 数据长度 


// I2C主模块初始化
void I2CM_Init()
{
    SysCtlClockSet(SYSCTL_SYSDIV_1 |
                   SYSCTL_USE_OSC  |
                   SYSCTL_OSC_MAIN |
                   SYSCTL_XTAL_6MHZ);                   // 配置外部6MHz晶振作为CPU主频
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);        // 使能I2C管脚所在的GPIO
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C);          // 使能I2C模块
    GPIOPinTypeI2C(GPIO_PORTB_BASE, I2C_SCL|I2C_SDA);   // I2C管脚配置
    I2CMasterInit(I2C_MASTER_BASE, false);              // I2C主模块初始化,100kbps速率
    IntMasterEnable();                                  // 使能总中断
    IntEnable(INT_I2C);                                 // 使能I2C中断
    I2CMasterIntEnable(I2C_MASTER_BASE);                // 使能I2C主模块中断
}


// I2C主模块突发发送后突发接收(返回接收到的多个字节有效数据)
// {S | SLA+W | addr | Sr | SLA+R | data_1 | ... | data_n | P}
void I2CM_BurstSendReceive(unsigned char ucSLA,         // 从机地址
                           unsigned char ucAddr,        // 数据存储地址
                           unsigned char *pucData,      // 保存接收到的数据
                           unsigned char ucSize)        // 数据长度
{
    GucStat  = STAT_RECEIVE_START;                      // 初始化为起始接收状态
    GucSLA   = ucSLA;
    GpucData = pucData;
    GucSize  = ucSize;
    I2CMasterSlaveAddrSet(I2C_MASTER_BASE,              // 设置SLA+W
                          ucSLA,                        // 该函数不执行任何I2C时序上的操作
                          false);
    I2CMasterDataPut(I2C_MASTER_BASE, ucAddr);          // 设置数据存储地址
                                                        // 该函数不执行任何I2C时序上的操作
    I2CMasterControl(I2C_MASTER_BASE,                   // 启动I2C主模块突发发送
                     I2C_MASTER_CMD_BURST_SEND_START);  // 总线动作:{S | SLA+W | addr}
    while ( GucStat != STAT_IDLE );                     // 等待I2C中断操作完毕
}


// I2C主模块中断服务函数
void I2C_ISR(void)
{
    unsigned char ucTmp = 0x00; //临时变量
    I2CMasterIntClear(I2C_MASTER_BASE);                 // 清除中断状态,重要!
    switch ( GucStat )          // 判断当前运行状态
    {
    case STAT_IDLE:             // 空闲状态
        ucTmp = 0x00;
        break;
    case STAT_RECEIVE_START:    // 接收起始状态
        I2CMasterSlaveAddrSet(I2C_MASTER_BASE,          // 设置SLA+R
                              GucSLA,
                              true);
        if ( GucSize == 1 )                             // 如果只接收1个字节的有效数据
        {
            I2CMasterControl(I2C_MASTER_BASE,           // 重复起始,接收有效数据,停止
                             I2CM_CMD_PSR);             // 总线动作 {Sr | SLA+R | data | P}
            GucStat = STAT_RECEIVE_LAST;                // 变成最后接收状态
        }
        else
        {
            I2CMasterControl(I2C_MASTER_BASE,           // 先重复起始,再应答接收
                             I2C_MASTER_CMD_BURST_RECEIVE_START);
                                                        // 总线动作 {Sr | SLA+R | data_1}
            GucStat = STAT_RECEIVE_CONT;                // 变成继续接收状态
        }
        break;
    case STAT_RECEIVE_CONT:     // 继续接收状态
        ucTmp = I2CMasterDataGet(I2C_MASTER_BASE);      // 读取有效数据
        *GpucData++ = ucTmp;                            // 保存有效数据
        if ( --GucSize == 1 )                           // 如果准备接收最后1个数据
        {
            I2CMasterControl(I2C_MASTER_BASE,           // 接收后停止
                             I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
                                                        // 总线动作 {data_n | P}
            GucStat = STAT_RECEIVE_LAST;                // 变成最后接收状态
        }
        else
        {
            // 保持继续接收状态不变
        }
        break;
    case STAT_RECEIVE_LAST:     // 最后接收状态
        ucTmp = I2CMasterDataGet(I2C_MASTER_BASE);      // 读取最后1个有效数据
        *GpucData++ = ucTmp;                            // 保存最后1个有效数据
        GucStat = STAT_IDLE;                            // 变成空闲状态
        break;
    default:
        break;
    }
}




// 读取LM75A的温度值,并通过UART发送显示
void TmpDisp(void)
{
    char TmpTab[8][4] =
    {
        "000",
        "125",
        "250",
        "375",
        "500",
        "625",
        "750",
        "875"
    };
    unsigned char ucData[2];
    char  cBuf[20];
    short sTmp;

    I2CM_BurstSendReceive(SLA_LM75A, LM75A_REG_TMP, ucData, 2);
    sTmp   = ucData[0];
    sTmp <<= 8;
    sTmp  |= ucData[1] & 0xE0;

    if ( sTmp < 0 )
    {
        sTmp = -sTmp;
        UART_Puts("-");
    }
    sprintf(cBuf, "%d", (sTmp / 256));
    UART_Puts(cBuf);
    UART_Puts(".");
    UART_Puts(TmpTab[(sTmp >> 5) & 0x07]);
    UART_Puts("\r\n");
}

⌨️ 快捷键说明

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