[活动] C++与C语言混合编程案例
1020 查看
4 回复
 楼主 | 发布于 2020-09-21 | 只看楼主
分享到:
虽然在小编的日常工作中,用到最多的语言为C,但有时还是会用到C的,知识总是用时方恨少, C/ C混合编程需要注意些什么以及如何优雅的实现呢,小编原来也是很抓瞎的,所以这次小编将以evkmimxrt685_i2c_read_accel_value_transfer工程(MCUXpresso版本)从C语言‘搬成’C语言为例,介绍C/ C混合编程实现的步骤与要点。
1. 新建C工程
请参考MCUXpresso_IDE_User_Guide中的5. Creating New Projects using installed SDK Part
Support章节新建一个基于MIMXRT685-EVK开发板的C工程,如下所示。
  1. /**
  2. * @file    MIMXRT685S_Project.cpp
  3. * @brief   Application entry point.
  4. */
  5. #include <stdio.h>
  6. #include "board.h"
  7. #include "peripherals.h"
  8. #include "pin_mux.h"
  9. #include "clock_config.h"
  10. #include "MIMXRT685S_cm33.h"
  11. #include "fsl_debug_console.h"
  12. /* TODO: insert other include files here. */

  13. /* TODO: insert other definitions and declarations here. */

  14. /*
  15. 1. @brief   Application entry point.
  16. */
  17. int main(void) {

  18.           /* Init board hardware. */
  19.     BOARD_InitBootPins();
  20.     BOARD_InitBootClocks();
  21.     BOARD_InitBootPeripherals();
  22.           /* Init FSL debug console. */
  23.     BOARD_InitDebugConsole();

  24.     PRINTF("Hello World\n");

  25.     /* Force the counter to be placed into memory. */
  26.     volatile static int i = 0 ;
  27.     /* Enter an infinite loop, just incrementing a counter. */
  28.     while(1) {
  29.         i++ ;
  30.         /* 'Dummy' NOP to allow source level single stepping of
  31.             tight while() loop */
  32.         __asm volatile ("nop");
  33.     }
  34.     return 0 ;
  35. }
复制代码
2. 修改evkmimxrt685_i2c_read_accel_value_transfer工程中的i2c_read_accel_value_transfer.c
删除int main() 函数和暂时用不到的宏定义(如下所示)
  1. #define ACCEL_STATUS 0x00U
  2. #define ACCEL_XYZ_DATA_CFG 0x0EU
  3. #define ACCEL_CTRL_REG1 0x2AU

  4. #define ACCEL_READ_TIMES 10U
复制代码
3. 创建i2c_read_accel_value_transfer.h头文件
  1. #ifndef _I2C_READ_ACCEL_VALUE_TRANSFER_
  2. #define _I2C_READ_ACCEL_VALUE_TRANSFER_


  3. #if defined(__cplusplus)
  4. extern "C" {
  5. #endif /* __cplusplus */





  6. #include "fsl_i2c.h"
  7. #include "board.h"
  8. #include "fsl_debug_console.h"

  9. extern bool I2C_ReadAccelWhoAmI(void);
  10. extern bool I2C_WriteAccelReg(I2C_Type *base, uint8_t device_addr, uint8_t reg_addr, uint8_t value);
  11. extern bool I2C_ReadAccelRegs(I2C_Type *base, uint8_t device_addr, uint8_t reg_addr, uint8_t *rxBuff, uint32_t rxSize);
  12. extern void i2c_master_callback(I2C_Type *base, i2c_master_handle_t *handle, status_t status, void *userData);

  13. extern uint8_t g_accel_addr_found;
  14. extern i2c_master_handle_t g_m_handle;

  15. #if defined(__cplusplus)
  16. }
  17. #endif

  18. #endif
复制代码
其中__cplusplus为预处理器名字,用于C文档的头文件中,而extern “C”是由C++提供的一个连接交换指定符号,用于告诉C++这段代码是C函数。extern “C”后面的函数不使用的C的名字修饰,而是用C,这是实现C++代码调用C代码的关键。
4. 
修改新建工程中的main()函数
这是最后一步移植工作,通过调用i2c_read_accel_value_transfer.c中定义的函数,实现原先evkmimxrt685_i2c_read_accel_value_transfer工程的功能,具体代码如下。
  1. /**
  2. * @file    MIMXRT685S_C_Plus_Demo.cpp
  3. * @brief   Application entry point.
  4. */
  5. #include <stdio.h>
  6. #include "board.h"
  7. #include "peripherals.h"
  8. #include "pin_mux.h"
  9. #include "clock_config.h"
  10. #include "MIMXRT685S_cm33.h"
  11. #include "fsl_debug_console.h"
  12. #include "i2c_read_accel_value_transfer.h"
  13. /* TODO: insert other include files here. */

  14. #define ACCEL_STATUS 0x00U
  15. #define ACCEL_XYZ_DATA_CFG 0x0EU
  16. #define ACCEL_CTRL_REG1 0x2AU

  17. #define ACCEL_READ_TIMES 10U
  18. /* TODO: insert other definitions and declarations here. */



  19. /*
  20. * @brief   Application entry point.
  21. */
  22. int main(void)
  23. {

  24.     bool isThereAccel = false;
  25.     /* Use 16 MHz clock for the FLEXCOMM2 */
  26.     CLOCK_AttachClk(kSFRO_to_FLEXCOMM2);

  27.           /* Init board hardware. */
  28.     BOARD_InitBootPins();
  29.     BOARD_InitBootClocks();
  30.     BOARD_InitBootPeripherals();
  31.           /* Init FSL debug console. */
  32.     BOARD_InitDebugConsole();


  33.     PRINTF("\r\nC_Plus Mix C Demo-- Read Accelerometer Value\r\n");

  34.     I2C_MasterTransferCreateHandle(BOARD_ACCEL_I2C_BASEADDR, &g_m_handle, i2c_master_callback, NULL);
  35.     isThereAccel = I2C_ReadAccelWhoAmI();
  36.     /*  read the accel xyz value if there is accel device on board */
  37.     if (true == isThereAccel)
  38.         {
  39.             uint8_t databyte  = 0;
  40.             uint8_t write_reg = 0;
  41.             uint8_t readBuff[7];
  42.             int16_t x, y, z;
  43.             uint8_t status0_value = 0;
  44.             uint32_t i            = 0U;

  45.             /*  please refer to the "example FXOS8700CQ Driver Code" in FXOS8700 datasheet. */
  46.             /*  write 0000 0000 = 0x00 to accelerometer control register 1 */
  47.             /*  standby */
  48.             /*  [7-1] = 0000 000 */
  49.             /*  [0]: active=0 */
  50.             write_reg = ACCEL_CTRL_REG1;
  51.             databyte  = 0;
  52.             I2C_WriteAccelReg(BOARD_ACCEL_I2C_BASEADDR, g_accel_addr_found, write_reg, databyte);

  53.             /*  write 0000 0001= 0x01 to XYZ_DATA_CFG register */
  54.             /*  [7]: reserved */
  55.             /*  [6]: reserved */
  56.             /*  [5]: reserved */
  57.             /*  [4]: hpf_out=0 */
  58.             /*  [3]: reserved */
  59.             /*  [2]: reserved */
  60.             /*  [1-0]: fs=01 for accelerometer range of +/-4g range with 0.488mg/LSB */
  61.             /*  databyte = 0x01; */
  62.             write_reg = ACCEL_XYZ_DATA_CFG;
  63.             databyte  = 0x01;
  64.             I2C_WriteAccelReg(BOARD_ACCEL_I2C_BASEADDR, g_accel_addr_found, write_reg, databyte);

  65.             /*  write 0000 1101 = 0x0D to accelerometer control register 1 */
  66.             /*  [7-6]: aslp_rate=00 */
  67.             /*  [5-3]: dr=001 for 200Hz data rate (when in hybrid mode) */
  68.             /*  [2]: lnoise=1 for low noise mode */
  69.             /*  [1]: f_read=0 for normal 16 bit reads */
  70.             /*  [0]: active=1 to take the part out of standby and enable sampling */
  71.             /*   databyte = 0x0D; */
  72.             write_reg = ACCEL_CTRL_REG1;
  73.             databyte  = 0x0d;
  74.             I2C_WriteAccelReg(BOARD_ACCEL_I2C_BASEADDR, g_accel_addr_found, write_reg, databyte);
  75.             PRINTF("The accel values:\r\n");
  76.             for (i = 0; i < ACCEL_READ_TIMES; i++)
  77.             {
  78.                 status0_value = 0;
  79.                 /*  wait for new data are ready. */
  80.                 while (status0_value != 0xff)
  81.                 {
  82.                     I2C_ReadAccelRegs(BOARD_ACCEL_I2C_BASEADDR, g_accel_addr_found, ACCEL_STATUS, &status0_value, 1);
  83.                 }

  84.                 /*  Multiple-byte Read from STATUS (0x00) register */
  85.                 I2C_ReadAccelRegs(BOARD_ACCEL_I2C_BASEADDR, g_accel_addr_found, ACCEL_STATUS, readBuff, 7);

  86.                 status0_value = readBuff[0];
  87.                 x             = ((int16_t)(((readBuff[1] * 256U) | readBuff[2]))) / 4U;
  88.                 y             = ((int16_t)(((readBuff[3] * 256U) | readBuff[4]))) / 4U;
  89.                 z             = ((int16_t)(((readBuff[5] * 256U) | readBuff[6]))) / 4U;

  90.                 PRINTF("status_reg = 0x%x , x = %5d , y = %5d , z = %5d \r\n", status0_value, x, y, z);
  91.             }
  92.         }
  93.     PRINTF("\r\nEnd of I2C example .\r\n");
  94.     while (1)
  95.     {
  96.     }

  97. }
复制代码

测试结果

测试结果

本帖有更多资源,需 登录 才可以下载,没有帐号?立即 注册

(0 ) (0 )
回复 举报

回复于 2020-09-25 沙发

(0 )
评论 (0) 举报

回复于 2020-10-09 2#

学习学习
(0 )
评论 (0) 举报

回复于 2020-10-31 3#

6666
(0 )
评论 (0) 举报

回复于 2021-08-30 4#

正好好好学习一下
(0 )
评论 (0) 举报
  • 发表回复
    0/3000





    举报

    请选择举报类别

    • 广告垃圾
    • 违规内容
    • 恶意灌水
    • 重复发帖

    全部板块

    返回顶部