SDK例程解析-IIC模块-例程04

[复制链接]

73

主题

469

帖子

1005

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1005
楼主
查看: 3416回复: 3 发表于 2019-11-25 23:24:08   只看该作者
SDK例程解析,源码与SDK有所改动,请参考帖子中的源码进行实验。

例程描述和实验现象,请参考下边的图片:




更多的细节可参考以下代码:

主机端的代码:

  1. /*******************************************************************************
  2. *  MSP432 I2C - EUSCI_B0_BASE I2C Master TX multiple bytes to multiple MSP432 Slaves
  3. *
  4. *  描述:
  5. *  两个MSP432通过IIC总线进行连接。
  6. *  同一个EUSCI模块配置成多个从机构造多从机的环境,主机发送多个数据到不同的从机。
  7. *
  8. *  该例程是主机端的代码。
  9. *  主机通过修改I2C_setSlaveAddress,将数据发送到不同的从机地址。
  10. *  往两个从机分别发送4个不同的字节;
  11. *
  12. ******************************************************************************/
  13. //库函数头文件包含
  14. #include <ti/devices/msp432p4xx/driverlib/driverlib.h>

  15. //标准头文件
  16. #include <stdint.h>
  17. #include <stdbool.h>

  18. //例程相关的定义
  19. #define SLAVE_ADDRESS_1 0x48
  20. #define SLAVE_ADDRESS_2 0x49

  21. //变量定义
  22. static uint8_t TXData = 0;
  23. static uint8_t TXByteCtr;
  24. static volatile bool sendStopCondition;
  25. static volatile bool sendToSlaveAddress2;

  26. //主机的IIC参数配置,速率选择(100KBPS, 400KBPS)
  27. const eUSCI_I2C_MasterConfig i2cConfig =
  28. {
  29.      EUSCI_B_I2C_CLOCKSOURCE_SMCLK,          // 选择时钟源SMCLK
  30.      3000000,                                // SMCLK的频率是3MHz (默认)
  31.      EUSCI_B_I2C_SET_DATA_RATE_100KBPS,      // 设置I2C时钟速率为100khz
  32.      0,                                      // 不使用字节计数阈值
  33.      EUSCI_B_I2C_NO_AUTO_STOP                // 不自动产生STOP
  34. };

  35. int main(void)
  36. {
  37.     //禁用看门狗
  38.     MAP_WDT_A_holdTimer();

  39.     //选择P1.6和P1.7为功能引脚(UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL).
  40.     MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
  41.             GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);

  42.     sendStopCondition = false;
  43.     sendToSlaveAddress2 = false;

  44.     //配置I2C为主机,采用SMCLK,工作在100khz,无自动停止位
  45.     MAP_I2C_initMaster(EUSCI_B0_BASE, &i2cConfig);

  46.     //设置要通信的第一个从机地址
  47.     MAP_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS_1);

  48.     //设置主机位发送模式
  49.     MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);

  50.     //启用I2C模块
  51.     MAP_I2C_enableModule(EUSCI_B0_BASE);

  52.     //清除中断标志位
  53.     MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE,
  54.             EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);

  55.     //使能发送中断和无应答中断
  56.     MAP_I2C_enableInterrupt(EUSCI_B0_BASE,
  57.             EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);

  58.     MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
  59.    
  60.     while (1)
  61.     {

  62.         //加载字节计数器
  63.         TXByteCtr = 4;

  64.         //确保最后一个字节已经发送完成
  65.         while (MAP_I2C_masterIsStopSent(EUSCI_B0_BASE) == EUSCI_B_I2C_SENDING_STOP);

  66.         //设置从机地址,然后发送START
  67.         if(sendToSlaveAddress2)
  68.         {
  69.             MAP_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS_2);
  70.         }
  71.         else
  72.         {
  73.             MAP_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS_1);
  74.         }

  75.         MAP_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, TXData++);
  76.         TXByteCtr--;

  77.         while(sendStopCondition == false)
  78.         {
  79.             //发送过程中进入低功耗模式
  80.             MAP_Interrupt_enableSleepOnIsrExit();
  81.             MAP_PCM_gotoLPM0InterruptSafe();
  82.         }

  83.         sendStopCondition = false;
  84.     }
  85. }

  86. /*******************************************************************************
  87. * USCIAB0TX_ISR用于发送数据, 字节数定义在TXByteCtr中。
  88. * TXData表示下一个要发送的数据。
  89. *******************************************************************************/
  90. void EUSCIB0_IRQHandler(void)
  91. {
  92.     uint_fas**_t status;

  93.     status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B0_BASE);
  94.     MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, status);

  95.     if (status & EUSCI_B_I2C_NAK_INTERRUPT)
  96.     {
  97.         MAP_I2C_masterSendStart(EUSCI_B0_BASE);
  98.         return;
  99.     }

  100.     //判断计数,如果不为零,发送下一个数据,同时计数减1
  101.     if (TXByteCtr)
  102.     {
  103.         //TXByteCtr: (4),3,2,1
  104.         MAP_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, TXData++);
  105.         TXByteCtr--;
  106.     }
  107.     else
  108.     {
  109.         //发送停止信号STOP
  110.         MAP_I2C_masterSendMultiByteStop(EUSCI_B0_BASE);
  111.         //用于退出低功耗模式
  112.         sendStopCondition = true;
  113.         //切换要设置的从机地址
  114.         sendToSlaveAddress2 = !sendToSlaveAddress2;
  115.         MAP_Interrupt_disableSleepOnIsrExit();
  116.     }

  117. }
复制代码




从极端的代码:
  1. /******************************************************************************
  2. *  MSP432 I2C - EUSCI_B0_BASE I2C Master TX multiple bytes to multiple MSP432 Slaves
  3. *
  4. *  描述:
  5. *  两个MSP432通过IIC总线进行连接。
  6. *  同一个EUSCI模块配置成多个从机构造多从机的环境,主机发送多个数据到从机。
  7. *
  8. *  该例程是从机端的代码。
  9. *  从机设备使用EUSCI0模块,演示了两个独立的从机地址;
  10. *  在IIC的中断服务程序中,不同的接收地址具有不同的接收服务程序。因此将接收的数据放在不同的接收区。
  11. *
  12. *  ACLK = n/a, MCLK = HSMCLK = SMCLK = BRCLK = default DCO = ~3.0MHz
  13. *
  14. *
  15.   *****************************************************************************/
  16. //库函数头文件包含
  17. #include <ti/devices/msp432p4xx/driverlib/driverlib.h>

  18. //标准头文件
  19. #include <stdint.h>
  20. #include <stdbool.h>

  21. //例程相关的定义
  22. #define SLAVE_ADDRESS_1     0x48
  23. #define SLAVE_ADDRESS_2     0x49
  24. #define NUM_OF_RX_BYTES     4

  25. //变量定义
  26. static volatile uint8_t RXData_0[NUM_OF_RX_BYTES];
  27. static volatile uint32_t rxIndex_0;
  28. static volatile uint8_t RXData_1[NUM_OF_RX_BYTES];
  29. static volatile uint32_t rxIndex_1;

  30. int main(void)
  31. {
  32.     //停用看门狗
  33.     MAP_WDT_A_holdTimer();

  34.     rxIndex_0 = 0;
  35.     rxIndex_1 = 0;

  36.     //选择P1.6和P1.7用作功能引脚,IIC接口.
  37.     MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
  38.         GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);

  39.     //配置从机地址1(0x48)
  40.     MAP_I2C_initSlave(EUSCI_B0_BASE, SLAVE_ADDRESS_1,
  41.             EUSCI_B_I2C_OWN_ADDRESS_OFFSET0,
  42.             EUSCI_B_I2C_OWN_ADDRESS_ENABLE);

  43.     //配置从机地址2(0x49)
  44.     MAP_I2C_initSlave(EUSCI_B0_BASE, SLAVE_ADDRESS_2,
  45.             EUSCI_B_I2C_OWN_ADDRESS_OFFSET1,
  46.             EUSCI_B_I2C_OWN_ADDRESS_ENABLE);

  47.     //设置处于接收模式
  48.     MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);

  49.     //使能模块和使能中断
  50.     MAP_I2C_enableModule(EUSCI_B0_BASE);
  51.     MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE,EUSCI_B_I2C_RECEIVE_INTERRUPT0 | EUSCI_B_I2C_RECEIVE_INTERRUPT1);
  52.     MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0 | EUSCI_B_I2C_RECEIVE_INTERRUPT1);

  53.     MAP_Interrupt_enableSleepOnIsrExit();
  54.     MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
  55.     MAP_Interrupt_enableMaster();

  56.     //进入低功耗模式
  57.     while (1)
  58.     {
  59.         MAP_PCM_gotoLPM0();
  60.     }
  61. }

  62. /******************************************************************************
  63. * eUSCI_B0 中断服务函数
  64. *
  65. * 在中断中处理接收到数据
  66. *
  67. ******************************************************************************/
  68. void EUSCIB0_IRQHandler(void)
  69. {
  70.     uint_fas**_t status;

  71.     status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B0_BASE);
  72.     MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, status);

  73.     //从机地址的 RXIFG
  74.     if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)
  75.     {
  76.         RXData_0[rxIndex_0++] = MAP_I2C_slaveGetData(EUSCI_B0_BASE);

  77.         //数组下标判断
  78.         if (rxIndex_0 == NUM_OF_RX_BYTES)
  79.         {
  80.             rxIndex_0 = 0;
  81.         }
  82.     }

  83.     //另一个从机地址的 RXIFG
  84.     if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT1)
  85.     {
  86.         RXData_1[rxIndex_1++] = MAP_I2C_slaveGetData(EUSCI_B0_BASE);

  87.         //数组下标判断
  88.         if (rxIndex_1 == NUM_OF_RX_BYTES)
  89.         {
  90.             //可在此处设置断点
  91.             rxIndex_1 = 0;
  92.         }
  93.     }
  94. }
复制代码


41

主题

160

帖子

332

积分

二氧化硅

Rank: 2

积分
332
沙发
发表于 2019-11-27 15:50:25   只看该作者
谢谢分享

150

主题

445

帖子

1904

积分

审核员

Rank: 9Rank: 9Rank: 9

积分
1904
板凳
发表于 2019-11-28 08:30:35   只看该作者
谢谢分享

45

主题

179

帖子

455

积分

二氧化硅

Rank: 2

积分
455
4#
发表于 2020-2-28 08:55:47   只看该作者
谢谢分享
快速回复 返回顶部 返回列表