当前位置:网站首页>Mmc5603nj geomagnetic sensor (Compass example)
Mmc5603nj geomagnetic sensor (Compass example)
2022-07-03 11:26:00 【Ch_ champion】
Catalog
summary
Needs on recent projects , Add compass function , Through online search, we know , There is less information about this sensor , Here is a Demo, Hope to help the siege lions in need , Study and discuss together , come on. come on. come on. !
One 、 Schematic diagram

Two 、 platform
1、keil5.29
2、RTL8762D( Realtek Bluetooth chip )
3、 ... and 、 code
1、mmc5603nj.h file
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MMC5603NJ_H__
#define __MMC5603NJ_H__
#include "stdint.h"
#define MMC5603_7BITI2C_ADDRESS 0x30
#define MMC5603_REG_DATA 0x00
#define MMC5603_REG_XL 0x00
#define MMC5603_REG_XH 0x01
#define MMC5603_REG_YL 0x02
#define MMC5603_REG_YH 0x03
#define MMC5603_REG_ZL 0x04
#define MMC5603_REG_ZH 0x05
#define MMC5603_REG_STATUS1 0x18
#define MMC5603_REG_STATUS0 0x19
#define MMC5603_REG_ODR 0x1A
#define MMC5603_REG_CTRL0 0x1B
#define MMC5603_REG_CTRL1 0x1C
#define MMC5603_REG_CTRL2 0x1D
#define MMC5603_REG_X_THD 0x1E
#define MMC5603_REG_Y_THD 0x1F
#define MMC5603_REG_Z_THD 0x20
#define MMC5603_REG_ST_X_VAL 0x27
#define MMC5603_REG_ST_Y_VAL 0x28
#define MMC5603_REG_ST_Z_VAL 0x29
#define MMC5603_REG_PRODUCTID1 0x39
/* Bit definition for control register ODR 0x1A */
#define MMC5603_CMD_ODR_1HZ 0x01
#define MMC5603_CMD_ODR_5HZ 0x05
#define MMC5603_CMD_ODR_10HZ 0x0A
#define MMC5603_CMD_ODR_50HZ 0x32
#define MMC5603_CMD_ODR_100HZ 0x64
#define MMC5603_CMD_ODR_200HZ 0xC8
#define MMC5603_CMD_ODR_255HZ 0xFF
/* Bit definition for control register 0 0x1B */
#define MMC5603_CMD_TMM 0x01
#define MMC5603_CMD_TMT 0x02
#define MMC5603_CMD_START_MDT 0x04
#define MMC5603_CMD_SET 0x08
#define MMC5603_CMD_RESET 0x10
#define MMC5603_CMD_AUTO_SR_EN 0x20
#define MMC5603_CMD_AUTO_ST_EN 0x40
#define MMC5603_CMD_CMM_FREQ_EN 0x80
/* Bit definition for control register 1 0x1C */
#define MMC5603_CMD_BW00 0x00
#define MMC5603_CMD_BW01 0x01
#define MMC5603_CMD_BW10 0x02
#define MMC5603_CMD_BW11 0x03
#define MMC5603_CMD_ST_ENP 0x20
#define MMC5603_CMD_ST_ENM 0x40
#define MMC5603_CMD_SW_RST 0x80
/* Bit definition for control register 2 0x1D */
#define MMC5603_CMD_PART_SET1 0x00
#define MMC5603_CMD_PART_SET25 0x01
#define MMC5603_CMD_PART_SET75 0x02
#define MMC5603_CMD_PART_SET100 0x03
#define MMC5603_CMD_PART_SET250 0x04
#define MMC5603_CMD_PART_SET500 0x05
#define MMC5603_CMD_PART_SET1000 0x06
#define MMC5603_CMD_PART_SET2000 0x07
#define MMC5603_CMD_EN_PART_SET 0x08
#define MMC5603_CMD_CMM_EN 0x10
#define MMC5603_CMD_INT_MDT_EN 0x20
#define MMC5603_CMD_INT_MD_EN 0x40
#define MMC5603_CMD_HPOWER 0x80
#define MMC5603_PRODUCT_ID 0x10
#define MMC5603_MM_DONE_INT 0x01
#define MMC5603_MT_DONE_INT 0x02
#define MMC5603_MDT_FLAG_INT 0x04
#define MMC5603_ST_FAIL_INT 0x08
#define MMC5603_OTP_READ_DONE 0x10
#define MMC5603_SAT_SENSOR 0x20
#define MMC5603_MM_DONE 0x40
#define MMC5603_MT_DONE 0x80
// 16-bit mode, null field output (32768)
#define MMC5603_16BIT_OFFSET 32768
#define MMC5603_16BIT_SENSITIVITY 1024
void MMC5603_Enable(void);
uint8_t mmc5603nj_bpm_algo_handler(void);
#endif /* __MMC5603NJ_IIC__H__ */
/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/
2、mmc5603nj.c file
/*********************************************************************************************************
* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
**********************************************************************************************************
* @file mmc5603nj.c
* @brief
* @details
* @author
* @date
* @version v0.1
*********************************************************************************************************
*/
#include "trace.h"
#include "rtl876x_spi.h"
#include "rtl876x_i2c.h"
#include "rtl876x_rcc.h"
#include "rtl876x_gpio.h"
#include "rtl876x_nvic.h"
#include "board.h"
#include "string.h"
#include "hub_task.h"
#include "os_sched.h"
#include "os_timer.h"
#include "SEGGER_RTT.h"
#include "rtl876x_tim.h"
#include "mmc5603nj.h"
#include "math.h"
#define GEOMAGNETISM_LOG_EN (true)
#if (GEOMAGNETISM_LOG_EN == true)
#include "stdio.h"
#define GEOMAGNETISM_LOG DBG_LOG
#else
#define HEART_LOG(...)
#endif
/* Indicate working mode of sensor */
static uint8_t sensor_state = 1;
/* Function declaration */
/**
* @brief Factory test mode
*/
int MMC5603_Factory_Test_Mode(void);
/**
* @brief SET operation
*/
void MMC5603_SET(void);
/**
* @brief RESET operation
*/
void MMC5603_RESET(void);
/**
* @brief OTP read done check
*/
int MMC5603_Check_OTP(void);
/**
* @brief Check Product ID
*/
int MMC5603_CheckID(void);
/**
* @brief Auto self-test registers configuration
*/
void MMC5603_Auto_SelfTest_Configuration(void);
/**
* @brief Auto self-test
*/
int MMC5603_Auto_SelfTest(void);
void mmc5603_Delay_ms(uint16_t delay_time)
{
os_delay(delay_time);
}
uint8_t MMC5603_I2c_Write(uint8_t reg, uint8_t dat)
{
uint8_t I2C_WriteBuf[2] = {0x0, 0x0};
I2C_WriteBuf[0] = reg;
I2C_WriteBuf[1] = dat;
uint32_t time_out = SYSTEM_IIC_TIMEROUT;
while ((I2C_GetFlagState(HRS_I2C_BUS, I2C_FLAG_TFE) == RESET) && (--time_out != 0));
time_out = SYSTEM_IIC_TIMEROUT;
while ((I2C_GetFlagState(HRS_I2C_BUS, I2C_FLAG_MST_ACTIVITY) == SET) && (--time_out != 0));
I2C_SetSlaveAddress(HRS_I2C_BUS, MMC5603_7BITI2C_ADDRESS);
I2C_MasterWrite(HRS_I2C_BUS, I2C_WriteBuf, 2);
if (time_out == 0) {
RtkWristbandSys.flag_field.i2c_bus_lock = true;
}
return 0;
}
uint8_t MMC5603_I2c_Read(uint8_t reg, uint8_t *buf, uint8_t len)
{
uint8_t tmp_buffer[1] = {0};
uint32_t time_out = SYSTEM_IIC_TIMEROUT;
tmp_buffer[0] = reg;
while ((I2C_GetFlagState(HRS_I2C_BUS, I2C_FLAG_TFE) == RESET) && (--time_out != 0));
time_out = SYSTEM_IIC_TIMEROUT;
while ((I2C_GetFlagState(HRS_I2C_BUS, I2C_FLAG_MST_ACTIVITY) == SET) && (--time_out != 0));
// I2C_SetSlaveAddress(HRS_I2C_BUS, (MMC5603_7BITI2C_ADDRESS | (0x01<<7)));
I2C_SetSlaveAddress(HRS_I2C_BUS, MMC5603_7BITI2C_ADDRESS);
I2C_Status ret = I2C_RepeatRead(HRS_I2C_BUS, tmp_buffer, 1, buf, len);
if (time_out == 0) {
RtkWristbandSys.flag_field.i2c_bus_lock = true;
}
if (ret != I2C_Success) {
return 1;
}
return 0;
}
uint8_t MMC5603_Write_Reg(uint8_t regAddr, uint8_t data)
{
return MMC5603_I2c_Write(regAddr, data);
}
uint8_t MMC5603_Read_Reg(uint8_t regAddr, uint8_t *buf)
{
return MMC5603_I2c_Read(regAddr, buf, 1);
}
uint8_t MMC5603_MultiRead_Reg(uint8_t regAddr, uint8_t *buf, uint16_t len)
{
return MMC5603_I2c_Read(regAddr, buf, len);
}
/*********************************************************************************
* decription: Factory test mode
*********************************************************************************/
int MMC5603_Factory_Test_Mode(void)
{
int i;
uint8_t data_reg[6] ={0};
uint16_t data_set[3] = {0};
uint16_t data_reset[3] = {0};
uint32_t delta_data[3] = {0};
const uint16_t thr_srst_low = 100;
/* Write reg 0x1D */
/* Set Cmm_en bit '0', Disable continuous mode */
MMC5603_Write_Reg(MMC5603_REG_CTRL2, 0x00);
mmc5603_Delay_ms(20);
/* Write reg 0x1B */
/* Set Auto_SR_en bit '0', Disable the function of automatic set/reset */
MMC5603_Write_Reg(MMC5603_REG_CTRL0, 0x00);
/* Write reg 0x1C, Set BW<1:0> = 00 */
MMC5603_Write_Reg(MMC5603_REG_CTRL1, 0x00);
/* Do RESET operation */
MMC5603_RESET();
/* Write 0x01 to register 0x1B, set Take_meas_M bit '1' */
MMC5603_Write_Reg(MMC5603_REG_CTRL0, MMC5603_CMD_TMM);
/* Delay 10 ms to finish the TM operation */
mmc5603_Delay_ms(10);
/* Read register data */
MMC5603_MultiRead_Reg(MMC5603_REG_DATA, data_reg, 6);
/* Get high 16bits data */
data_reset[0] = (uint16_t)(data_reg[0] << 8 | data_reg[1]); //X axis
data_reset[1] = (uint16_t)(data_reg[2] << 8 | data_reg[3]); //Y axis
data_reset[2] = (uint16_t)(data_reg[4] << 8 | data_reg[5]); //Z axis
/* Do SET operation */
MMC5603_SET();
/* Write 0x01 to register 0x1B, set Take_meas_M bit '1' */
MMC5603_Write_Reg(MMC5603_REG_CTRL0,MMC5603_CMD_TMM);
/* Delay 10 ms to finish the TM operation */
mmc5603_Delay_ms(10);
/* Read register data */
MMC5603_MultiRead_Reg(MMC5603_REG_DATA, data_reg, 6);
/* Get high 16bits data */
data_set[0] = (uint16_t)(data_reg[0] << 8 | data_reg[1]); //X axis
data_set[1] = (uint16_t)(data_reg[2] << 8 | data_reg[3]); //Y axis
data_set[2] = (uint16_t)(data_reg[4] << 8 | data_reg[5]); //Z axis
for (i = 0; i < 3; i++)
{
if(data_set[i] >= data_reset[i])
delta_data[i] = data_set[i] - data_reset[i];
else
delta_data[i] = data_reset[i] - data_set[i];
}
/* If output < 100lsb, fail*/
if (delta_data[0]<thr_srst_low && delta_data[1]<thr_srst_low && delta_data[2]<thr_srst_low)
return -1; // fail
return 1; //pass
}
/*********************************************************************************
* decription: SET operation
*********************************************************************************/
void MMC5603_SET(void)
{
/* Write 0x08 to register 0x1B, set SET bit high */
MMC5603_Write_Reg(MMC5603_REG_CTRL0, MMC5603_CMD_SET);
/* Delay to finish the SET operation */
mmc5603_Delay_ms(1);
return;
}
/*********************************************************************************
* decription: RESET operation
*********************************************************************************/
void MMC5603_RESET(void)
{
/* Write 0x10 to register 0x1B, set RESET bit high */
MMC5603_Write_Reg(MMC5603_REG_CTRL0, MMC5603_CMD_RESET);
/* Delay to finish the RESET operation */
mmc5603_Delay_ms(1);
return;
}
/*********************************************************************************
* decription: Product ID check
*********************************************************************************/
int MMC5603_CheckID(void)
{
unsigned char pro_id = 0;
/* Read register 0x39, check product ID */
MMC5603_Read_Reg(MMC5603_REG_PRODUCTID1, &pro_id);
GEOMAGNETISM_LOG("pro_id:%d \n", pro_id);
if (pro_id != MMC5603_PRODUCT_ID)
return -1;
return 1;
}
/*********************************************************************************
* decription: Auto self-test registers configuration
*********************************************************************************/
void MMC5603_Auto_SelfTest_Configuration(void)
{
int i;
uint8_t reg_value[3];
int16_t st_thr_data[3]={0};
int16_t st_thr_new[3]={0};
int16_t st_thd[3]={0};
uint8_t st_thd_reg[3];
/* Read trim data from reg 0x27-0x29 */
MMC5603_MultiRead_Reg(MMC5603_REG_ST_X_VAL, reg_value, 3);
for (i = 0; i < 3; i++)
{
st_thr_data[i] = (int16_t)(reg_value[i]-128)*32;
if (st_thr_data[i]<0)
st_thr_data[i] = -st_thr_data[i];
st_thr_new[i] = st_thr_data[i]-st_thr_data[i]/5;
st_thd[i] = st_thr_new[i]/8;
if (st_thd[i] > 255)
st_thd_reg[i] = 0xFF;
else
st_thd_reg[i] = (uint8_t)st_thd[i];
}
/* Write threshold into the reg 0x1E-0x20 */
MMC5603_Write_Reg(MMC5603_REG_X_THD, st_thd_reg[0]);
MMC5603_Write_Reg(MMC5603_REG_Y_THD, st_thd_reg[1]);
MMC5603_Write_Reg(MMC5603_REG_Z_THD, st_thd_reg[2]);
return;
}
/*********************************************************************************
* decription: Auto self-test
*********************************************************************************/
int MMC5603_Auto_SelfTest(void)
{
uint8_t reg_status = 0;
/* Write 0x40 to register 0x1B, set Auto_st_en bit high */
MMC5603_Write_Reg(MMC5603_REG_CTRL0, MMC5603_CMD_AUTO_ST_EN);
/* Delay 15ms to finish the selftest process */
mmc5603_Delay_ms(15);
/* Read register 0x18, check Sat_sensor bit */
MMC5603_Read_Reg(MMC5603_REG_STATUS1, ®_status);
if ((reg_status&MMC5603_SAT_SENSOR))
return -1;
return 1;
}
/*********************************************************************************
* decription: Continuous mode configuration with auto set and reset
*********************************************************************************/
void MMC5603_Continuous_Mode_With_Auto_SR(uint8_t bandwith, uint8_t sampling_rate)
{
/* Write reg 0x1C, Set BW<1:0> = bandwith */
MMC5603_Write_Reg(MMC5603_REG_CTRL1, bandwith);
/* Write reg 0x1A, set ODR<7:0> = sampling_rate */
MMC5603_Write_Reg(MMC5603_REG_ODR, sampling_rate);
/* Write reg 0x1B */
/* Set Auto_SR_en bit '1', Enable the function of automatic set/reset */
/* Set Cmm_freq_en bit '1', Start the calculation of the measurement period according to the ODR*/
MMC5603_Write_Reg(MMC5603_REG_CTRL0, MMC5603_CMD_CMM_FREQ_EN|MMC5603_CMD_AUTO_SR_EN);
/* Write reg 0x1D */
/* Set Cmm_en bit '1', Enter continuous mode */
MMC5603_Write_Reg(MMC5603_REG_CTRL2, MMC5603_CMD_CMM_EN);
return;
}
/*********************************************************************************
* decription: Do selftest operation periodically
*********************************************************************************/
int MMC5603_Saturation_Checking(void)
{
int ret = 0; //1 pass, -1 fail, 0 elapsed time is less 5 seconds
/* If sampling rate is 50Hz, then do saturation checking every 250 loops, i.e. 5 seconds */
static int NumOfSamples = 250;
static int cnt = 0;
if ((cnt++) >= NumOfSamples) {
cnt = 0;
ret = MMC5603_Auto_SelfTest();
if (ret == -1) {
/* Sensor is saturated, need to do SET operation */
MMC5603_SET();
}
/* Do TM_M after selftest operation */
MMC5603_Write_Reg(MMC5603_REG_CTRL0, MMC5603_CMD_TMM);
mmc5603_Delay_ms(8);
}
return ret;
}
/*********************************************************************************
* decription: Auto switch the working mode between Auto_SR and SETonly
*********************************************************************************/
void MMC5603_Auto_Switch(uint16_t *mag)
{
float mag_out[3];
mag_out[0] = ((float)mag[0] - MMC5603_16BIT_OFFSET)/MMC5603_16BIT_SENSITIVITY;
mag_out[1] = ((float)mag[1] - MMC5603_16BIT_OFFSET)/MMC5603_16BIT_SENSITIVITY;
mag_out[2] = ((float)mag[2] - MMC5603_16BIT_OFFSET)/MMC5603_16BIT_SENSITIVITY;
if (sensor_state == 1) {
/* If X or Y axis output exceed 10 Gauss, then switch to single mode */
if ((fabs(mag_out[0])>10.0f) || (fabs(mag_out[1])>10.0f)) {
sensor_state = 2;
/* Disable continuous mode */
MMC5603_Write_Reg(MMC5603_REG_CTRL2, 0x00);
mmc5603_Delay_ms(15);//Delay 15ms to finish the last sampling
/* Do SET operation */
MMC5603_Write_Reg(MMC5603_REG_CTRL0, MMC5603_CMD_SET);
mmc5603_Delay_ms(1);//Delay 1ms to finish the SET operation
/* Do TM_M before next data reading */
MMC5603_Write_Reg(MMC5603_REG_CTRL0, MMC5603_CMD_TMM);
mmc5603_Delay_ms(8);//Delay 8ms to finish the TM_M operation
}
} else if (sensor_state == 2) {
/* If both of X and Y axis output less than 8 Gauss, then switch to continuous mode with Auto_SR */
if ((fabs(mag_out[0])<8.0f) && (fabs(mag_out[1])<8.0f)) {
sensor_state = 1;
/* Enable continuous mode with Auto_SR */
MMC5603_Write_Reg(MMC5603_REG_CTRL0, MMC5603_CMD_CMM_FREQ_EN|MMC5603_CMD_AUTO_SR_EN);
MMC5603_Write_Reg(MMC5603_REG_CTRL2, MMC5603_CMD_CMM_EN);
} else {
/* Sensor checking */
if (MMC5603_Saturation_Checking()==0) {
/* Do TM_M before next data reading */
MMC5603_Write_Reg(MMC5603_REG_CTRL0, MMC5603_CMD_TMM);
}
}
}
return;
}
/*********************************************************************************
* decription: Disable sensor continuous mode
*********************************************************************************/
void MMC5603_Disable(void)
{
/* Write reg 0x1D */
/* Set Cmm_en bit '0', Disable continuous mode */
MMC5603_Write_Reg(MMC5603_REG_CTRL2, 0x00);
mmc5603_Delay_ms(20);
return;
}
/*********************************************************************************
* decription: Enable sensor
*********************************************************************************/
void MMC5603_Enable(void)
{
int ret = 0;
/* Inite the sensor state */
sensor_state = 1;
/* Check product ID */
ret = MMC5603_CheckID();
if (ret<0)
return;
/* Auto self-test registers configuration */
MMC5603_Auto_SelfTest_Configuration();
/* Do SET operation */
MMC5603_SET();
/* Work mode setting */
MMC5603_Continuous_Mode_With_Auto_SR(MMC5603_CMD_BW00, 50);
mmc5603_Delay_ms(20);
return;
}
/*********************************************************************************
* decription: Read the data register and convert to magnetic field
*********************************************************************************/
void MMC5603_GetData(float *mag_out)
{
uint8_t data_reg[6] = {0};
uint16_t data_temp[3] = {0};
/* Read register data */
MMC5603_MultiRead_Reg(MMC5603_REG_DATA, data_reg, 6);
/* Get high 16bits data */
data_temp[0] = (uint16_t)(data_reg[0] << 8 | data_reg[1]);
data_temp[1] = (uint16_t)(data_reg[2] << 8 | data_reg[3]);
data_temp[2] = (uint16_t)(data_reg[4] << 8 | data_reg[5]);
/* Transform to unit Gauss */
mag_out[0] = ((float)data_temp[0] - MMC5603_16BIT_OFFSET)/MMC5603_16BIT_SENSITIVITY;
mag_out[1] = ((float)data_temp[1] - MMC5603_16BIT_OFFSET)/MMC5603_16BIT_SENSITIVITY;
mag_out[2] = ((float)data_temp[2] - MMC5603_16BIT_OFFSET)/MMC5603_16BIT_SENSITIVITY;
MMC5603_Auto_Switch(data_temp);
return;
}
uint8_t mmc5603nj_bpm_algo_handler(void)
{
float magnetic_field_x;
float magnetic_field_y;
float magnetic_field_z;
/* Magnetic field vector, unit is gauss */
float mag_raw_data[3] = {0.0};
/* Get the MMC5603 data, unit is gauss */
MMC5603_GetData(mag_raw_data);
magnetic_field_x = mag_raw_data[0]; //unit is gauss
magnetic_field_y = mag_raw_data[1]; //unit is gauss
magnetic_field_z = mag_raw_data[2]; //unit is gauss
/* Sampling interval is 20ms, and the sampling rate is 50Hz. */
mmc5603_Delay_ms(20);
char Buffer_X[100]={0};
char Buffer_Y[100]={0};
char Buffer_Z[100]={0};
sprintf(Buffer_X,"%0.3f ",magnetic_field_x);
sprintf(Buffer_Y,"%0.3f ",magnetic_field_y);
sprintf(Buffer_Z,"%0.3f ",magnetic_field_z);
GEOMAGNETISM_LOG("x1: %s gauss.",Buffer_X);
GEOMAGNETISM_LOG("y1: %s gauss.",Buffer_Y);
GEOMAGNETISM_LOG("z1: %s gauss.",Buffer_Z);
/*Shenzhen Guangdong
Latitude latitude : 22° 32' 43.9" N
Longitude longitude : 114° 4' 5.9" E
MA TSO LUNG
Magnetic Declination Geomagnetic declination : -3° 1'
Declination is NEGATIVE (WEST)
Inclination: 34° 6'
Magnetic field strength Magnetic field intensity : 45442.3 nT=45.4423μT=0.454423Gauss*/
// Direction angle calculation : The direction angle is X Axis and Y The arctangent of the shaft reading , Output direction angle and mobile compass function comparison , The measurement result is good
//float Curent_Angle=(atan2((double)mag_raw_data[1],(double)mag_raw_data[0]) * (180 / 3.14159265) + 180+ Geomagnetic declination );
float Curent_Angle=(atan2((double)mag_raw_data[1],(double)mag_raw_data[0]) * (180 / 3.14159265) + 180 + 3);
char TEST_OK[]={"OK"};
char Angle[100]={0};
sprintf(Angle,"%0.2f ",Curent_Angle);
GEOMAGNETISM_LOG("Angle: %s ",Angle);
GEOMAGNETISM_LOG("%s",TEST_OK);
return 0;
}
3、main.c file
#include <stdlib.h>
#include "board.h"
#include "os_sched.h"
#include "string.h"
#include "trace.h"
#include "gap.h"
#include "gap_adv.h"
#include "gap_bond_le.h"
#include "app_task.h"
#include "communicate_task.h"
#include "dlps.h"
#include "ftl.h"
#include "ias.h"
#include "bas.h"
#include "hids_media.h"
#include "ancs.h"
#include "ams.h"
#include <gatts_client.h>
#include "rtl876x_io_dlps.h"
#include "rtl876x_rcc.h"
#include "rtl876x_i2c.h"
#include "otp_config.h"
#include "rtl876x_lib_platform.h"
#include "single_tone.h"
#include "profile_server.h"
#include "hub_clock.h"
#include "app_flash_config.h"
#include "profile_client.h"
#include "ota_service.h"
#include "hub_task.h"
#include "hci_app.h"
#include "flash_test_temp.h"
#include "mmc5603nj.h"
int main(void)
{
le_gap_init(1);
gap_lib_init();
app_le_gap_init();
app_le_profile_init();
pwr_mgr_init();
task_init();
os_sched_start();
} Four 、 Running results


5、 ... and 、 summary
Okay , That's all for the introduction , Take a note , At the same time, I hope I can help the siege lions who need help .
Reference article :
MMC5603 Geomagnetic sensor commissioning log _jerseyCEO The blog of -CSDN Blog
边栏推荐
- Tencent micro app to get wechat user information
- asyncio 警告 DeprecationWarning: There is no current event loop
- VPP three-layer network interconnection configuration
- 1. Hal driven development
- How to become a senior digital IC Design Engineer (1-3) Verilog coding syntax: Verilog behavior level, register transfer level, gate level (abstract level)
- Expandablelistview that can expand and shrink (imitating the list page of professional selection of Zhilian recruitment)
- 软件测试周刊(第78期):你对未来越有信心,你对现在越有耐心。
- How PHP solves the problem of high concurrency
- 机器学习 3.2 决策树模型 学习笔记(待补)
- LeetCode 46:全排列
猜你喜欢

Tencent micro app to get wechat user information

软考中级软件设计师该怎么备考

After using the thread pool for so long, do you really know how to reasonably configure the number of threads?

ASP.NET-酒店管理系统

How did I grow up in the past eight years as a test engineer of meituan? I hope technicians can gain something after reading it

Stack, monotone stack, queue, monotone queue

Application of high-precision indoor positioning technology in safety management of smart factory

活动预告 | 直播行业“内卷”,以产品力拉动新的数据增长点

Event preview | the live broadcast industry "rolled in" to drive new data growth points with product power

MATLAB提取不規則txt文件中的數值數據(簡單且實用)
随机推荐
进程与线程
2022 东北四省赛 VP记录/补题
BI技巧丨权限轴
Tablespace creation management and control file management
Arctangent entropy: the latest SCI paper in July 2022
C language AES encryption and decryption
如何成为一名高级数字 IC 设计工程师(1-2)Verilog 编码语法篇:Verilog 1995、2001、2005 标准
表空间创建管理及控制文件管理
repo ~ 常用命令
How to become a senior digital IC Design Engineer (1-2) Verilog coding syntax: Verilog 1995, 2001, 2005 standards
How to clean up v$rman_ backup_ job_ Details view reports error ora-02030
POI excel cell wrap
程序员的创业陷阱:接私活
MATLAB提取不规则txt文件中的数值数据(简单且实用)
高精度室内定位技术,在智慧工厂安全管理的应用
Commonly used discrete random distribution
DS90UB949
Processes and threads
Résumé des questions d'entrevue (2) Modèle io, ensemble, principe NiO, pénétration du cache, avalanche de rupture
Internet Socket (非)阻塞write/read n个字节