|
楼主
查看: 5091回复: 3
发表于 2019-11-25 23:24:08
只看该作者
SDK例程解析,源码与SDK有所改动,请参考帖子中的源码进行实验。
例程描述和实验现象,请参考下边的图片:
更多的细节可参考以下代码:
主机端的代码:
- /*******************************************************************************
- * MSP432 I2C - EUSCI_B0_BASE I2C Master TX multiple bytes to multiple MSP432 Slaves
- *
- * 描述:
- * 两个MSP432通过IIC总线进行连接。
- * 同一个EUSCI模块配置成多个从机构造多从机的环境,主机发送多个数据到不同的从机。
- *
- * 该例程是主机端的代码。
- * 主机通过修改I2C_setSlaveAddress,将数据发送到不同的从机地址。
- * 往两个从机分别发送4个不同的字节;
- *
- ******************************************************************************/
- //库函数头文件包含
- #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
- //标准头文件
- #include <stdint.h>
- #include <stdbool.h>
- //例程相关的定义
- #define SLAVE_ADDRESS_1 0x48
- #define SLAVE_ADDRESS_2 0x49
- //变量定义
- static uint8_t TXData = 0;
- static uint8_t TXByteCtr;
- static volatile bool sendStopCondition;
- static volatile bool sendToSlaveAddress2;
- //主机的IIC参数配置,速率选择(100KBPS, 400KBPS)
- const eUSCI_I2C_MasterConfig i2cConfig =
- {
- EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // 选择时钟源SMCLK
- 3000000, // SMCLK的频率是3MHz (默认)
- EUSCI_B_I2C_SET_DATA_RATE_100KBPS, // 设置I2C时钟速率为100khz
- 0, // 不使用字节计数阈值
- EUSCI_B_I2C_NO_AUTO_STOP // 不自动产生STOP
- };
- int main(void)
- {
- //禁用看门狗
- MAP_WDT_A_holdTimer();
- //选择P1.6和P1.7为功能引脚(UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL).
- MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
- GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);
- sendStopCondition = false;
- sendToSlaveAddress2 = false;
- //配置I2C为主机,采用SMCLK,工作在100khz,无自动停止位
- MAP_I2C_initMaster(EUSCI_B0_BASE, &i2cConfig);
- //设置要通信的第一个从机地址
- MAP_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS_1);
- //设置主机位发送模式
- MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
- //启用I2C模块
- MAP_I2C_enableModule(EUSCI_B0_BASE);
- //清除中断标志位
- MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE,
- EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);
- //使能发送中断和无应答中断
- MAP_I2C_enableInterrupt(EUSCI_B0_BASE,
- EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);
- MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
-
- while (1)
- {
- //加载字节计数器
- TXByteCtr = 4;
- //确保最后一个字节已经发送完成
- while (MAP_I2C_masterIsStopSent(EUSCI_B0_BASE) == EUSCI_B_I2C_SENDING_STOP);
- //设置从机地址,然后发送START
- if(sendToSlaveAddress2)
- {
- MAP_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS_2);
- }
- else
- {
- MAP_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS_1);
- }
- MAP_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, TXData++);
- TXByteCtr--;
- while(sendStopCondition == false)
- {
- //发送过程中进入低功耗模式
- MAP_Interrupt_enableSleepOnIsrExit();
- MAP_PCM_gotoLPM0InterruptSafe();
- }
- sendStopCondition = false;
- }
- }
- /*******************************************************************************
- * USCIAB0TX_ISR用于发送数据, 字节数定义在TXByteCtr中。
- * TXData表示下一个要发送的数据。
- *******************************************************************************/
- void EUSCIB0_IRQHandler(void)
- {
- uint_fas**_t status;
- status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B0_BASE);
- MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, status);
- if (status & EUSCI_B_I2C_NAK_INTERRUPT)
- {
- MAP_I2C_masterSendStart(EUSCI_B0_BASE);
- return;
- }
- //判断计数,如果不为零,发送下一个数据,同时计数减1
- if (TXByteCtr)
- {
- //TXByteCtr: (4),3,2,1
- MAP_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, TXData++);
- TXByteCtr--;
- }
- else
- {
- //发送停止信号STOP
- MAP_I2C_masterSendMultiByteStop(EUSCI_B0_BASE);
- //用于退出低功耗模式
- sendStopCondition = true;
- //切换要设置的从机地址
- sendToSlaveAddress2 = !sendToSlaveAddress2;
- MAP_Interrupt_disableSleepOnIsrExit();
- }
- }
复制代码
从极端的代码:
- /******************************************************************************
- * MSP432 I2C - EUSCI_B0_BASE I2C Master TX multiple bytes to multiple MSP432 Slaves
- *
- * 描述:
- * 两个MSP432通过IIC总线进行连接。
- * 同一个EUSCI模块配置成多个从机构造多从机的环境,主机发送多个数据到从机。
- *
- * 该例程是从机端的代码。
- * 从机设备使用EUSCI0模块,演示了两个独立的从机地址;
- * 在IIC的中断服务程序中,不同的接收地址具有不同的接收服务程序。因此将接收的数据放在不同的接收区。
- *
- * ACLK = n/a, MCLK = HSMCLK = SMCLK = BRCLK = default DCO = ~3.0MHz
- *
- *
- *****************************************************************************/
- //库函数头文件包含
- #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
- //标准头文件
- #include <stdint.h>
- #include <stdbool.h>
- //例程相关的定义
- #define SLAVE_ADDRESS_1 0x48
- #define SLAVE_ADDRESS_2 0x49
- #define NUM_OF_RX_BYTES 4
- //变量定义
- static volatile uint8_t RXData_0[NUM_OF_RX_BYTES];
- static volatile uint32_t rxIndex_0;
- static volatile uint8_t RXData_1[NUM_OF_RX_BYTES];
- static volatile uint32_t rxIndex_1;
- int main(void)
- {
- //停用看门狗
- MAP_WDT_A_holdTimer();
- rxIndex_0 = 0;
- rxIndex_1 = 0;
- //选择P1.6和P1.7用作功能引脚,IIC接口.
- MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
- GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);
- //配置从机地址1(0x48)
- MAP_I2C_initSlave(EUSCI_B0_BASE, SLAVE_ADDRESS_1,
- EUSCI_B_I2C_OWN_ADDRESS_OFFSET0,
- EUSCI_B_I2C_OWN_ADDRESS_ENABLE);
- //配置从机地址2(0x49)
- MAP_I2C_initSlave(EUSCI_B0_BASE, SLAVE_ADDRESS_2,
- EUSCI_B_I2C_OWN_ADDRESS_OFFSET1,
- EUSCI_B_I2C_OWN_ADDRESS_ENABLE);
- //设置处于接收模式
- MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);
- //使能模块和使能中断
- MAP_I2C_enableModule(EUSCI_B0_BASE);
- MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE,EUSCI_B_I2C_RECEIVE_INTERRUPT0 | EUSCI_B_I2C_RECEIVE_INTERRUPT1);
- MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0 | EUSCI_B_I2C_RECEIVE_INTERRUPT1);
- MAP_Interrupt_enableSleepOnIsrExit();
- MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
- MAP_Interrupt_enableMaster();
- //进入低功耗模式
- while (1)
- {
- MAP_PCM_gotoLPM0();
- }
- }
- /******************************************************************************
- * eUSCI_B0 中断服务函数
- *
- * 在中断中处理接收到数据
- *
- ******************************************************************************/
- void EUSCIB0_IRQHandler(void)
- {
- uint_fas**_t status;
- status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B0_BASE);
- MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, status);
- //从机地址的 RXIFG
- if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)
- {
- RXData_0[rxIndex_0++] = MAP_I2C_slaveGetData(EUSCI_B0_BASE);
- //数组下标判断
- if (rxIndex_0 == NUM_OF_RX_BYTES)
- {
- rxIndex_0 = 0;
- }
- }
- //另一个从机地址的 RXIFG
- if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT1)
- {
- RXData_1[rxIndex_1++] = MAP_I2C_slaveGetData(EUSCI_B0_BASE);
- //数组下标判断
- if (rxIndex_1 == NUM_OF_RX_BYTES)
- {
- //可在此处设置断点
- rxIndex_1 = 0;
- }
- }
- }
复制代码
|
|