|
楼主
查看: 4070回复: 1
发表于 2019-11-23 23:09:48
只看该作者
SDK例程解析,源码与SDK有所改动,请参考帖子中的源码进行实验。
例程描述和实验现象,请参考下边的图片;
更多的细节可参考以下代码:
主机端的代码:
- /******************************************************************************
- * MSP432 I2C - EUSCI_B0 I2C主机发送1个字节到从机,然后RESTART读取10个字节
- *
- * 描述:
- * 两个MSP432通过IIC总线进行连接。主机发送数据到从机。
- * 主机发送1个字节到从机,紧跟着RESTART, 从从机读取10个字节;
- * 这个一个常规的操作,从从机设备读取多个数据,例如传感器.
- *
- * 该例程是主机端的代码。
- * 主机会对接收到的10个字节数据进行判断;
- * 如果收到的10个数据符合预期,则通过红色LED闪烁进行指示;
- * 如果收到的数据不符合预期,则通过绿色的LED闪烁指示。
- *
- * 注意:
- * 原例程中关于低功耗的代码已经移除;
- *
- *****************************************************************************/
- //库函数头文件包含
- #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
- //标准头文件
- #include <stdint.h>
- #include <stdbool.h>
- #include <string.h>
- //例程相关的定义
- #define SLAVE_ADDRESS 0x48
- #define NUM_OF_REC_BYTES 10
- //变量定义
- const uint8_t TXData[] = {0x04};
- static uint8_t RXData[NUM_OF_REC_BYTES];
- static volatile uint32_t rxIndex;
- static volatile bool stopSent;
- //主机的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)
- {
- volatile uint32_t ii;
- //停用看门狗
- MAP_WDT_A_holdTimer();
- //P1.0正确接收预期数据的指示灯
- MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
- MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
- //P2.1接收的数据不符合预期的指示灯
- MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN1);
- MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN1);
- //选择P1.6和P1.7用作功能引脚,IIC接口.
- MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
- GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);
- stopSent = false;
- //数组初始化为0,用0x00去填充
- memset(RXData, 0x00, NUM_OF_REC_BYTES);
- //IIC配置成主机,具体参数在i2cConfig中定义
- MAP_I2C_initMaster(EUSCI_B0_BASE, &i2cConfig);
- //配置要通信的从机地址
- MAP_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS);
- //使能IIC模块
- MAP_I2C_enableModule(EUSCI_B0_BASE);
- MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
- MAP_Interrupt_enableMaster();
- while (1)
- {
- //两次之间的延时等待
- for (ii = 0; ii < 40000; ii++);
- for (ii = 0; ii < 40000; ii++);
- memset(RXData, 0x00, NUM_OF_REC_BYTES);
- //确保上一次的传输已经完成
- while (MAP_I2C_masterIsStopSent(EUSCI_B0_BASE));
- // MAP_Interrupt_enableSleepOnIsrExit();
- //发送START和第1个字节
- MAP_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, TXData[0]);
- //发送完第1个字节后,初始化成接收模式
- rxIndex = 0;
- MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
- MAP_I2C_masterReceiveStart(EUSCI_B0_BASE);
- // MAP_PCM_gotoLPM0InterruptSafe();
- }
- }
- /*******************************************************************************
- * eUSCIB0 ISR中断服务程序.
- * 在中断中完成数据的发送和接收.
- *
- *******************************************************************************/
- 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_RECEIVE_INTERRUPT0)
- {
- //NUM_OF_REC_BYTES=10, rxIndex=8,禁用接收中断了即倒数第2个字节;
- if (rxIndex == NUM_OF_REC_BYTES - 2)
- {
- MAP_I2C_disableInterrupt(EUSCI_B0_BASE,EUSCI_B_I2C_RECEIVE_INTERRUPT0);
- MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_STOP_INTERRUPT);
- //接收到倒数第2个字节发送STOP. 最后1个接收到的字节可以在STOP中断里边读取
- MAP_I2C_masterReceiveMultiByteStop(EUSCI_B0_BASE);
- RXData[rxIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
- }
- else
- {
- RXData[rxIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
- }
- }
- else if (status & EUSCI_B_I2C_STOP_INTERRUPT)
- {
- // MAP_Interrupt_disableSleepOnIsrExit();
- MAP_I2C_disableInterrupt(EUSCI_B0_BASE,EUSCI_B_I2C_STOP_INTERRUPT);
- //读取最后1个字节
- RXData[rxIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
- rxIndex = 0;
- //对接收到的数据结果进行判断
- //抽测3-5个数据,如果对的话,就认为全对了
- if((RXData[0]==0x00)&&(RXData[1]==0x11)&&(RXData[8]==0x88)&&(RXData[9]==0x99))
- {
- //接收到的数据符合预期,红灯闪烁
- MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
- }
- else
- {
- //接收到的数据不符合预期,绿灯闪烁
- MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P2, GPIO_PIN1);
- }
- }
- }
复制代码
从机端的代码:
- /******************************************************************************
- * MSP432 I2C - EUSCI_B0 I2C主机发送1个字节到从机,然后RESTART读取10个字节
- *
- * 描述:
- * 两个MSP432通过IIC总线进行连接。主机发送数据到从机。
- * 主机发送1个字节到从机,紧跟着RESTART, 从从机读取10个字节;
- * 这个一个常规的操作,从从机设备读取多个数据,例如传感器.
- *
- * 该例程是从机的代码。
- *
- *
- *****************************************************************************/
- //库函数头文件包含
- #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
- //标准头文件
- #include <stdint.h>
- #include <stdbool.h>
- #include <string.h>
- //例程相关的定义
- #define SLAVE_ADDRESS 0x48
- #define NUM_OF_RX_BYTES 1
- #define NUM_OF_TX_BYTES 10
- //变量定义
- static volatile uint8_t RXData[NUM_OF_RX_BYTES];
- static volatile uint32_t rxIndex;
- static volatile uint32_t txIndex;
- const uint32_t TXData[NUM_OF_TX_BYTES] =
- {
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99
- };
- int main(void)
- {
- //停用看门狗
- MAP_WDT_A_holdTimer();
- rxIndex = 0;
- txIndex = 0;
- //P1.0正确接收预期数据的指示灯
- MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
- MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
- //选择P1.6和P1.7用作功能引脚,IIC接口.
- MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
- GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);
- //IIC配置成从机,写入地址
- MAP_I2C_initSlave(EUSCI_B0_BASE, SLAVE_ADDRESS, EUSCI_B_I2C_OWN_ADDRESS_OFFSET0,
- EUSCI_B_I2C_OWN_ADDRESS_ENABLE);
- //使能模块和使能中断
- MAP_I2C_enableModule(EUSCI_B0_BASE);
- MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
- MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
- MAP_I2C_enableInterrupt(EUSCI_B0_BASE,EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
- MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
- MAP_Interrupt_enableSleepOnIsrExit();
- MAP_Interrupt_enableMaster();
- //系统进入低功耗状态
- while (1)
- {
- MAP_PCM_gotoLPM0();
- }
- }
- /*******************************************************************************
- * eUSCIB0 ISR.
- * 在中断服务程序中进行数据的发送和接收
- ******************************************************************************/
- 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[rxIndex++] = MAP_I2C_slaveGetData(EUSCI_B0_BASE);
- //如果已达到最后,清零index
- if (rxIndex >= NUM_OF_RX_BYTES)
- {
- rxIndex = 0;
- txIndex = 0;
- }
- }
- //发送中断标志 TXIFG
- if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0)
- {
- //txIndex: 0,1, ... , 8,9
- MAP_I2C_slavePutData(EUSCI_B0_BASE, TXData[txIndex++]);
- //如果已达到最后,清零index
- if (txIndex >= NUM_OF_TX_BYTES)
- {
- txIndex = 0;
- //指示数据帧的发送
- MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
- }
- }
- }
复制代码
|
|