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

[复制链接]

73

主题

469

帖子

1007

积分

管理员

Rank: 9Rank: 9Rank: 9

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

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



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

主机端的代码:
  1. /******************************************************************************
  2. *  MSP432 I2C - EUSCI_B0 I2C主机发送1个字节到从机,然后RESTART读取10个字节
  3. *
  4. *  描述:
  5. *  两个MSP432通过IIC总线进行连接。主机发送数据到从机。
  6. *  主机发送1个字节到从机,紧跟着RESTART, 从从机读取10个字节;
  7. *  这个一个常规的操作,从从机设备读取多个数据,例如传感器.
  8. *
  9. *  该例程是主机端的代码。
  10. *  主机会对接收到的10个字节数据进行判断;
  11. *  如果收到的10个数据符合预期,则通过红色LED闪烁进行指示;
  12. *  如果收到的数据不符合预期,则通过绿色的LED闪烁指示。
  13. *
  14. *  注意:
  15. *  原例程中关于低功耗的代码已经移除;
  16. *
  17.   *****************************************************************************/
  18. //库函数头文件包含
  19. #include <ti/devices/msp432p4xx/driverlib/driverlib.h>

  20. //标准头文件
  21. #include <stdint.h>
  22. #include <stdbool.h>
  23. #include <string.h>

  24. //例程相关的定义
  25. #define SLAVE_ADDRESS       0x48
  26. #define NUM_OF_REC_BYTES    10

  27. //变量定义
  28. const uint8_t TXData[] = {0x04};
  29. static uint8_t RXData[NUM_OF_REC_BYTES];
  30. static volatile uint32_t rxIndex;
  31. static volatile bool stopSent;

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

  41. int main(void)
  42. {
  43.     volatile uint32_t ii;

  44.     //停用看门狗
  45.     MAP_WDT_A_holdTimer();

  46.     //P1.0正确接收预期数据的指示灯
  47.     MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
  48.     MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
  49.     //P2.1接收的数据不符合预期的指示灯
  50.     MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN1);
  51.     MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN1);

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

  55.     stopSent = false;
  56.     //数组初始化为0,用0x00去填充
  57.     memset(RXData, 0x00, NUM_OF_REC_BYTES);

  58.     //IIC配置成主机,具体参数在i2cConfig中定义
  59.     MAP_I2C_initMaster(EUSCI_B0_BASE, &i2cConfig);

  60.     //配置要通信的从机地址
  61.     MAP_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS);

  62.     //使能IIC模块
  63.     MAP_I2C_enableModule(EUSCI_B0_BASE);
  64.     MAP_Interrupt_enableInterrupt(INT_EUSCIB0);

  65.     MAP_Interrupt_enableMaster();

  66.     while (1)
  67.     {
  68.         //两次之间的延时等待
  69.         for (ii = 0; ii < 40000; ii++);
  70.         for (ii = 0; ii < 40000; ii++);

  71.         memset(RXData, 0x00, NUM_OF_REC_BYTES);

  72.         //确保上一次的传输已经完成
  73.         while (MAP_I2C_masterIsStopSent(EUSCI_B0_BASE));

  74.        // MAP_Interrupt_enableSleepOnIsrExit();

  75.         //发送START和第1个字节
  76.         MAP_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, TXData[0]);

  77.         //发送完第1个字节后,初始化成接收模式
  78.         rxIndex = 0;
  79.         MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
  80.         MAP_I2C_masterReceiveStart(EUSCI_B0_BASE);

  81. //        MAP_PCM_gotoLPM0InterruptSafe();
  82.     }
  83. }

  84. /*******************************************************************************
  85. * eUSCIB0 ISR中断服务程序.
  86. * 在中断中完成数据的发送和接收.
  87. *
  88. *******************************************************************************/
  89. void EUSCIB0_IRQHandler(void)
  90. {
  91.     uint_fas**_t status;

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

  94.     //将接收到的数据放入接收缓冲区中
  95.     if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)
  96.     {
  97.         //NUM_OF_REC_BYTES=10, rxIndex=8,禁用接收中断了即倒数第2个字节;
  98.         if (rxIndex == NUM_OF_REC_BYTES - 2)
  99.         {
  100.             MAP_I2C_disableInterrupt(EUSCI_B0_BASE,EUSCI_B_I2C_RECEIVE_INTERRUPT0);
  101.             MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_STOP_INTERRUPT);

  102.             //接收到倒数第2个字节发送STOP. 最后1个接收到的字节可以在STOP中断里边读取
  103.             MAP_I2C_masterReceiveMultiByteStop(EUSCI_B0_BASE);
  104.             RXData[rxIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
  105.         }
  106.         else
  107.         {
  108.             RXData[rxIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
  109.         }
  110.     }
  111.     else if (status & EUSCI_B_I2C_STOP_INTERRUPT)
  112.     {
  113. //        MAP_Interrupt_disableSleepOnIsrExit();
  114.         MAP_I2C_disableInterrupt(EUSCI_B0_BASE,EUSCI_B_I2C_STOP_INTERRUPT);
  115.         //读取最后1个字节
  116.         RXData[rxIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
  117.         rxIndex = 0;

  118.         //对接收到的数据结果进行判断
  119.         //抽测3-5个数据,如果对的话,就认为全对了
  120.         if((RXData[0]==0x00)&&(RXData[1]==0x11)&&(RXData[8]==0x88)&&(RXData[9]==0x99))
  121.         {
  122.            //接收到的数据符合预期,红灯闪烁
  123.            MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
  124.         }
  125.         else
  126.         {
  127.             //接收到的数据不符合预期,绿灯闪烁
  128.             MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P2, GPIO_PIN1);
  129.         }

  130.     }
  131. }
复制代码



从机端的代码:
  1. /******************************************************************************
  2. *  MSP432 I2C - EUSCI_B0 I2C主机发送1个字节到从机,然后RESTART读取10个字节
  3. *
  4. *  描述:
  5. *  两个MSP432通过IIC总线进行连接。主机发送数据到从机。
  6. *  主机发送1个字节到从机,紧跟着RESTART, 从从机读取10个字节;
  7. *  这个一个常规的操作,从从机设备读取多个数据,例如传感器.
  8. *
  9. *  该例程是从机的代码。
  10. *
  11. *
  12. *****************************************************************************/
  13. //库函数头文件包含
  14. #include <ti/devices/msp432p4xx/driverlib/driverlib.h>

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

  19. //例程相关的定义
  20. #define SLAVE_ADDRESS       0x48
  21. #define NUM_OF_RX_BYTES        1
  22. #define NUM_OF_TX_BYTES        10

  23. //变量定义
  24. static volatile uint8_t RXData[NUM_OF_RX_BYTES];
  25. static volatile uint32_t rxIndex;
  26. static volatile uint32_t txIndex;
  27. const uint32_t TXData[NUM_OF_TX_BYTES] =
  28. {
  29.      0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99
  30. };

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

  35.     rxIndex = 0;
  36.     txIndex = 0;

  37.     //P1.0正确接收预期数据的指示灯
  38.     MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
  39.     MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);

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

  43.     //IIC配置成从机,写入地址
  44.     MAP_I2C_initSlave(EUSCI_B0_BASE, SLAVE_ADDRESS, EUSCI_B_I2C_OWN_ADDRESS_OFFSET0,
  45.             EUSCI_B_I2C_OWN_ADDRESS_ENABLE);

  46.     //使能模块和使能中断
  47.     MAP_I2C_enableModule(EUSCI_B0_BASE);
  48.     MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
  49.     MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
  50.     MAP_I2C_enableInterrupt(EUSCI_B0_BASE,EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

  51.     MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
  52.     MAP_Interrupt_enableSleepOnIsrExit();
  53.     MAP_Interrupt_enableMaster();

  54.     //系统进入低功耗状态
  55.     while (1)
  56.     {
  57.         MAP_PCM_gotoLPM0();
  58.     }
  59. }

  60. /*******************************************************************************
  61. * eUSCIB0 ISR.
  62. * 在中断服务程序中进行数据的发送和接收
  63. ******************************************************************************/
  64. void EUSCIB0_IRQHandler(void)
  65. {
  66.     uint_fas**_t status;

  67.     status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B0_BASE);
  68.     MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, status);

  69.     //接收中断标志 RXIFG
  70.     if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)
  71.     {
  72.         RXData[rxIndex++] = MAP_I2C_slaveGetData(EUSCI_B0_BASE);

  73.         //如果已达到最后,清零index
  74.         if (rxIndex >= NUM_OF_RX_BYTES)
  75.         {
  76.             rxIndex = 0;
  77.             txIndex = 0;
  78. }
  79.     }

  80.     //发送中断标志 TXIFG
  81.     if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0)
  82.     {
  83.         //txIndex: 0,1, ... , 8,9
  84.         MAP_I2C_slavePutData(EUSCI_B0_BASE, TXData[txIndex++]);

  85.         //如果已达到最后,清零index
  86.         if (txIndex >= NUM_OF_TX_BYTES)
  87.         {
  88.             txIndex = 0;
  89. //指示数据帧的发送
  90.             MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
  91.         }
  92.     }
  93. }
复制代码


150

主题

446

帖子

1968

积分

审核员

Rank: 9Rank: 9Rank: 9

积分
1968
沙发
发表于 2019-11-27 10:19:29   只看该作者
谢谢分享
快速回复 返回顶部 返回列表