在线时间2107 小时
UID3253523
注册时间2016-3-21
NXP金币2010
该用户从未签到
超级版主
- 积分
- 20159
- 最后登录
- 2024-5-7
|
本帖最后由 小恩GG 于 2020-5-9 16:55 编辑
虽然在小编的日常工作中,用到最多的语言为C,但有时还是会用到C的,知识总是用时方恨少, C/ C混合编程需要注意些什么以及如何优雅的实现呢,小编原来也是很抓瞎的,所以这次小编将以evkmimxrt685_i2c_read_accel_value_transfer工程(MCUXpresso版本)从C语言‘搬成’C语言为例,介绍C/ C混合编程实现的步骤与要点。 1. 新建C工程 - /**
- * @file MIMXRT685S_Project.cpp
- * @brief Application entry point.
- */
- #include <stdio.h>
- #include "board.h"
- #include "peripherals.h"
- #include "pin_mux.h"
- #include "clock_config.h"
- #include "MIMXRT685S_cm33.h"
- #include "fsl_debug_console.h"
- /* TODO: insert other include files here. */
- /* TODO: insert other definitions and declarations here. */
- /*
- 1. @brief Application entry point.
- */
- int main(void) {
- /* Init board hardware. */
- BOARD_InitBootPins();
- BOARD_InitBootClocks();
- BOARD_InitBootPeripherals();
- /* Init FSL debug console. */
- BOARD_InitDebugConsole();
- PRINTF("Hello World\n");
- /* Force the counter to be placed into memory. */
- volatile static int i = 0 ;
- /* Enter an infinite loop, just incrementing a counter. */
- while(1) {
- i++ ;
- /* 'Dummy' NOP to allow source level single stepping of
- tight while() loop */
- __asm volatile ("nop");
- }
- return 0 ;
- }
复制代码 2. 修改evkmimxrt685_i2c_read_accel_value_transfer工程中的i2c_read_accel_value_transfer.c
删除int main() 函数和暂时用不到的宏定义(如下所示)
- #define ACCEL_STATUS 0x00U
- #define ACCEL_XYZ_DATA_CFG 0x0EU
- #define ACCEL_CTRL_REG1 0x2AU
- #define ACCEL_READ_TIMES 10U
复制代码 3. 创建i2c_read_accel_value_transfer.h头文件
- #ifndef _I2C_READ_ACCEL_VALUE_TRANSFER_
- #define _I2C_READ_ACCEL_VALUE_TRANSFER_
- #if defined(__cplusplus)
- extern "C" {
- #endif /* __cplusplus */
- #include "fsl_i2c.h"
- #include "board.h"
- #include "fsl_debug_console.h"
- extern bool I2C_ReadAccelWhoAmI(void);
- extern bool I2C_WriteAccelReg(I2C_Type *base, uint8_t device_addr, uint8_t reg_addr, uint8_t value);
- extern bool I2C_ReadAccelRegs(I2C_Type *base, uint8_t device_addr, uint8_t reg_addr, uint8_t *rxBuff, uint32_t rxSize);
- extern void i2c_master_callback(I2C_Type *base, i2c_master_handle_t *handle, status_t status, void *userData);
- extern uint8_t g_accel_addr_found;
- extern i2c_master_handle_t g_m_handle;
- #if defined(__cplusplus)
- }
- #endif
- #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工程的功能,具体代码如下。- /**
- * @file MIMXRT685S_C_Plus_Demo.cpp
- * @brief Application entry point.
- */
- #include <stdio.h>
- #include "board.h"
- #include "peripherals.h"
- #include "pin_mux.h"
- #include "clock_config.h"
- #include "MIMXRT685S_cm33.h"
- #include "fsl_debug_console.h"
- #include "i2c_read_accel_value_transfer.h"
- /* TODO: insert other include files here. */
- #define ACCEL_STATUS 0x00U
- #define ACCEL_XYZ_DATA_CFG 0x0EU
- #define ACCEL_CTRL_REG1 0x2AU
- #define ACCEL_READ_TIMES 10U
- /* TODO: insert other definitions and declarations here. */
- /*
- * @brief Application entry point.
- */
- int main(void)
- {
- bool isThereAccel = false;
- /* Use 16 MHz clock for the FLEXCOMM2 */
- CLOCK_AttachClk(kSFRO_to_FLEXCOMM2);
- /* Init board hardware. */
- BOARD_InitBootPins();
- BOARD_InitBootClocks();
- BOARD_InitBootPeripherals();
- /* Init FSL debug console. */
- BOARD_InitDebugConsole();
- PRINTF("\r\nC_Plus Mix C Demo-- Read Accelerometer Value\r\n");
- I2C_MasterTransferCreateHandle(BOARD_ACCEL_I2C_BASEADDR, &g_m_handle, i2c_master_callback, NULL);
- isThereAccel = I2C_ReadAccelWhoAmI();
- /* read the accel xyz value if there is accel device on board */
- if (true == isThereAccel)
- {
- uint8_t databyte = 0;
- uint8_t write_reg = 0;
- uint8_t readBuff[7];
- int16_t x, y, z;
- uint8_t status0_value = 0;
- uint32_t i = 0U;
- /* please refer to the "example FXOS8700CQ Driver Code" in FXOS8700 datasheet. */
- /* write 0000 0000 = 0x00 to accelerometer control register 1 */
- /* standby */
- /* [7-1] = 0000 000 */
- /* [0]: active=0 */
- write_reg = ACCEL_CTRL_REG1;
- databyte = 0;
- I2C_WriteAccelReg(BOARD_ACCEL_I2C_BASEADDR, g_accel_addr_found, write_reg, databyte);
- /* write 0000 0001= 0x01 to XYZ_DATA_CFG register */
- /* [7]: reserved */
- /* [6]: reserved */
- /* [5]: reserved */
- /* [4]: hpf_out=0 */
- /* [3]: reserved */
- /* [2]: reserved */
- /* [1-0]: fs=01 for accelerometer range of +/-4g range with 0.488mg/LSB */
- /* databyte = 0x01; */
- write_reg = ACCEL_XYZ_DATA_CFG;
- databyte = 0x01;
- I2C_WriteAccelReg(BOARD_ACCEL_I2C_BASEADDR, g_accel_addr_found, write_reg, databyte);
- /* write 0000 1101 = 0x0D to accelerometer control register 1 */
- /* [7-6]: aslp_rate=00 */
- /* [5-3]: dr=001 for 200Hz data rate (when in hybrid mode) */
- /* [2]: lnoise=1 for low noise mode */
- /* [1]: f_read=0 for normal 16 bit reads */
- /* [0]: active=1 to take the part out of standby and enable sampling */
- /* databyte = 0x0D; */
- write_reg = ACCEL_CTRL_REG1;
- databyte = 0x0d;
- I2C_WriteAccelReg(BOARD_ACCEL_I2C_BASEADDR, g_accel_addr_found, write_reg, databyte);
- PRINTF("The accel values:\r\n");
- for (i = 0; i < ACCEL_READ_TIMES; i++)
- {
- status0_value = 0;
- /* wait for new data are ready. */
- while (status0_value != 0xff)
- {
- I2C_ReadAccelRegs(BOARD_ACCEL_I2C_BASEADDR, g_accel_addr_found, ACCEL_STATUS, &status0_value, 1);
- }
- /* Multiple-byte Read from STATUS (0x00) register */
- I2C_ReadAccelRegs(BOARD_ACCEL_I2C_BASEADDR, g_accel_addr_found, ACCEL_STATUS, readBuff, 7);
- status0_value = readBuff[0];
- x = ((int16_t)(((readBuff[1] * 256U) | readBuff[2]))) / 4U;
- y = ((int16_t)(((readBuff[3] * 256U) | readBuff[4]))) / 4U;
- z = ((int16_t)(((readBuff[5] * 256U) | readBuff[6]))) / 4U;
- PRINTF("status_reg = 0x%x , x = %5d , y = %5d , z = %5d \r\n", status0_value, x, y, z);
- }
- }
- PRINTF("\r\nEnd of I2C example .\r\n");
- while (1)
- {
- }
- }
复制代码
测试结果
测试结果 |
|