TI中文支持网
TI专业的中文技术问题搜集分享网站

opt3001碰到一个问题,就是在中断里面给opt3001的寄存器写值,发现I2C_transfer写值写不进去。这是因为I2C和opt3001的中断嵌套吗,这个问题应该怎么解决呢,下面是opt3001的中断代码,光照判断进中断首先是没问题的,在中断外,读写寄存器值也是没问题的。

void OPT3001CallbackFxn(PIN_Handle handle, PIN_Id pinId) {
  switch (pinId) {
    case OPT3001_INT:
          PIN_setConfig(OPT3001_INT_PinHandle, PIN_BM_IRQ, OPT3001_INT | PIN_IRQ_DIS);
          PIN_clrPendInterrupt(handle,pinId);
         if(g_DoorStatus == DOOR_OPEN){
             g_DoorStatus == DOOR_CLOSE;
            Set_OPT3001_High_Limit( cfg_para_opt3001.lignt_limit_ths );
          }else{
            g_DoorStatus == DOOR_OPEN;
           Set_OPT3001_Low_Limit( cfg_para_opt3001.lignt_limit_ths );
          }
        break;
    }
}

Kevin Qiu1:

能进中断具体指的是运行到哪一步,监测写的值是否发生变化

user6477475:

回复 Kevin Qiu1:

下面是我的代码,我是将开发板置于箱子内部,通过光照阈值和当前光照值来判断箱子的开关状态,例如我阈值设置的是0x20,当前采集的光照值大于0x20,则判断箱子打开,设置光照下限,当关闭箱子的时候,将会触发下限进中断函数,因此我需要在中断里面再设置其上限,刹车再次打开箱子的时候能够再次进入中断来获取箱子的打开状态,现在的问题是中断里面的设置上限(通过I2C)的时候,就卡住了,程序就跑飞了,我具体跟踪了下,I2C_transfer(handle,&i2cTrans)在写上一部分的时候返回老是false。我I2C用的是block通讯模式。

#include <stdio.h>
#include <string.h>
#include <stdbool.h>

/ * XDCtools头文件* /
#include <xdc / std.h>
#include <xdc / runtime / System.h>

/ * BIOS头文件* /
#include <ti / sysbios /BIOS.h>
#include <ti / sysbios /knl/Clock.h>
#include <ti / sysbios /knl/Task.h>

/ * TI-RTOS头文件* /
#include <ti /
drivers / I2C.h> //修改
#include <ti / drivers / i2c / I2CCC26XX.h>

#include“ Board.h”
#include“ HAL_ OPT3001 .h”

静态PIN_Handle OPT3001 _LED_PinHandle;
静态PIN_Handle OPT3001 _INT_PinHandle;
静态PIN_State OPT3001 _LED_PinState;
静态PIN_State OPT3001 _INT_PinState;
静态Task_Struct task0Struct;
静态Char task0Stack [TASKSTACKSIZE];

/ *定义I2C ============================================ ============================== * //
静态uint8_t txBuffer [3]; //发送器缓冲区
静态uint8_t rxBuffer [3] ; //接收缓冲区

静态uint8_t RXBuf [3]; //发送缓冲区
静态uint8_t TXBuf [3]; //接收缓冲区

静态I2C_Handle句柄;
静态I2C_Params参数;
静态I2C_Transaction i2cTrans;

无符号字符g_DoorStatus = DOOR_OPEN;
typedef struct
{uint8_t lignt_limit_ths; //光照强度阈值
} CONGFIG_PARAMETER;

CONGFIG_PARAMETER cfg_para_ opt3001 ;

静态PIN_Config OPT3001 _INT_PinTable [] = {OPT3001 _INT | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,PIN_TERMINATE
};

void I2C_configParam_ OPT3001(){
/ *创建要使用的I2C ***************** /I2C_Params_init(&params);params.bitRate = I2C_100kHz;
handle = I2C_open(Board_I2C,&params);if(句柄== NULL){System_abort(“初始化I2C时出错\ n”);}else {System_printf(“ I2C Initialized!\ n”);}/ *完成I2C的使用创建********** /Task_sleep(1000000 / Clock_tickPeriod);
}

//函数封装(给寄存器读写值)
布尔HalSensorRWReg_ OPT3001(uint8_t地址,uint8_t * pWriteBuf,uint8_t WriteBytes,uint8_t * pReadBuf,uint8_t的ReadBytes,uint8_t slaveAddress)
{uint8_t TMP [32]; //接收器缓冲器的memcpy(TMP, txBuffer,WriteBytes);txBuffer [0] = addr; //地址是设备IDmemcpy(txBuffer + 1,tmp,WriteBytes);i2cTrans.writeCount = 1 + WriteBytes;i2cTrans.writeBuf = txBuffer;i2cTrans.readCount = ReadBytes;i2cTrans.readBuf = rxBuffer;i2cTrans.slaveAddress = slaveAddress;while(!I2C_transfer(handle,&i2cTrans)){
}返回0;
}

//重置总线
void Reset_ OPT3001 _Register()
{HalSensorRWReg_ OPT3001(0x06,txBuffer,0,rxBuffer,0,0x00);
}

//获取当前光照结果寄存器值

无效Get_ OPT3001 _Result()
{HalSensorRWReg_ OPT3001(0x00,txBuffer,0,rxBuffer,2,0x44);memcpy(TXBuf,rxBuffer,2);
}

//获取光照状态寄存器值

无效Get_ OPT3001 _Status()
{HalSensorRWReg_ OPT3001(0x01,txBuffer,0,rxBuffer,2,0x44);memcpy(RXBuf,rxBuffer,2);
}

//设置光照下限

无效Set_ OPT3001 _Low_Limit(uint8_t限制)

{
Reset_ OPT3001 _Register();
txBuffer [0] = 0x54; txBuffer [1] = 0x10;HalSensorRWReg_ OPT3001(0x01,txBuffer,2,rxBuffer,0,0x44);
txBuffer [0] = 0x50; txBuffer [1] =限制;HalSensorRWReg_ OPT3001(0x02,txBuffer,2,rxBuffer,0,0x44);
}

//设置光照上限

无效Set_ OPT3001 _High_Limit(无符号字符数限制)
{txBuffer [0] = 0x54; txBuffer [1] = 0x10;HalSensorRWReg_ OPT3001(0x01,txBuffer,2,rxBuffer,0,0x44);
txBuffer [0] = 0x50; txBuffer [1] =限制;HalSensorRWReg_ OPT3001(0x03,txBuffer,2,rxBuffer,0,0x44);

}

//初始化箱门状态,如果当前光照值大于阈值,则判断箱门开,设置光照下限(当光照度低于当前阈值时,会进中断)

//如果当前光照值小于于阈值,则判断箱门关,设置光照上限(当光照度高于当前阈值时,会进中断)

void Init_ OPT3001 _IN(){Get_ OPT3001 _Status();Get_ OPT3001 _Result();uint16_t b =(TXBuf [0] << 8 | TXBuf [1])&0xFFF;
uint16_t c = TXBuf [1];if((((TXBuf [0] << 8 | TXBuf [1])&0xFFF)> = cfg_para_ opt3001 .lignt_limit_ths){g_DoorStatus = DOOR_OPEN;Set_ OPT3001 _Low_Limit(cfg_para_ opt3001 .lignt_limit_ths);}else if(TXBuf [1] <cfg_para_ opt3001 .lignt_limit_ths){g_DoorStatus = DOOR_CLOSE;组_OPT3001 _High_Limit(cfg_para_ opt3001 .lignt_limit_ths);}
}

// OPT3001初始化,给0x01寄存器配值(5101)
void SET_ OPT3001 _Register()
{//清空总线Reset_ OPT3001 _Register();
txBuffer [0] = 0x54; txBuffer [1] = 0x10;HalSensorRWReg_ OPT3001(0x01,txBuffer,2,rxBuffer,0,0x44);
HalSensorRWReg_ OPT3001(0x01,txBuffer,0,rxBuffer,2,0x44);
}

/ ***************************************************** ********************* // **
* @brief根据箱门状态设置上下限
*
* @param箱门报警后,箱门状态
*
* @return无
*************************************************** ************************** /
void CFG_ OPT3001 _IN(unsigned char state)
{if(state == DOOR_OPEN){Set_ OPT3001 _Low_Limit(cfg_para_ opt3001 .lignt_limit_ths);}else if(state == DOOR_CLOSE){Set_ OPT3001 _High_Limit(cfg_para_ opt3001 .lignt_limit_ths);}
}

//主任务函数

静态uint8_t HalSensorRWRegOPT3001(UArg arg0,UArg arg1)
{I2C_configParam_ OPT3001();
/ * OPT3001初始化* / SET_ OPT3001 _Register();Task_sleep(2000000 / Clock_tickPeriod);
/ *初始化箱门状态* / Init_ OPT3001 _IN();

/ *使能光照报警* /PIN_setConfig(OPT3001 _INT_PinHandle,PIN_BM_IRQ,OPT3001 _INT | PIN_IRQ_NEGEDGE);返回0;
}

/ *
* ======== OPT3001CallbackFxn(中断函数)========
* /
void OPT3001CallbackFxn(PIN_Handle handle,PIN_Id pinId){switch(pinId){case OPT3001 _INT:PIN_setConfig(OPT3001 _INT_PinHandle, PIN_BM_IRQ,OPT3001 _INT | PIN_IRQ_DIS);PIN_clrPendInterrupt(handle,pinId);if(g_DoorStatus == DOOR_OPEN){g_DoorStatus == DOOR_CLOSE;设置OPT3001高限(cfg_para_ opt3001 .lignt_limit_ths);}否则{g_DoorStatus == DOOR_OPEN;组_OPT3001 _Low_Limit(cfg_para_ opt3001 .lignt_limit_ths);};}
}

/ *
* ========主要======================================= ================================================== ======
* /
INT opt3001main(无效)
{/ *初始化设备配置参数* /cfg_para_ opt3001 .lignt_limit_ths = 0×20; //光照强度阈值Task_Params taskParams;
/ *调用板初始化函数* /Board_initGeneral();Board_initI2C();OPT3001 _INT_PinHandle = PIN_open(&OPT3001 _INT_PinState,OPT3001 _INT_PinTable);*为按钮引脚设置回调* /如果(PIN_registerIntCb(OPT3001 _INT_PinHandle,&OPT3001CallbackFxn)!= 0){System_abort(“错误注册按钮回调函数”);}
/ *构造g_sensor任务线程* /Task_Params_init(&taskParams);taskParams.stackSize = TASKSTACKSIZE;taskParams.stack =&task0Stack;Task_construct(&task0Struct,(Task_FuncPtr)HalSensorRWRegOPT3001,&taskParams,NULL);
/ *启动BIOS * /BIOS_start();
返回(0);
}

user6477475:

回复 Kevin Qiu1:

就是红箭头指的这块,程序就会跑飞。

Kevin Qiu1:

回复 user6477475:

返回false可能是没有收到信号,一直在等待
看下SDK中C:/ti/simplelink_cc2640r2_sdk_4_30_00_08/docs/tidrivers/doxygen/html/_i2_c_8h.html
IIC的用法说明

user6477475:

回复 Kevin Qiu1:

I2C读写是没有问题的,在中断外读写都ok的,就是在中断里面读写I2C就阻塞了。

Kevin Qiu1:

回复 user6477475:

在中断中使用阻塞容易发生问题,得不到返回信号,建议不要在中断中使用阻塞
也可以看下e2e.ti.com/…/3124685

YiKai Chen:

回复 user6477475:

中断里面不要使用任何driver程序

user6477475:

回复 YiKai Chen:

我现在是这样解决的,我建了两个任务,将读取I2C操作放到另外一个任务里面,然后用信号量去控制,这是好的解决方法吗,还有其他的解决方法吗?

YiKai Chen:

回复 user6477475:

读取I2C操作放到另外一个任务里面我認為好的解决方法了

赞(0)
未经允许不得转载:TI中文支持网 » opt3001碰到一个问题,就是在中断里面给opt3001的寄存器写值,发现I2C_transfer写值写不进去。这是因为I2C和opt3001的中断嵌套吗,这个问题应该怎么解决呢,下面是opt3001的中断代码,光照判断进中断首先是没问题的,在中断外,读写寄存器值也是没问题的。
分享到: 更多 (0)