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.
你好,想问一下,现在我手上有一块fr6989的launchpad,当我使用driverlib的硬件i2c的例子的时候,无论是主机还是从机模式都没反应,特别是主机模式发送,用示波器钩对应脚p1.6 1.7,一点反应都没有,跟踪内部寄存器,都是配置正确的,流程也是对的,就是不知道为什么一点反应都没有。1.6 1.7口通过普通输出IO翻转验证是好的。当从机的时候UCBBUSY就为1,ucsllow为0。外部已经加了上拉电阻。
确认下,i2c配置完成以后p1.6和p1.7是否都是高电平
正常情况下,i2c主机发送时,时钟线上能够看到时钟信号,数据线上能看到发的从地址
i2c从机的UCBBUSY位应该是接收到起始信号后才会置位,接收到结束信号后后会清零
硬件是开发板,应该没啥问题,还是怀疑配置上有错误
谢谢解答。配置完后,需要设置内部上拉或者外部上拉才为高电平。然而发送时用示波器观察p1.7时钟脚确实没有信号,我用的是ti官方driverlib中的example,它是通过调用库函数初始化操作,我看了他的库函数确实配置流程是和userguide一致,跑起来后观察uscb中i2c相关所有寄存器配置值也是对的上的,非常奇怪,不会是他的库函数有问题吧。有没有代码参考一下
谢谢解答。配置完后,需要设置内部上拉或者外部上拉才为高电平。然而发送时用示波器观察p1.7时钟脚确实没有信号一直为高,我用的是ti官方driverlib中的example,它是通过调用库函数初始化操作,我看了他的库函数确实配置流程是和userguide一致,跑起来后观察uscb中i2c相关所有寄存器配置值也是对的上的,非常奇怪,不会是他的库函数有问题吧。有没有代码参考一下
谢谢回答。
我下的driverlib版本里都是库函数操作的,没有寄存器操作的,因为电脑用ccs一编译就卡死,只能用IAR。
我已经再买了一块fr5969的launchpad,还没到。我主要是想用从机模式,第一次接触430平台,时间紧,只能用库函数的方式了。
//----------------------------------这是driverlib中的例程-----------------------------------------------------//
//--------------------------------------------------------------------------------------------------------------------//
#include "driverlib.h"
//*****************************************************************************
//!
//! Description: This demo connects two MSP430's via the I2C bus. The master
//! reads from the slave. This is the SLAVE code. The TX data begins at 0
//! and is incremented each time it is sent. A stop condition
//! is used as a trigger to increment the outgoing data.
//! The USCI_B0 TX interrupt is used to know
//! when to TX.
//! Tested on MSP430FR5969
//!
//! /|\ /|\
// //! 10k 10k
//! slave | | master
//! ----------------- | | -----------------
//! -|XIN P1.6/UCB0SDA|<-|----+->|P1.6/UCB0SDA XIN|-
//! | | | | |
//! -|XOUT | | | XOUT|-
//! | P1.7/UCB0SCL|<-+------>|P1.7/UCB0SCL |
//! | | | |
//!
//! This example uses the following peripherals and I/O signals. You must
//! review these and change as needed for your own board:
//! - I2C peripheral
//! - GPIO Port peripheral (for I2C pins)
//! - SCL2
//! - SDA
//!
//! This example uses the following interrupt handlers. To use this example
//! in your own application you must add these interrupt handlers to your
//! vector table.
//! - USCI_B0_VECTOR.
//!
//*****************************************************************************
//*****************************************************************************
//
//Set the address for slave module. This is a 7-bit address sent in the
//following format:
//[A6:A5:A4:A3:A2:A1:A0:RS]
//
//A zero in the "RS" position of the first byte means that the master
//transmits (sends) data to the selected slave, and a one in this position
//means that the master receives data from the slave.
//
//*****************************************************************************
#define SLAVE_ADDRESS 0x48
uint8_t TXData = 0x00;
void main(void)
{
WDT_A_hold(WDT_A_BASE);
// Configure Pins for I2C
//Set P1.6 and P1.7 as Secondary Module Function Input.
/*
* Select Port 1
* Set Pin 6, 7 to input Secondary Module Function, (UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL).
*/
GPIO_setAsPeripheralModuleFunctionInputPin(
GPIO_PORT_P1,
GPIO_PIN6 + GPIO_PIN7,
GPIO_SECONDARY_MODULE_FUNCTION
);
/*
* Disable the GPIO power-on default high-impedance mode to activate
* previously configured port settings
*/
PMM_unlockLPM5();
// eUSCI configuration
EUSCI_B_I2C_initSlaveParam param = {0};
param.slaveAddress = SLAVE_ADDRESS;
param.slaveAddressOffset = EUSCI_B_I2C_OWN_ADDRESS_OFFSET0;
param.slaveOwnAddressEnable = EUSCI_B_I2C_OWN_ADDRESS_ENABLE;
EUSCI_B_I2C_initSlave(EUSCI_B0_BASE, ¶m);
//Enable I2C Module to start operations
EUSCI_B_I2C_enable(EUSCI_B0_BASE);
EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0 +
EUSCI_B_I2C_STOP_INTERRUPT
);
EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0 +
EUSCI_B_I2C_STOP_INTERRUPT
);
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
__no_operation();
}
//******************************************************************************
//
//This is the USCI_B0 interrupt vector service routine.
//
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B0_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(USCI_B0_VECTOR)))
#endif
void USCIB0_ISR(void)
{
switch(__even_in_range(UCB0IV,0x1E))
{
case 0x00: break; // Vector 0: No interrupts break;
case 0x02: break; // Vector 2: ALIFG
case 0x04: break; // Vector 4: NACKIFG
case 0x06: break; // Vector 6: STTIFG
case 0x08: // Vector 8: STPIFG
TXData++;
break;
case 0x0a: break; // Vector 10: RXIFG3 break;
case 0x0c: break; // Vector 14: TXIFG3 break;
case 0x0e: break; // Vector 16: RXIFG2 break;
case 0x10: break; // Vector 18: TXIFG2 break;
case 0x12: break; // Vector 20: RXIFG1 break;
case 0x14: break; // Vector 22: TXIFG1 break;
case 0x16: break; // Vector 24: RXIFG0 break;
case 0x18:
EUSCI_B_I2C_slavePutData(EUSCI_B0_BASE,
TXData
);
break; // Vector 26: TXIFG0 break;
case 0x1a: break; // Vector 28: BCNTIFG break;
case 0x1c: break; // Vector 30: clock low timeout break;
case 0x1e: break; // Vector 32: 9th bit break;
default: break;
}
}
//-------------------------------------------------------------------------------------------------------------//
//----------------------------------这是库函数定义-----------------------------------------------------//
//-------------------------------------------------------------------------------------------------------------//
void EUSCI_B_I2C_initSlave(uint16_t baseAddress,
EUSCI_B_I2C_initSlaveParam *param)
{
//Disable the USCI module
HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCSWRST;
//Clear USCI master mode
HWREG16(baseAddress + OFS_UCBxCTLW0) &= ~UCMST;
//Configure I2C as Slave and Synchronous mode
HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCMODE_3 + UCSYNC;
//Set up the slave address.
HWREG16(baseAddress + OFS_UCBxI2COA0 + param->slaveAddressOffset)
= param->slaveAddress + param->slaveOwnAddressEnable;
}
//-------------------------------------------------------------------------------------------------------------//
void EUSCI_B_I2C_enable(uint16_t baseAddress)
{
//Reset the UCSWRST bit to enable the USCI Module
HWREG16(baseAddress + OFS_UCBxCTLW0) &= ~(UCSWRST);
}
//-------------------------------------------------------------------------------------------------------------//
void EUSCI_B_I2C_disable(uint16_t baseAddress)
{
//Set the UCSWRST bit to disable the USCI Module
HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCSWRST;
}
//-------------------------------------------------------------------------------------------------------------//
void EUSCI_B_I2C_enableInterrupt(uint16_t baseAddress,
uint16_t mask)
{
//Enable the interrupt masked bit
HWREG16(baseAddress + OFS_UCBxIE) |= mask;
}
//-------------------------------------------------------------------------------------------------------------//
void EUSCI_B_I2C_disableInterrupt(uint16_t baseAddress,
uint16_t mask)
{
//Disable the interrupt masked bit
HWREG16(baseAddress + OFS_UCBxIE) &= ~(mask);
}
//-------------------------------------------------------------------------------------------------------------//
void EUSCI_B_I2C_clearInterrupt(uint16_t baseAddress,
uint16_t mask)
{
//Clear the I2C interrupt source.
HWREG16(baseAddress + OFS_UCBxIFG) &= ~(mask);
}
i2c配置完成后,在不通信的时候,时钟线和数据线一定是高电平,这点没有异议,是不需要做内部上拉的,希望仔细看一下开发板电路图,这两根线外部是否有上拉电阻,是否上拉到同一个电源上,我用5739的开发板它就没有外部上拉,是不可以进行i2c通信的
那和我5739的开发板是一样的,没有上拉,是做不了i2c通信的,如果用外部的板子上拉要注意和单片机的电源电压保持一致,否则也可能带来问题,最好的还是用4.7k电阻上拉到单片机的Vcc
fr6989的launchpad P1.6,P1.7没有上拉电阻,做不了I2C,要做硬件I2C的话,data和clock一定要上拉,一般是4.7K