Quantcast
Channel: MSP 低功耗微控制器论坛 - 最近的话题
Viewing all articles
Browse latest Browse all 3634

msp430i2021 定时器触发 硬件IIC读写

$
0
0

整个框架是: 定时器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 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)

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


Viewing all articles
Browse latest Browse all 3634

Trending Articles