整个框架是: 定时器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, ¶m);
//Specify slave address
EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE, SlaveAddr);
//Set Master in receive mode
EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);
//Enable I2C Module to start operations
EUSCI_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)
初入硬件,调了好几天了。。很惆怅,希望大家能够提供一点帮助蛤。
