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

msp430i2021 定时器触发 硬件IIC读写

整个框架是: 定时器1ms 中断一次,ISR里采集AD, 采集加速度计9轴(iic),并发送给串口。

AD和串口部分都是没有问题的,但是硬件iic的部分一直没有调通。

(备注: 如果按照iic 400kb/s 的情况算,1ms的时间里是可以完成这些动作的)

由于,库函数中没有直接读写slave中的特定寄存器的代码,我根据自己的需求写了如下i2c.c的代码:

#include "driverlib.h"

uint8_t myI2CRxData[14];

void myI2C_Init(uint16_t SlaveAddr){GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,GPIO_PIN6 + GPIO_PIN7,GPIO_TERNARY_MODULE_FUNCTION);EUSCI_B_I2C_initMasterParam param = {0};param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;param.i2cClk =  16384000 ;param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_400KBPS;param.byteCounterThreshold = 1;param.autoSTOPGeneration =  EUSCI_B_I2C_NO_AUTO_STOP;EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, &param);//Specify slave addressEUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE, SlaveAddr);//Set Master in receive modeEUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);//Enable I2C Module to start operationsEUSCI_B_I2C_enable(EUSCI_B0_BASE);

//EUSCI_B_I2C_disableInterrupt(EUSCI_B0_BASE,
//EUSCI_B_I2C_RECEIVE_INTERRUPT0 +
//EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT
//);
//
//EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE,
//EUSCI_B_I2C_RECEIVE_INTERRUPT0 +
//EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT
//);
}


//1> EUSCI_B_I2C_masterSendMultiByteStart ----> start + data(slave address(W))
//2> EUSCI_B_I2C_masterSendMultiByteNext  ----> data(REG address)
//3> EUSCI_B_I2C_masterSendMultiByteFinish  ----> data + stop

void myI2C_WriteSingleByte(uint16_t baseAddress, uint8_t SlaveAddress,uint8_t RegAddress, uint8_t TxData){
	SlaveAddress = SlaveAddress << 1;
	SlaveAddress += 1; // 最低位w操作1 , r操作0
	EUSCI_B_I2C_masterSendMultiByteStart(baseAddress,SlaveAddress);//send start + data(slave address(W))
	EUSCI_B_I2C_masterSendMultiByteNext(baseAddress,RegAddress);// send  data(REG address)
	EUSCI_B_I2C_masterSendMultiByteFinish(baseAddress,TxData);//send data + stop
}

//1> EUSCI_B_I2C_masterSendMultiByteStart----> start + data(slave address(W))
//2> EUSCI_B_I2C_masterSendMultiByteNext----> data(REG address)
//3> EUSCI_B_I2C_masterSendMultiByteStart----> start + data(slave address(R))
//4> EUSCI_B_I2C_masterReceiveMultiByteNext----> data(重复此函数,读取n-1个)
//5> EUSCI_B_I2C_masterReceiveMultiByteFinish ----> data + stop

void myI2C_ReadContinueBytes(uint16_t baseAddress, uint8_t SlaveAddress,uint8_t RegAddress, int REGnum){

	SlaveAddress = SlaveAddress << 1;
	SlaveAddress |= 1; // 最低位w操作1 , r操作0
	EUSCI_B_I2C_masterSendMultiByteStart(baseAddress,SlaveAddress);//send start + data(slave address(W))
	EUSCI_B_I2C_masterSendMultiByteNext(baseAddress,RegAddress);// send data(REG address)
	SlaveAddress &= 0; // 最低位w操作1 , r操作0
	EUSCI_B_I2C_masterSendMultiByteStart(baseAddress,SlaveAddress);//send start + data(slave address(R))
	int i;
	for(i=0; i<REGnum-1;i++){
		myI2CRxData[i] = EUSCI_B_I2C_masterReceiveMultiByteNext(baseAddress); //receive data(重复此函数,读取n-1个)
	}
	myI2CRxData[REGnum-1] = EUSCI_B_I2C_masterReceiveMultiByteFinish(baseAddress); //receive data + stop
}

以及用到该函数的MPU9255部分的代码:
/*
 * myMPU9255.c
 *
 *  Created on: 2017年7月17日
 *Author: ShawnX
 */
#include "driverlib.h"
#include "myI2C.h"
#include "myMPU9255.h"

extern uint8_t myI2CRxData[14];

void myMPU9255_Init(void){

	myI2C_Init(SLAVE_ADDRESS);
	myI2C_WriteSingleByte(EUSCI_B0_BASE, SLAVE_ADDRESS, PWR_MGMT_1,0x00); //resume from sleep.
	myI2C_WriteSingleByte(EUSCI_B0_BASE, SLAVE_ADDRESS, SMPLRT_DIV, 0x07);
	myI2C_WriteSingleByte(EUSCI_B0_BASE, SLAVE_ADDRESS, CONFIG, 0x06);
	myI2C_WriteSingleByte(EUSCI_B0_BASE, SLAVE_ADDRESS, GYRO_CONFIG, 0x18);
	myI2C_WriteSingleByte(EUSCI_B0_BASE, SLAVE_ADDRESS, ACCEL_CONFIG, 0x01);
}

void  myAccelGyro_Read(void){myI2C_ReadContinueBytes(EUSCI_B0_BASE, SLAVE_ADDRESS, 0x3B,14);

}

 
但是程序运行后,一直卡在库函数中这句话上
//Poll for transmit interrupt flag.while(!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)){;}

总结一下我的问题:

1. 程序出错在什么地方呢?

2. 是否能够提供可以直接读写slave特定寄存器的库函数呢?或者相关硬件iic的参考函数呢?(ps,由于使用了定时器中断,所以为了避免中断嵌套,最好是不用中断方式的iic)

初入硬件,调了好几天了。。很惆怅,希望大家能够提供一点帮助蛤。

Shawn Hsiia:

这个是我工程文件,希望大家能给点指点。

灰小子:

mspware里有iic相关的例程,楼主可以参考下

Shawn Hsiia:

回复 灰小子:

您好,

我参考的确实是mspware里的程序,它里面提供的例程都是用中断的方式,而且也没有读写特定寄存器,特别的不实用。

这是driverlib里的库函数,都是这种没有读写特定寄存器的函数。

还请前辈指教。

赞(0)
未经允许不得转载:TI中文支持网 » msp430i2021 定时器触发 硬件IIC读写
分享到: 更多 (0)