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

📄 lm3s_i2cm.c

📁 基于Cortex-M3的全自动焊接机
💻 C
📖 第 1 页 / 共 2 页
字号:
#include  "LM3S_I2CM.h"
#include  <hw_ints.h>
#include  <interrupt.h>
#include  <sysctl.h>
#include  <gpio.h>
#include  <hw_types.h>
#include  <hw_i2c.h>
#include  <hw_memmap.h>
#include  <hw_sysctl.h> 


#define  PART_LM3S1138
#include  <pin_map.h>


//  定义工作状态
#define  STAT_IDLE              0                   //  空闲状态
#define  STAT_ADDR              1                   //  发送数据地址状态
#define  STAT_DATA              2                   //  接收或发送数据状态
#define  STAT_FINISH            3                   //  收发完成状态


//  定义全局变量
static unsigned long I2CM_BASE_One = I2C1_MASTER_BASE;  //  定义I2C主机基址,并初始化
static tI2CM_DEVICE gtDevice_One;                       //  器件数据接口
static unsigned char gucStatus_One = STAT_IDLE;         //  工作状态
static tBoolean gbSendRecv_One;                         //  收发操作标志,false发送,true接收
static char gcAddr_One[4];                              //  数据地址数组
static unsigned int guiAddrIndex_One;                   //  数据地址数组索引变量
static unsigned int guiDataIndex_One;                   //  数据缓冲区索引变量




//  定义全局变量
static unsigned long I2CM_BASE = I2C0_MASTER_BASE;  //  定义I2C主机基址,并初始化
static tI2CM_DEVICE gtDevice;                       //  器件数据接口
static unsigned char gucStatus = STAT_IDLE;         //  工作状态
static tBoolean gbSendRecv;                         //  收发操作标志,false发送,true接收
static char gcAddr[4];                              //  数据地址数组
static unsigned int guiAddrIndex;                   //  数据地址数组索引变量
static unsigned int guiDataIndex;                   //  数据缓冲区索引变量




//  对tI2CM_DEVICE结构体变量初始化设置所有数据成员
void I2CM_DeviceInitSet_One(tI2CM_DEVICE *pDevice, unsigned char ucSLA,
                                               unsigned long ulAddr,
                                               unsigned int uiLen,
                                               unsigned char *pcData,
                                               unsigned int uiSize)
{
    pDevice->ucSLA = ucSLA;
    pDevice->ulAddr = ulAddr;
    pDevice->uiLen = uiLen;
    pDevice->pcData = pcData;
    pDevice->uiSize = uiSize;
}


//  对tI2CM_DEVICE结构体变量设置与数据收发相关的成员(数据地址、数据缓冲区、数据大小)
void I2CM_DeviceDataSet_One(tI2CM_DEVICE *pDevice, unsigned long ulAddr,
                                               unsigned char *pcData,
                                               unsigned int uiSize)
{
    pDevice->ulAddr = ulAddr;
    pDevice->pcData = pcData;
    pDevice->uiSize = uiSize;
}


//  I2C主机初始化
void I2CM_Init_One(void)
{
    I2CM_DeviceInitSet_One(&gtDevice_One, 0, 0, 0, (void *)0, 0);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);         //  使能I2C1模块
    SysCtlPeripheralEnable(I2C1SCL_PERIPH);             //  使能SCL所在的GPIO模块
    GPIOPinTypeI2C(I2C1SCL_PORT, I2C1SCL_PIN);          //  配置相关管脚为SCL功能
    SysCtlPeripheralEnable(I2C1SDA_PERIPH);             //  使能SDA所在的GPIO模块
    GPIOPinTypeI2C(I2C1SDA_PORT, I2C1SDA_PIN);          //  配置相关管脚为SDA功能
    IntEnable(INT_I2C1);                                //  
        
    I2CMasterInit(I2CM_BASE_One, false);                    //  I2C主机模块初始化,100kbps
    I2CMasterSpeedSet(I2C1_MASTER_BASE,15000);
    IntPrioritySet(INT_I2C1 , 3 << 5);                      //  设置GPIOD中断优先级为1
    I2CMasterIntEnable(I2CM_BASE_One);                       //  使能I2C主模块中断
    IntMasterEnable();                                      //  使能处理器中断
    I2CMasterEnable(I2CM_BASE_One);                         //  使能I2C主机
}


//  功能:I2C主机发送或接收数据
//  参数:pDevice是指向tI2CM_DEVICE型结构体变量的指针
//        bFlag取值false表示发送操作,取值true表示接收操作
//  返回:I2C_MASTER_ERR_NONE      没有错误
//        I2C_MASTER_ERR_ADDR_ACK  地址应答错误
//        I2C_MASTER_ERR_DATA_ACK  数据应答错误
//        I2C_MASTER_ERR_ARB_LOST  多主机通信仲裁失败
//  发送格式:S | SLA+W | addr[1~4] | data[1~n] | P
//  接收格式:S | SLA+W | addr[1~4] | Sr | SLA+R | data[1~n] | P
unsigned long I2CM_SendRecv_One(tI2CM_DEVICE *pDevice, tBoolean bFlag)
{
    //  数据地址长度或收发数据大小不能为0,否则不执行任何操作
    if ((pDevice->uiLen <= 0) || (pDevice->uiSize <= 0))
    {
        return(I2C_MASTER_ERR_NONE);
    }

    gtDevice_One = *pDevice;
    if (gtDevice_One.uiLen > 4) gtDevice_One.uiLen = 4;                 //  数据地址长度不能超过4B

    gbSendRecv_One = bFlag;                                         //  相关全局变量初始化
    guiAddrIndex_One = 0;
    guiDataIndex_One = 0;

    switch (gtDevice_One.uiLen)                                     //  将数据地址分解成数组
    {
    case 1:                                                     //  1字节数据地址
        gcAddr_One[0] = (char)(gtDevice_One.ulAddr);
        break;

    case 2:                                                     //  2字节数据地址
        gcAddr_One[0] = (char)(gtDevice_One.ulAddr >> 8);
        gcAddr_One[1] = (char)(gtDevice_One.ulAddr);
        break;

    case 3:                                                     //  3字节数据地址
        gcAddr_One[0] = (char)(gtDevice_One.ulAddr >> 16);
        gcAddr_One[1] = (char)(gtDevice_One.ulAddr >> 8);
        gcAddr_One[2] = (char)(gtDevice_One.ulAddr);
        break;

    case 4:                                                     //  4字节数据地址
        gcAddr_One[0] = (char)(gtDevice_One.ulAddr >> 24);
        gcAddr_One[1] = (char)(gtDevice_One.ulAddr >> 16);
        gcAddr_One[2] = (char)(gtDevice_One.ulAddr >> 8);
        gcAddr_One[3] = (char)(gtDevice_One.ulAddr);
        break;

    default:
        break;
    }

    //  如果是多主机通信,则需要首先等待总线空闲
    //  while (I2CMasterBusBusy(I2CM_BASE));                    //  等待总线空闲

    I2CMasterSlaveAddrSet(I2CM_BASE_One, gtDevice_One.ucSLA, false);    //  设置从机地址,写操作
    I2CMasterDataPut(I2CM_BASE_One, gcAddr_One[guiAddrIndex_One++]);        //  开始发送数据地址
    //I2CMasterDataPut(I2CM_BASE, gcAddr[++guiAddrIndex]);        //  开始发送数据地址
    gucStatus_One = STAT_ADDR;                                      //  设置状态:发送数据地址

    //  命令:主机突发发送起始
    I2CMasterControl(I2CM_BASE_One, I2C_MASTER_CMD_BURST_SEND_START);

    while (gucStatus_One != STAT_IDLE);                             //  等待总线操作完毕

    return(I2CMasterErr(I2CM_BASE_One));                            //  返回可能的错误状态
}


//  I2C中断服务函数
void I2C_ISR_One(void)
{
    unsigned long ulStatus;

    ulStatus = I2CMasterIntStatus(I2CM_BASE_One, true);             //  读取中断状态
    I2CMasterIntClear(I2CM_BASE_One);                               //  清除中断状态

    if (I2CMasterErr(I2CM_BASE_One) != I2C_MASTER_ERR_NONE)         //  若遇到错误
    {
        gucStatus_One = STAT_IDLE;
        return;
    }

    if (!ulStatus) return;

    switch (gucStatus_One)
    {
    case STAT_ADDR:                                             //  发送数据地址状态
        if (guiAddrIndex_One < gtDevice_One.uiLen)                      //  若数据地址未发送完毕
        {
            //  继续发送数据地址
            I2CMasterDataPut(I2CM_BASE_One, gcAddr_One[guiAddrIndex_One++]);

            //  命令:主机突发发送继续
            I2CMasterControl(I2CM_BASE_One, I2C_MASTER_CMD_BURST_SEND_CONT);

            break;
        }
        else
        {
            gucStatus_One = STAT_DATA;                              //  设置状态:收发数据

            if (gbSendRecv_One)                                     //  若是接收操作
            {
                //  设置从机地址,读操作
                I2CMasterSlaveAddrSet(I2CM_BASE_One, gtDevice_One.ucSLA, true);

                if (gtDevice_One.uiSize == 1)                       //  若只准备接收1个字节
                {
                    gucStatus_One = STAT_FINISH;                    //  设置状态:接收结束

                    //  命令:主机单次接收
                    I2CMasterControl(I2CM_BASE_One, I2C_MASTER_CMD_SINGLE_RECEIVE);
                }
                else
                {
                    //  命令:主机突发接收起始
                    I2CMasterControl(I2CM_BASE_One, I2C_MASTER_CMD_BURST_RECEIVE_START);
                }

                break;
            }
        }

        //  直接进入下一条case语句

    case STAT_DATA:                                             //  收发数据状态
        if (gbSendRecv_One)                                         //  若是接收操作
        {
            //  读取接收到的数据
            gtDevice_One.pcData[guiDataIndex_One++] = I2CMasterDataGet(I2CM_BASE_One);

            if (guiDataIndex_One + 1 < gtDevice_One.uiSize)             //  若数据未接收完毕
            {
                //  命令:主机突发接收继续
                I2CMasterControl(I2CM_BASE_One, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
            }
            else
            {
                gucStatus_One = STAT_FINISH;                        //  设置状态:接收完成

                //  命令:主机突发接收完成
                I2CMasterControl(I2CM_BASE_One, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
            }
        }
        else
        {
            //  发送数据
            I2CMasterDataPut(I2CM_BASE_One, gtDevice_One.pcData[guiDataIndex_One++]);

            if (guiDataIndex_One < gtDevice_One.uiSize)                 //  若数据未发送完毕
            {
                //  命令:主机突发发送继续
                I2CMasterControl(I2CM_BASE_One, I2C_MASTER_CMD_BURST_SEND_CONT);
            }
            else
            {
                gucStatus_One = STAT_FINISH;                        //  设置状态:发送完成

                //  命令:主机突发发送完成
                I2CMasterControl(I2CM_BASE_One, I2C_MASTER_CMD_BURST_SEND_FINISH);
            }
        }

        break;

    case STAT_FINISH:                                           //  收发完成状态
        if (gbSendRecv_One)                                         //  若是接收操作
        {
            //  读取接最后收到的数据
            gtDevice_One.pcData[guiDataIndex_One] = I2CMasterDataGet(I2CM_BASE_One);
        }

        gucStatus_One = STAT_IDLE;                                  //  设置状态:空闲

⌨️ 快捷键说明

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