This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
工具/软件:Code Composer Studio
您好!
我一直在研究 DriverLib 示例、并尝试开发 i2c 驱动器、以读取/写入 opt3001 ALS。 我对了解中断和 ISR 比较陌生、认为我在调试代码时遇到了一些问题、在 i2c_write 结束时、器件进入 LPM0+GIE、大概通过 ISR、但我无法单步执行或退出 LPM 和相应的 ISR。
由于我不熟悉中断、我的 ISR 代码很可能不正确、但由于我无法单步执行、我有一个硬时间引脚指出发生了什么错误。 第113行是我第一次遇到问题的地方,但我希望155也会有同样的问题。
有什么问题吗?
"MSP430:不能单步执行目标程序:CPU 当前处于关闭状态、调试功能将受到限制。"
/* i2c_driver.c * *创建日期:2014年7月16日 * 作者:a0272990 * *版权所有2014 Texas Instruments Incorporated。 保留所有权利。 * */ //********************** //#includes //********* #include "driverlib.h" #include "i2c_driver.h" #include "QmathLib.h" #include "IQmathLib.h" #include "math.h" //********* //#defines //********* #define OPT3001_ADDRESS 0x44 // OPT3001的 I2C 地址 #define CHECK_POLARITY 0x80 //极性标志(MSB 的 MSB) //********* //全局变量 //********* #define RXCOUNT 0x05 #define TXLENGTH 0x04 uint8_t i2c_transmitCounter = 0;//可用于存储 I2C uint8_t i2c_transmitData[40]的发送状态的变量; // uint8_t * p_i2c_transmitData; //发送数据的指针 uint8_t i2c_receivedCounter = 0; //可用于存储 I2C uint8_t i2c_receivedBuffer[40]的接收状态的变量; // uint8_t * p_i2c_receivedBuffer; //指向接收数据的指针 //无符号字符接收缓冲区[10]={0x01、0x01、0x01、0x01、0x01、0x01、 0x01、0x01、0x01、0x01、0x01}; //unsigned char * receiveBufferPointer; //unsigned char receiveCount = 0; uint16_t i2c_mode = 0; //用于存储 i2c 模式(TX 或 Rx)的变量 //********* // I2C 库函数 //********* void init_i2c (void) { //将 I2C 引脚分配给 USCI_B1 GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P4、GPIO_PIN1 + GPIO_PIN2); //初始化主控 USCI_B_I2C_initMasterParam param ={0}; param.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK; param.i2cClk = UCS_getSMCLK (); param.datarate = USCI_B_I2C_SET_DATA_RATE_100KBPS;USCI_B1_initMaster_B (USCI_B1) param);// 启用 I2C 模块以启动操作 USCI_B_I2C_ENABLE (USCI_B1_base); //启用主器件接收中断 USCI_B_I2C_enableInterrupt (USCI_B1_base、USCI_B_I2C_receive_interrupt); } void i2c_write (uint8_t slave_address) {&t //初始化主设备 USCI_B_I2C_initMasterParam param ={0}; param.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK; param.i2cClk = UCS_getSMCLK (); param.datarate = USCI_B_I2C_SET_DATA_RATE_400KBPS; USCI_B_I2C_initMaster (USCI_B1_base、¶m); //指定从器件地址 USCI_B_I2C_setSlaveAddress (USCI_B1_BASE、SLAVE_ADDRESS ); //设置发送模式 USCI_B_I2C_setMode (USCI_B1_BASE、 USCI_B_I2C_Transmit 模式 ); //启用 I2C 模块以启动操作 USCI_B_I2C_ENABLE (USCI_B1_BASE); while (1) { //启用发送中断 USCI_B_I2C_clearInterrupt (USCI_B1_base、USCI_B_I2C_Transmit 中断); USCI_B_I2C_enableInterrupt (USCI_B1_base、USCI_B_I2C_Transmit _interrupt); //每次传输之间的延迟 _DELAY_CYCLES (50);//替换为计时器 ISR? //加载 TX 字节计数器 I2C_transmitCounter = 1; //启动开始并发送第一个字符 USCI_B_I2C_masterSendMultiByteStart (USCI_B1_base、i2c_transmitData[0]); //输入启用中断的 LPM0 _bis_SR_register (LPM0_bits + GIE); __no_operation(); //延迟直到传输完成 while (USCI_B_I2C_isBusy (USCI_B1_base)); } } void i2c_read_Byte (uint8_t slave_address、uint8_t byte_count) { //初始化主设备 USCI_B_I2C_initMasterParam param ={0}; param.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK; param.i2cClk = UCS_getSMCLK (); param.datarate = USCI_B_I2C_SET_DATA_RATE_100KBPS; USCI_B_I2C_initMaster (USCI_B1_base、¶m); //指定从器件地址 USCI_B_I2C_setSlaveAddress (USCI_B1_BASE、SLAVE_ADDRESS); //设置接收模式 USCI_B_I2C_setMode (USCI_B1_base、USCI_B_I2C_Receive_mode); //启用 I2C 模块以启动操作 USCI_B_I2C_ENABLE (USCI_B1_BASE); //启用主机接收中断 USCI_B_I2C_enableInterrupt (USCI_B1_base、USCI_B_I2C_receive_interrupt); //等待总线空闲 while (USCI_B_I2C_isBusy (USCI_B1_base)); while (1) { P_i2c_receivedBuffer =(unsigned char *) i2c_receivedBuffer; I2C_receivedCounter = i2c_receivedBuffer 的大小; //初始化多接收 USCI_B_I2C_masterReceiveMultiByteStart (USCI_B1_BASE); //进入启用中断的低功耗模式0。 _bis_SR_register (LPM0_bits + GIE); __no_operation(); } } void OPT3001_init (void) { uint8_t OPT3001_Config_SW_RESET[3]= { 0x01、//CDC 配置寄存器地址 0xC2、//MSB 配置(设置100ms 转换时间、单次触发模式) 0x10 //LSB 配置 }; P_i2c_transmitData =(uint8_t *) OPT3001_Config_sw_reset;//传输阵列起始地址 I2C_transmitCounter = OPT3001_Config_SW_RESET 的大小; //加载发送字节计数器 I2C_WRITE (OPT3001_ADDRESS); __DELAY_CYCLES (DELAY_10_MS); } Int32_t OPT3001_SingleRead (void) { //uint8_t CDC_Config[2]={0};//测试变量 uint8_t Lux_Measur1_MSB[2]={0x00、0x00};//电容 MEAS1的 MSB //uint32_t luxVal=0; int32_t Lux_MEAS1 = 0;来自 MEAS1的//24位 Lux 值(32位变量) uint8_t OPT3001_initMEAS1[3]= { 0x01、//选择配置寄存器地址 0xC2、//MSB 配置(设置100ms 转换时间、单次触发模式) 0x10 //LSB 配置 }; const uint8_t OPT3001_ResultAddr[1]={0x00};//Lux_MEAS1_MSB 寄存器地址 P_i2c_transmitData =(uint8_t *) OPT3001_initMEAS1; //发送阵列起始地址 I2C_transmitCounter = OPT3001_initMEAS1的大小; //加载发送字节计数器 I2C_WRITE (OPT3001_ADDRESS); _delay_cycles (delay_10_ms); P_i2c_transmitData =(uint8_t *) OPT3001_ResultAddr;//传输阵列起始地址 I2C_transmitCounter = OPT3001_ResultAddr 的大小; //加载发送字节计数器 I2C_WRITE (OPT3001_ADDRESS); P_i2c_receivedBuffer =(uint8_t *) Lux_Measur1_MSB; //接收阵列起始地址 I2C_READ_BYTE (OPT3001_ADDRESS、LUX_Meas1_MSB 的大小);//读取两个字节的 lux 数据形式结果寄存器 LUX_MEAS1 = 0x0FFF &(uint16_t) LUX_Measur1_MSB[0]<< 8 |(uint16_t) LUX_Measur1_MSB[1]; int8_t exp = lux_Meas1_MSB[0]>4;//指数是前四位 Lux_MEAS1 = 0.01 * pow (2、exp)* Lux_MEAS1; 返回 LUX_MEAS1; } //********* // ////这是 USCI_B1中断矢量处理例程。 //// ********* #if defined (__TI_Compiler_version__)|| defined (__IAR_systems_icc_) #pragma vector=USCI_B1_vector __interrupt #elif defined (__GNU__) __attribute__(INTERRUPT (USCI_B1_vector))) #endif void USCI_B1_ISR (void )(void) 开关(_偶数_在范围内(UCB1IV、12)){ USCI_I2C_UCTXIFG 案例: { //检查 TX 字节计数器 IF (i2c_transmitCounter < i2c_transmitData 的大小) { //启动从主设备到从设备的字符发送 USCI_B_I2C_masterSendMultiByteNext (USCI_B1_BASE、 I2C_transmitData[i2c_transmitCounter] ); //递增 TX 字节计数器 I2C_transmitCounter++; } 其他 { //仅启动停止 USCI_B_I2C_masterSendMultiByteStop (USCI_B1_BASE); //清除主机中断状态 USCI_B_I2C_clearInterrupt (USCI_B1_base、 USCI_B_I2C_Transmit 中断); //在中断返回时退出 LPM0 __BIC_SR_REGISTER_ON_EXIT (LPM0_Bits); } 中断; } USCI_I2C_UCRXIFG 案例: { //递减 RX 字节计数器 I2C_receivedCounter--; if (i2c_receivedCounter) { if (i2c_receivedCounter = 1) { //启动接收结束->接收字节与 NAK *p_i2c_receivedBuffer++= USCI_B_I2C_masterReceiveMultiByteFinish ( USCI_B1_BASE ); } 其他 { //每次接收一个字节 *p_i2c_receivedBuffer++= USCI_B_I2C_masterReceiveMultiByteNext ( USCI_B1_BASE ); } } 其他 { //接收最后一个字节 *p_i2c_receivedBuffer = USCI_B_I2C_masterReceiveMultiByteNext ( USCI_B1_BASE ); __BIC_SR_REGISTER_ON_EXIT (LPM0_Bits); } 中断; } }
我犯了一个错误,因为我最初要传递的初始化数据只有3个字节,但它们在 opt3001_int()中本地声明; 我更新了第110行上的代码,以实际使用 p_i2c_transmitData,而不是直接传递配置字节。
USCI_B_I2C_masterSendMultiByteStart (USCI_B1_BASE,* p_i2c_transmitData);
我还初始化了 receivata 和 transmitBuffer @[5]而不是[40];
我看到在我执行 i2c_write()之前首先启用 UCTXIFG;在这里禁用 UCNACKIFG,然后在 USCI_B_I2C_masterSendMultiByteStart()期间启用 UCNACKIFG;
Bruce、
我是否误解了 ISR 会中断;应该让我离开 while (1);在 i2c_write()中;? 具有 ISR 的此函数直接从 DriverLib 中提取(我确实在 DriverLib 中添加了 I2C TX 和 RX 的 case 语句)
1. 好的、我看到了您的意思。 我将 ISR 更改为仅检查 i2c_transmit count!= 0
2、除了数字1、我改变了概念、将数据大小调整为 TX 或 RX 递减计数器、直到没有剩余字节。
3. 同样有意义的是,我删除了它。 这是更新后的代码。
/* i2c_driver.c * *创建日期:2014年7月16日 * 作者:a0272990 * *版权所有2014 Texas Instruments Incorporated。 保留所有权利。 * */ //********************** //#includes //********* #include "driverlib.h" #include "i2c_driver.h" #include "QmathLib.h" #include "IQmathLib.h" #include "math.h" //********* //#defines //********* #define OPT3001_ADDRESS 0x44 // OPT3001的 I2C 地址 #define CHECK_POLARITY 0x80 //极性标志(MSB 的 MSB) //********* //全局变量 //********* #define RXCOUNT 0x05 #define TXLENGTH 0x04 uint8_t i2c_transmitCounter = 0;//可用于存储 I2C uint8_t i2c_transmitData[5]的发送状态的变量; // uint8_t * p_i2c_transmitData; //发送数据的指针 uint8_t i2c_receivedCounter = 0; //可用于存储 I2C uint8_t i2c_receivedBuffer[40]的接收状态的变量; // uint8_t * p_i2c_receivedBuffer; //指向接收数据的指针 //无符号字符接收缓冲区[10]={0x01、0x01、0x01、0x01、0x01、0x01、 0x01、0x01、0x01、0x01、0x01}; //unsigned char * receiveBufferPointer; //unsigned char receiveCount = 0; uint16_t i2c_mode = 0; //用于存储 i2c 模式(TX 或 Rx)的变量 //********* // I2C 库函数 //********* void init_i2c (void) { //将 I2C 引脚分配给 USCI_B1 GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P4、GPIO_PIN1 + GPIO_PIN2); //初始化主控 USCI_B_I2C_initMasterParam param ={0}; param.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK; param.i2cClk = UCS_getSMCLK (); param.datarate = USCI_B_I2C_SET_DATA_RATE_100KBPS;USCI_B1_initMaster_B (USCI_B1) param);// 启用 I2C 模块以启动操作 USCI_B_I2C_ENABLE (USCI_B1_base); //启用主器件接收中断 USCI_B_I2C_enableInterrupt (USCI_B1_base、USCI_B_I2C_receive_interrupt); } void i2c_write (uint8_t slave_address) {&t //初始化主设备 USCI_B_I2C_initMasterParam param ={0}; param.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK; param.i2cClk = UCS_getSMCLK (); param.datarate = USCI_B_I2C_SET_DATA_RATE_400KBPS; USCI_B_I2C_initMaster (USCI_B1_base、¶m); uint8_t SL_ADDR_WR =((slave_address<1));//将地址向左移位。 写入位使能= 0 //指定从器件地址 USCI_B_I2C_setSlaveAddress (USCI_B1_BASE、SL_ADDR_WR ); //设置发送模式 USCI_B_I2C_setMode (USCI_B1_BASE、 USCI_B_I2C_Transmit 模式 ); //启用 I2C 模块以启动操作 USCI_B_I2C_ENABLE (USCI_B1_BASE); //启用发送中断 USCI_B_I2C_clearInterrupt (USCI_B1_base、USCI_B_I2C_Transmit _interrupt + USCI_B_I2C_NAK_INTERRUPT); USCI_B_I2C_enableInterrupt (USCI_B1_base、USCI_B_I2C_Transmit _interrupt); //每次传输之间的延迟 _DELAY_CYCLES (50);//替换为计时器 ISR? //启动开始并发送第一个字符 USCI_B_I2C_masterSendMultiByteStart (USCI_B1_base、* p_i2c_transmitData++);//p_i2c_data 是数据包的第一个地址。 在 opt3001_init()中指定; I2C_transmitCounter --; //启用中断 _ bis_SR_register (GIE);//LPM0_bits + GIE _ no_operation (); //延迟直到传输完成 while (USCI_B_I2C_isBusBusy (USCI_B1_base)); } void i2c_read_Byte (uint8_t slave_address、uint8_t byte_count) { //初始化主设备 USCI_B_I2C_initMasterParam param ={0}; param.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK; param.i2cClk = UCS_getSMCLK (); param.datarate = USCI_B_I2C_SET_DATA_RATE_100KBPS; USCI_B_I2C_initMaster (USCI_B1_base、¶m); //指定从器件地址 uint8_t SL_ADDR_R =((slave_address<<1)| 0x01);//左移位地址&添加读取位 USCI_B_I2C_setSlaveAddress (USCI_B1_BASE、SLAVE_ADDRESS); //设置接收模式 USCI_B_I2C_setMode (USCI_B1_base、USCI_B_I2C_Receive_mode); //启用 I2C 模块以启动操作 USCI_B_I2C_ENABLE (USCI_B1_BASE); //启用主机接收中断 USCI_B_I2C_enableInterrupt (USCI_B1_base、USCI_B_I2C_receive_interrupt); //等待总线空闲 while (USCI_B_I2C_isBusy (USCI_B1_base)); while (1) { P_i2c_receivedBuffer =(unsigned char *) i2c_receivedBuffer; I2C_receivedCounter = i2c_receivedBuffer 的大小; //初始化多接收 USCI_B_I2C_masterReceiveMultiByteStart (USCI_B1_BASE); //进入启用中断的低功耗模式0。 //_bis_SR_register (GIE);//LPM0_bits + GIE __no_operation(); } } void OPT3001_init (void) { uint8_t OPT3001_Config_SW_RESET[3]= { 0x01、//CDC 配置寄存器地址 0xC2、//MSB 配置(设置100ms 转换时间、单次触发模式) 0x10 //LSB 配置 }; P_i2c_transmitData =(uint8_t *) OPT3001_Config_sw_reset;//传输阵列起始地址 I2C_transmitCounter = OPT3001_Config_SW_RESET 的大小; //加载发送字节计数器 I2C_WRITE (OPT3001_ADDRESS); __DELAY_CYCLES (DELAY_10_MS); } Int32_t OPT3001_SingleRead (void) { //uint8_t CDC_Config[2]={0};//测试变量 uint8_t Lux_Measur1_MSB[2]={0x00、0x00};//电容 MEAS1的 MSB //uint32_t luxVal=0; int32_t Lux_MEAS1 = 0;来自 MEAS1的//24位 Lux 值(32位变量) uint8_t OPT3001_initMEAS1[3]= { 0x01、//选择配置寄存器地址 0xc4、//MSB 配置(设置100ms 转换时间、连续转换 0x10 //LSB 配置 }; const uint8_t OPT3001_ResultAddr[1]={0x00};//Lux_MEAS1_MSB 寄存器地址 P_i2c_transmitData =(uint8_t *) OPT3001_initMEAS1; //发送阵列起始地址 I2C_transmitCounter = OPT3001_initMEAS1的大小; //加载发送字节计数器 I2C_WRITE (OPT3001_ADDRESS); _delay_cycles (delay_10_ms); P_i2c_transmitData =(uint8_t *) OPT3001_ResultAddr;//传输阵列起始地址 I2C_transmitCounter = OPT3001_ResultAddr 的大小; //加载发送字节计数器 I2C_WRITE (OPT3001_ADDRESS); P_i2c_receivedBuffer =(uint8_t *) Lux_Measur1_MSB; //接收阵列起始地址 I2C_READ_BYTE (OPT3001_ADDRESS、LUX_Meas1_MSB 的大小);//读取两个字节的 lux 数据形式结果寄存器 LUX_MEAS1 = 0x0FFF &(uint16_t) LUX_Measur1_MSB[0]<< 8 |(uint16_t) LUX_Measur1_MSB[1]; int8_t exp = lux_Meas1_MSB[0]>4;//指数是前四位 Lux_MEAS1 = 0.01 * pow (2、exp)* Lux_MEAS1; 返回 LUX_MEAS1; } //********* // ////这是 USCI_B1中断矢量处理例程。 //// ********* #if defined (__TI_Compiler_version__)|| defined (__IAR_systems_icc_) #pragma vector=USCI_B1_vector __interrupt #elif defined (__GNU__) __attribute__(INTERRUPT (USCI_B1_vector))) #endif void USCI_B1_ISR (void )(void) 开关(_偶数_在范围内(UCB1IV、12)){ USCI_I2C_UCTXIFG 案例: { //检查 TX 字节计数器 IF (i2c_transmitCounter) { //启动从主设备到从设备的字符发送 USCI_B_I2C_masterSendMultiByteNext (USCI_B1_BASE、 *p_i2c_transmitData++ ); //递增 TX 字节计数器 I2C_transmitCounter--; } 其他 { //仅启动停止 USCI_B_I2C_masterSendMultiByteStop (USCI_B1_BASE); //清除主机中断状态 USCI_B_I2C_clearInterrupt (USCI_B1_base、 USCI_B_I2C_Transmit 中断); //在中断返回时退出 LPM0 //_BIC_SR_REGISTER_ON_EXIT (LPM0_Bits);不在低功耗模式 中} 中断; } USCI_I2C_UCRXIFG 案例: { //递减 RX 字节计数器 I2C_receivedCounter--; if (i2c_receivedCounter) { if (i2c_receivedCounter = 1) { //启动接收结束->接收字节与 NAK *p_i2c_receivedBuffer++= USCI_B_I2C_masterReceiveMultiByteFinish ( USCI_B1_BASE ); } 其他 { //每次接收一个字节 *p_i2c_receivedBuffer++= USCI_B_I2C_masterReceiveMultiByteNext ( USCI_B1_BASE ); } } 其他 { //接收最后一个字节 *p_i2c_receivedBuffer = USCI_B_I2C_masterReceiveMultiByteNext ( USCI_B1_BASE ); //_BIC_SR_REGISTER_ON_EXIT (LPM0_Bits);不在低功耗模式 中} 中断; } }
你是对的。 我进行了测试、以查看这是否是一个问题。 不是。
我观察到的几件事:
在调试启动时 UCTXIFG 为1。 它在中断清除期间被禁用(看起来正常)。
2.当我单步执行 I2C_materSendMultiByteStart()时; UCTXIFG 最终在" while (!(HWREG8 (baseAddress + OFS_UCBxIFG)& UCTXIFG)"阶段被重新启用;(在 USCI_B_i2c.c 中、下面的第15行)
下一步是 HWREG8 (baseAddress + OFS_UCBxTXBUF)= txData;(同样、在 USCI_B_i2c.c 中)并且 UCTXIFG 再次被禁用。 这个分配正在将 TX 数据的第一个字节载入 TXBUF。 寄存器 UCB1TXBUF 显示来自 transmitData 的第一个字节的正确值(下面的第18行)
下面是数据捕获。 我实际上在寄存器中获得了一个 NACK 标志、但它不会显示在数据采集中。 也许我需要一个新主题、但我仍然不明白为什么当有数据被载入 UCB1TXBUF 时 UCTXIFG 不被启用
void USCI_B_I2C_masterSendMultiByteStart (uint16_t baseAddress、 uint8_t txData ) { //存储当前发送中断使能 uint8_t txieStatus = HWREG8 (baseAddress + OFS_UCBxIE)& UCTXIE; //禁用发送中断使能 HWREG8 (baseAddress + OFS_UCBxIE)&=~(UCTXIE); //发送启动条件。 HWREG8 (baseAddress + OFS_UCBxCTL1)|= UCTR + UCTXSTT; //轮询发送中断标志。 while (!(HWREG8 (baseAddress + OFS_UCBxIFG)& UCTXIFG)); //发送单字节数据。 HWREG8 (baseAddress + OFS_UCBxTXBUF)= txData; //恢复发送中断使能 HWREG8 (baseAddress + OFS_UCBxIE)|= txieStatus; }
我认为调试步进可能是主要问题之一。 根据设置断点的位置、TXIFG 可能无法正确触发。 我通过让代码在没有断点的情况下运行来发现这一点、并在 i2c 分析器中查看所有预期数据。
我现在似乎可以正常工作、但我确实发现 TIDA 00754中存在一些错误、其中 MSB 未正确分配到正确的变量中。 在任何情况下、这里都是最终代码。 我必须将 RXCOUNT 调整为固定的2个字节、以避免卡在 RX 环路中。
我想让它进入连续模式、而不是单次触发模式、但这是另一天的问题。
/* i2c_driver.c * *创建日期:2014年7月16日 * 作者:a0272990 * *版权所有2014 Texas Instruments Incorporated。 保留所有权利。 * */ //********************** //#includes //********* #include "driverlib.h" #include "i2c_driver.h" #include "QmathLib.h" #include "IQmathLib.h" #include "math.h" //********* //#defines //********* #define OPT3001_ADDRESS 0x44 // OPT3001的 I2C 地址 #define CHECK_POLARITY 0x80 //极性标志(MSB 的 MSB) //********* //全局变量 //********* #define RXCOUNT 0x02 // opt3001寄存器读取 的预期长度#define TXLENGTH 0x04 uint8_t i2c_transmitCounter = 0;//可用于存储 I2C uint8_t i2c_transmitData[5]的发送状态的变量; // uint8_t * p_i2c_transmitData; //发送数据的指针 uint8_t i2c_receivedCounter = 0; //可用于存储 I2C uint8_t i2c_receivedBuffer[2]的接收状态的变量; //仅适用于 opt3001 uint8_t *p_i2c_receivedBuffer; //指向接收数据的指针 //无符号字符接收缓冲区[10]={0x01、0x01、0x01、0x01、0x01、0x01、 0x01、0x01、0x01、0x01、0x01}; //unsigned char * receiveBufferPointer; //unsigned char receiveCount = 0; uint16_t i2c_mode = 0; //用于存储 i2c 模式(TX 或 Rx)的变量 //********* // I2C 库函数 //********* void init_i2c (void) { //将 I2C 引脚分配给 USCI_B1 GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P4、GPIO_PIN1 + GPIO_PIN2); //初始化主控 USCI_B_I2C_initMasterParam param ={0}; param.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK; param.i2cClk = UCS_getSMCLK (); param.datarate = USCI_B_I2C_SET_DATA_RATE_100KBPS;USCI_B1_initMaster_B (USCI_B1) param);// 启用 I2C 模块以启动操作 USCI_B_I2C_ENABLE (USCI_B1_base); //启用主器件接收中断 USCI_B_I2C_enableInterrupt (USCI_B1_base、USCI_B_I2C_receive_interrupt); } void i2c_write (uint8_t slave_address) {&t //初始化主设备 USCI_B_I2C_initMasterParam param ={0}; param.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK; param.i2cClk = UCS_getSMCLK (); param.datarate = USCI_B_I2C_SET_DATA_RATE_400KBPS; USCI_B_I2C_initMaster (USCI_B1_base、¶m); //uint8_t SL_ADDR_WR =((slave_address<<1));//向左移位地址。 写入位使能= 0 //指定从器件地址 USCI_B_I2C_setSlaveAddress (USCI_B1_BASE、SLAVE_ADDRESS ); //设置发送模式 USCI_B_I2C_setMode (USCI_B1_BASE、 USCI_B_I2C_Transmit 模式 ); //启用 I2C 模块以启动操作 USCI_B_I2C_ENABLE (USCI_B1_BASE); //启用发送中断 USCI_B_I2C_clearInterrupt (USCI_B1_base、USCI_B_I2C_Transmit _interrupt + USCI_B_I2C_NAK_INTERRUPT); USCI_B_I2C_enableInterrupt (USCI_B1_base、USCI_B_I2C_Transmit _interrupt); //每次传输之间的延迟 _DELAY_CYCLES (50);//替换为计时器 ISR? //启动开始并发送第一个字符 USCI_B_I2C_masterSendMultiByteStart (USCI_B1_base、* p_i2c_transmitData++);//p_i2c_data 是数据包的第一个地址。 在 opt3001_init()中指定; I2C_transmitCounter --; //启用中断 _ bis_SR_register (GIE);//LPM0_bits + GIE _ no_operation (); //延迟直到传输完成 while (USCI_B_I2C_isBusBusy (USCI_B1_base)); } void i2c_read_Byte (uint8_t slave_address、uint8_t byte_count) { //初始化主设备 USCI_B_I2C_initMasterParam param ={0}; param.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK; param.i2cClk = UCS_getSMCLK (); param.datarate = USCI_B_I2C_SET_DATA_RATE_100KBPS; USCI_B_I2C_initMaster (USCI_B1_base、¶m); //指定从器件地址。 使用7BIT 从器件 ADDR USCI_B_I2C_setSlaveAddress (USCI_B1_BASE、SLAVE_ADDRESS); //设置接收模式 USCI_B_I2C_setMode (USCI_B1_base、USCI_B_I2C_Receive_mode); //启用 I2C 模块以启动操作 USCI_B_I2C_ENABLE (USCI_B1_BASE); //启用主机接收中断 USCI_B_I2C_enableInterrupt (USCI_B1_base、USCI_B_I2C_receive_interrupt); //等待总线空闲 while (USCI_B_I2C_isBusy (USCI_B1_base)); P_i2c_receivedBuffer =(unsigned char *) i2c_receivedBuffer; I2C_receivedCounter = RXCOUNT; //初始化多接收 USCI_B_I2C_masterReceiveMultiByteStart (USCI_B1_BASE); //进入启用中断的低功耗模式0。 _bis_SR_register (GIE);//LPM0_bits + GIE __no_operation(); } void OPT3001_init (void) { uint8_t OPT3001_Config_SW_RESET[3]= { 0x01、//CDC 配置寄存器地址 0xC2、//MSB 配置(设置100ms 转换时间、单次触发模式) 0x10 //LSB 配置 }; P_i2c_transmitData =(uint8_t *) OPT3001_Config_sw_reset;//传输阵列起始地址 I2C_transmitCounter = OPT3001_Config_SW_RESET 的大小; //加载发送字节计数器 I2C_WRITE (OPT3001_ADDRESS); __DELAY_CYCLES (DELAY_10_MS); } Int32_t OPT3001_SingleRead (void) { //uint8_t CDC_Config[2]={0};//测试变量 uint8_t Lux_Measur1_MSB[2]={0x00、0x00};//电容 MEAS1的 MSB //uint32_t luxVal=0; int32_t Lux_MEAS1 = 0;来自 MEAS1的//24位 Lux 值(32位变量) uint8_t OPT3001_initMEAS1[3]= { 0x01、//选择配置寄存器地址 0xC2、//MSB 配置(设置100ms 转换时间、连续转换 0x10 //LSB 配置 }; const uint8_t OPT3001_ResultAddr[1]={0x00};//Lux_MEAS1_MSB 寄存器地址 P_i2c_transmitData =(uint8_t *) OPT3001_initMEAS1; //发送阵列起始地址 I2C_transmitCounter = OPT3001_initMEAS1的大小; //加载发送字节计数器 I2C_WRITE (OPT3001_ADDRESS); _delay_cycles (delay_10_ms); P_i2c_transmitData =(uint8_t *) OPT3001_ResultAddr;//传输阵列起始地址 I2C_transmitCounter = OPT3001_ResultAddr 的大小; //加载发送字节计数器 I2C_WRITE (OPT3001_ADDRESS); P_i2c_receivedBuffer =(uint8_t *) Lux_Measur1_MSB; //接收阵列起始地址 I2C_READ_BYTE (OPT3001_ADDRESS、LUX_Meas1_MSB 的大小);//读取两个字节的 lux 数据形式结果寄存器 LUX_Meas1_MSB[0]= i2c_receivedBuffer[0]; LUX_Meas1_MSB[1]= i2c_receivedBuffer[1]; LUX_MEAS1 = 0x0FFF &(uint16_t) LUX_Measur1_MSB[0]<< 8 |(uint16_t) LUX_Measur1_MSB[1]; int8_t exp = lux_Meas1_MSB[0]>4;//指数是前四位 Lux_MEAS1 = 0.01 * pow (2、exp)* Lux_MEAS1; 返回 LUX_MEAS1; } int32_t OPT3001_ID (uint8_t opt_ID_TYPE) { uint8_t readid_msb[2]={0x00、0x00}; ///此时已由 opt3001_int()配置; uint8_t OPT3001_initMEAS1[3]= { 0x01、//选择配置寄存器地址 0xC2、//MSB 配置(设置100ms 转换时间、连续转换 0x10 //LSB 配置 }; P_i2c_transmitData =(uint8_t *) OPT3001_initMEAS1; //发送阵列起始地址 I2C_transmitCounter = OPT3001_initMEAS1的大小; //加载发送字节计数器 I2C_WRITE (OPT3001_ADDRESS); _delay_cycles (delay_10_ms); P_i2c_transmitData =(uint8_t *) opt_ID_type;//传输阵列起始地址 I2C_transmitCounter = opt_ID_type 的大小; //加载发送字节计数器 I2C_WRITE (OPT3001_ADDRESS); P_i2c_receivedBuffer =(uint8_t *) readid_msb; //接收阵列起始地址 I2C_READ_BYTE (OPT3001_ADDRESS、sizeof readid_msb);//读取两个字节的 lux 数据形式结果寄存器 uint32_t readid = 0x0FFF &(uint16_t) readid_msb[0]<< 8 |(uint16_t) readid_msb[1]; 退货读数; } //********* // ////这是 USCI_B1中断矢量处理例程。 //// ********* #if defined (__TI_Compiler_version__)|| defined (__IAR_systems_icc_) #pragma vector=USCI_B1_vector __interrupt #elif defined (__GNU__) __attribute__(INTERRUPT (USCI_B1_vector))) #endif void USCI_B1_ISR (void )(void) 开关(_偶数_在范围内(UCB1IV、12)){ USCI_I2C_UCTXIFG 案例: { //检查 TX 字节计数器 IF (i2c_transmitCounter) { //启动从主设备到从设备的字符发送 USCI_B_I2C_masterSendMultiByteNext (USCI_B1_BASE、 *p_i2c_transmitData++ ); //递增 TX 字节计数器 I2C_transmitCounter--; } 其他 { //仅启动停止 USCI_B_I2C_masterSendMultiByteStop (USCI_B1_BASE); //清除主机中断状态 USCI_B_I2C_clearInterrupt (USCI_B1_base、 USCI_B_I2C_Transmit 中断); //在中断返回时退出 LPM0 //_BIC_SR_REGISTER_ON_EXIT (LPM0_Bits);不在低功耗模式 中} 中断; } USCI_I2C_UCRXIFG 案例: { //递减 RX 字节计数器 I2C_receivedCounter--; if (i2c_receivedCounter) { if (i2c_receivedCounter = 1) { //启动接收结束->接收字节与 NAK *p_i2c_receivedBuffer++= USCI_B_I2C_masterReceiveMultiByteFinish( USCI_B1_base ); } 其他 { //每次接收一个字节 *p_i2c_receivedBuffer++= USCI_B_I2C_masterReceiveMultiByteNext (USCI_B1_base); } } 其他 { //接收最后一个字节 *p_i2c_receivedBuffer = USCI_B_I2C_masterReceiveMultiByteNext (USCI_B1_base); __BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//不在低功耗模式 中} 中断; } }