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

[复制链接]

73

主题

469

帖子

1007

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1007
楼主
查看: 3820回复: 1 发表于 2019-11-25 23:20:25   只看该作者


SDK例程解析,源码与SDK有所改动,请参考帖子中的源码进行实验。

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





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

主机端的代码:


  1. /******************************************************************************
  2. *  MSP432 I2C - EUSCI_B0 I2C Master TX  bytes to MSP432 Slave - Timeout
  3. *
  4. *  描述:
  5. *  两个MSP432通过IIC总线进行连接。主机发送数据到从机。
  6. *
  7. *  该例程是主机端的代码。
  8. *  主机发送1个字节数据,紧跟着RESTART, 读取多个数据;
  9. *  P1.0接红色LED,P2.1接绿色LED,P2.2接蓝色LED;
  10. *  当主机接收到正常的数据时,点亮红色LED;接收到错误的数据时,点亮绿色LED;
  11. *  主机检测到SLC拉低超时时,蓝色LED灯闪烁;
  12. *
  13. *  注意:主机的代码只发送1次地址,也就是和从机之发起1次通信;
  14. *  在实验时,可将从机接调试器,通过设置断点来构造实验条件,(在CCS中复位从机不会断开连接)
  15. *  先让从机全速运行,再手动复位主机;
  16. *
  17. *
  18.   *****************************************************************************/
  19. //库函数头文件包含
  20. #include <ti/devices/msp432p4xx/driverlib/driverlib.h>

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

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

  28. //变量
  29. const uint8_t TXData[] = {0x04};
  30. static uint8_t RXData[NUM_OF_REC_BYTES];
  31. static volatile uint32_t rxIndex;
  32. static volatile bool stopSent;
  33. unsigned int i=0, timeout=0;

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

  43. int main(void)
  44. {
  45.     volatile uint32_t ii;

  46.     //关闭看门狗
  47.     MAP_WDT_A_holdTimer();

  48.     //P1.0接有LED,设置为输出.初始状态低电平 ,LED熄灭
  49.     MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
  50.     MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);

  51.     //P2.1指示灯
  52.     MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN1);
  53.     MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN1);

  54.     //P2.2指示灯
  55.     MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN2);
  56.     MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN2);

  57.     //选择P1.6和P1.7用作功能引脚,IIC接口(UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL).
  58.     MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
  59.             GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);

  60.     stopSent = false;
  61.     memset(RXData, 0x00, NUM_OF_REC_BYTES);

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

  64.     //设置时钟线拉低超时时间,如果从机拉低SCL>28ms,会触发中断
  65.     MAP_I2C_setTimeout(EUSCI_B0_BASE, EUSCI_B_I2C_TIMEOUT_28_MS);

  66.     //设置通信的从机地址
  67.     MAP_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS);

  68.     //使能IIC模块
  69.     MAP_I2C_enableModule(EUSCI_B0_BASE);

  70.     //使能接收中断和SCL拉低超时中断
  71.     MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
  72.     MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
  73.     MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT);

  74.     //判断总线上最后一次传输是否完成
  75.     while (MAP_I2C_masterIsStopSent(EUSCI_B0_BASE));

  76. //    MAP_Interrupt_enableSleepOnIsrExit();

  77.     //开启全局中断
  78.     MAP_Interrupt_enableMaster();

  79.     //发送START和第一个字节
  80.     MAP_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, TXData[0]);

  81.     //设置为接收
  82.     rxIndex = 0;
  83.     MAP_I2C_masterReceiveStart(EUSCI_B0_BASE);

  84.     while(1)
  85.     {
  86. //        MAP_PCM_gotoLPM0InterruptSafe();

  87.         //如果发生超时,P2.2 蓝色LED闪烁
  88.         while(timeout)
  89.         {
  90.             MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P2, GPIO_PIN2);
  91.             for (ii = 0; ii < 40000; ii++);
  92. //            __delay_cycles(300000);
  93.         }
  94.     }
  95. }

  96. /*******************************************************************************
  97. * eUSCIB0 ISR.
  98. * RESTART和接收操作在中断服务程序中完成.
  99. *******************************************************************************/
  100. void EUSCIB0_IRQHandler(void)
  101. {
  102.     uint_fas**_t status;

  103.     status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B0_BASE);
  104.     MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, status);

  105.     //判断SCL超时标志
  106.     if (status & EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT)
  107.     {
  108.         timeout++;
  109.         //三色LED,熄灭绿色LED. 只闪烁蓝色LED
  110.         MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN1);
  111.     }

  112.     //将接收到的数据放入接收缓冲区中
  113.     if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)
  114.     {
  115.         //NUM_OF_REC_BYTES=10, rxIndex=8,禁用接收中断了即倒数第2个字节;
  116.         if (rxIndex == NUM_OF_REC_BYTES - 2)
  117.         {
  118.             MAP_I2C_disableInterrupt(EUSCI_B0_BASE,EUSCI_B_I2C_RECEIVE_INTERRUPT0);
  119.             MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_STOP_INTERRUPT);

  120.             //接收到倒数第2个字节发送STOP. 最后1个接收到的字节可以在STOP中断里边读取
  121.             MAP_I2C_masterReceiveMultiByteStop(EUSCI_B0_BASE);
  122.             RXData[rxIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
  123.         }
  124.         else
  125.         {
  126.             RXData[rxIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
  127.         }
  128.     }
  129.     else if (status & EUSCI_B_I2C_STOP_INTERRUPT)
  130.     {
  131. //        MAP_Interrupt_disableSleepOnIsrExit();
  132.         MAP_I2C_disableInterrupt(EUSCI_B0_BASE,EUSCI_B_I2C_STOP_INTERRUPT);
  133.         //读取最后1个字节
  134.         RXData[rxIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
  135.         rxIndex = 0;

  136.         //对接收到的数据结果进行判断
  137.         //抽测3-5个数据,如果对的话,就认为全对了
  138.         if((RXData[0]==0x00)&&(RXData[1]==0x11)&&(RXData[8]==0x88)&&(RXData[9]==0x99))
  139.         {
  140.            //接收到的数据符合预期,红灯点亮
  141.            MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
  142.         }
  143.         else
  144.         {
  145.             //接收到的数据不符合预期,绿灯点亮
  146.             MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P2, GPIO_PIN1);
  147.         }

  148.     }
  149. }
复制代码




从极端的代码:


  1. /******************************************************************************
  2. *  MSP432 I2C - EUSCI_B0 I2C Master TX  bytes to MSP432 Slave - Timeout
  3. *
  4. *  描述:
  5. *  两个MSP432通过IIC总线进行连接。主机发送数据到从机。
  6. *
  7. *  该例程是主机端的代码。
  8. *  主机发送1个字节数据,紧跟着RESTART, 读取多个数据;
  9. *  P1.0接红色LED,P2.1接绿色LED,P2.2接蓝色LED;
  10. *  当主机接收到正常的数据时,点亮红色LED;接收到错误的数据时,点亮绿色LED;
  11. *  主机检测到SLC拉低超时时,蓝色LED灯闪烁;
  12. *
  13. *  注意:主机的代码只发送1次地址,也就是和从机之发起1次通信;
  14. *  在实验时,可将从机接调试器,通过设置断点来构造实验条件,(在CCS中复位从机不会断开连接)
  15. *  先让从机全速运行,再手动复位主机;
  16. *
  17. *
  18.   *****************************************************************************/
  19. //库函数头文件包含
  20. #include <ti/devices/msp432p4xx/driverlib/driverlib.h>

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

  25. //例程相关的定义
  26. #define SLAVE_ADDRESS       0x48
  27. #define NUM_OF_RX_BYTES        1
  28. #define NUM_OF_TX_BYTES        10

  29. //变量定义
  30. static volatile uint8_t RXData[NUM_OF_RX_BYTES];
  31. static volatile uint32_t rxIndex;
  32. static volatile uint32_t txIndex;
  33. const uint32_t TXData[NUM_OF_TX_BYTES] =
  34. {
  35.      0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99
  36. };

  37. int main(void)
  38. {
  39.     //停用看门狗
  40.     MAP_WDT_A_holdTimer();

  41.     rxIndex = 0;
  42.     txIndex = 0;

  43.     //P1.0用作指示灯
  44.     MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
  45.     MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);

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

  49.     //IIC配置成从机
  50.     MAP_I2C_initSlave(EUSCI_B0_BASE, SLAVE_ADDRESS, EUSCI_B_I2C_OWN_ADDRESS_OFFSET0,
  51.             EUSCI_B_I2C_OWN_ADDRESS_ENABLE);

  52.     //使能模块和使能中断
  53.     MAP_I2C_enableModule(EUSCI_B0_BASE);
  54.     MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
  55.     MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
  56.     MAP_I2C_enableInterrupt(EUSCI_B0_BASE,EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

  57.     MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
  58.     MAP_Interrupt_enableSleepOnIsrExit();

  59.     MAP_Interrupt_enableMaster();

  60.     //系统进入低功耗状态
  61.     while (1)
  62.     {
  63.         MAP_PCM_gotoLPM0();
  64.     }
  65. }

  66. /*******************************************************************************
  67. * eUSCIB0 ISR.
  68. * 在中断服务程序中进行数据的发送和接收
  69. ******************************************************************************/
  70. void EUSCIB0_IRQHandler(void)
  71. {
  72.     uint_fas**_t status;

  73.     status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B0_BASE);
  74.     MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, status);

  75.     //可以在两个不同的场景构建SCL拉低超时
  76.     //从机在接收的时候,如果UCBxRXBUF数据未读取,SCL拉低
  77.     //从机在发送的时候,SCL拉低,等待往TXBUF写入有效数据

  78.     //接收中断标志 RXIFG
  79.     if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)
  80.     {
  81.         //此处设置断点,不读取收到的数据
  82.         RXData[rxIndex++] = MAP_I2C_slaveGetData(EUSCI_B0_BASE);

  83.         //如果已达到最后,清零index
  84.         if (rxIndex >= NUM_OF_RX_BYTES)
  85.         {
  86.             rxIndex = 0;
  87.             txIndex = 0;
  88.         }
  89.     }
  90.     //发送中断标志 TXIFG
  91.     if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0)
  92.     {
  93.         //此处设置断点,不往TXBUF里写数据

  94.         //txIndex: 0,1, ... , 8,9
  95.         MAP_I2C_slavePutData(EUSCI_B0_BASE, TXData[txIndex++]);

  96.         //如果已达到最后,清零index
  97.         if (txIndex >= NUM_OF_TX_BYTES)
  98.         {
  99.             txIndex = 0;

  100.             //指示数据帧的发送
  101.             MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
  102.         }
  103.     }
  104. }
复制代码


150

主题

446

帖子

1968

积分

审核员

Rank: 9Rank: 9Rank: 9

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