MMC5603地磁传感器调试日志
/******************************************************************************/
/*开发平台:Keil uVision5 */
/*开发语言:C语言 */
/*作者:jerseyceo */
/*实现功能:地磁传感器的应用(指南针) */
/******************************************************************************/
第一步:nrf52832开发板与MMC5603地磁传感器硬件连接
注:MMC5603NJ可以从单个1.62V到3.6 v供应。下面的电路连接图说明了电源连接选项。
nrf52832 MMC5603
引脚: VDD —> VDD
引脚: GND —> GND
引脚: SCL —> SCL
引脚: SDA —> SDA
NOTE:焊接引脚连接上电后,使用万用表测量传感器VDD与GND引脚两端电压,检测传感器是否处于正常工作电压范围,以便进行接下来的keil编程调试与开发。
第二步:学习并掌握硬件TWI(I2C)通信原理,使用I2C通信协议配置传感器工作参数。
1.库函数的应用
图1:TWI应用步骤
1.1.定义TWI驱动程序实例
/* TWI instance ID,ID和外设编号对应,0:TWI0 1:TWI1*/
#define TWI_INSTANCE_ID 0
/* TWI instance. 定义TWI驱动程序实例,使用TWI0:外设0*/
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
/* 从机设备地址0x60=0x30<<1(TWI硬件自动完成读写位)*/
#define MMC5603_7BITI2C_ADDRESS 0x30
1.2.初始化TWI
初始化实例:err_code = nrf_drv_twi_init(&m_twi, &twi_mmc5603_config, twi_handler, NULL);
1.2.1.初始化TWI函数原型:
ret_code_t nrf_drv_twi_init(nrf_drv_twi_t const * p_instance,
nrf_drv_twi_config_t const * p_config,
nrf_drv_twi_evt_handler_t event_handler,
void * p_context)
p_instance:指向驱动程序实例结构体
p_config:指向初始化配置结构体
event_handler:事件句柄,如果设置为NULL,则使能TWI阻塞模式
p_context:指向传递给事件句柄的context
1.2.2.初始化配置结构体(nrf_drv_twi_config_t) :
const nrf_drv_twi_config_t twi_mmc5603_config = {
.scl = ARDUINO_SCL_PIN, //定义TWI SCL 引脚
.sda = ARDUINO_SDA_PIN, //定义TWI SDA 引脚
.frequency = NRF_DRV_TWI_FREQ_100K, //TWI 工作频率
.interrupt_priority = APP_IRQ_PRIORITY_HIGH, //TWI优先级
.clear_bus_init = false };
1.2.3.TWI事件句柄(nrf_drv_twi_evt_handler_t) :(TWI工作于非阻塞模式)
//TWI传输完成标志,false表示传输未完成
static volatile bool m_xfer_done = false;
void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
//判断TWI事件类型
switch (p_event->type)
{
//传输事件完成
case NRF_DRV_TWI_EVT_DONE:
//功能代码
if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
{
//此处可对传输事件完成后,打印读取数据日志信息。
}
m_xfer_done = true;//置位传输完成标志
break;
case NRF_DRV_TWI_EVT_ADDRESS_NACK: //< Error event: NACK received after sending the address.
case NRF_DRV_TWI_EVT_DATA_NACK : //< Error event: NACK received after sending a data byte.
default:
break;
}
}
1.2.4.使能TWI(nrf_drv_twi_enable):初始化完成后,使能TWI才能进行数据传输
__STATIC_INLINE
void nrf_drv_twi_enable(nrf_drv_twi_t const * p_instance)
{
if (NRF_DRV_TWI_USE_TWIM)
{
nrfx_twim_enable(&p_instance->u.twim);
}
else if (NRF_DRV_TWI_USE_TWI)
{
nrfx_twi_enable(&p_instance->u.twi);
}
}
1.2.5.数据传输
数据发送:向TWI从机发送数据
实例:err_code_tx = nrf_drv_twi_tx(&m_twi, i2c_add, ®_add, 1, false);
ret_code_t nrf_drv_twi_tx(
nrf_drv_twi_t const * p_instance,//指向TWI驱动程序实例结构体
uint8_t address,//指定的从机地址(7位LSB)
uint8_t const * p_data,//指向传输数据缓存(传感器内部寄存器/写入寄存器的命令)
uint8_t length,//发送的字节数
bool no_stop)//如果置位,成功传输后不会生成停止条件(下次传输中可重复启动)
数据接收:从TWI从机读取数据
实例:ret_code_t err_code_rx = nrf_drv_twi_rx(&m_twi, i2c_add, data, sizeof(data));
ret_code_t nrf_drv_twi_rx(
nrf_drv_twi_t const * p_instance,//指向TWI驱动程序实例结构体
uint8_t address,//指定的从机地址(7位LSB)
uint8_t * p_data,//指向接收数据缓存
uint8_t length)//读取的字节数
2.MMC5603地磁传感器原始数据读取(TWI0非阻塞)程序调试
2.1.MMC5603 I2C 时序
MMC5603 数据传输的时序如下图所示,首先产生起始条件,紧跟着发送7位地址 + 读
写位(0=写,1=读),之后发送传输的数据,最后产生停止条件。
图2:MMC5603 数据传输时序
*_*:根据 MMC5603 数据传输时序图,对照MMC5603的寄存器表,编写“写MMC5603寄存器”
和“读MMC5603寄存器”的函数。在编写读/写函数是,需要注意的是:
(1)因为时序要求写操作后产生停止条件,因此调用nrf_drv_twi_tx()函数时,参数“no_stop”必
须为false,及产生停止条件。
(2)配置TWI的工作模式是非阻塞模式,是异步的,所以调用nrf_drv_twi_tx()函数后,要等待
TWI传输完成,代码中通过查询m_xfer_done标志判断TWI传输是否完成。
2.2.写MMC5603寄存器函数
/*@brief I2C write register */
int MMC5603_Write_Reg(unsigned char i2c_add, unsigned char reg_add, unsigned char cmd)
{
/* i2c_add is the 7-bit i2c address of the sensor
* reg_add is the register address to write
* cmd is the value that need to be written to the register
* I2C operating successfully, return 1, otherwise return 0;
*/
m_xfer_done = false;//TWI传输完成标志位设置为 false,表示传输未完成
ret_code_t err_code_tx; /*指示TWI硬件驱动API调用过程的成功或失败*/
uint8_t reg[2]={reg_add,cmd};/*等待写入的寄存器地址,要写入的命名*/
err_code_tx = nrf_drv_twi_tx(&m_twi, i2c_add, reg, sizeof(reg), false);/*写入数据*/
APP_ERROR_CHECK(err_code_tx);/*检查写入过程成功或失败*/
while (m_xfer_done == false);/*一直等待TWI总线传输完成,直到m_xfer_done置为true,跳出函数,结束写操作*/
return 1;
}
2.3.单字节读MMC5603寄存器函数
/*@brief I2C read register.*/
int MMC5603_Read_Reg(unsigned char i2c_add, unsigned char reg_add, unsigned char *data)
{
/* i2c_add is the 7-bit i2c address of the sensor
* reg_add is the register address to read
* data is the first address of the buffer that need to store the register value
* I2C operating successfully, return 1, otherwise return 0;
*/
//先写寄存器,确定要读取的(只读)从机寄存器,此处不需要(无法)向目标寄存器写命令;
//再读寄存器,从slave目标(只读)寄存器读取数据到指定数据缓存区;
/* 步骤一: 写寄存器
m_xfer_done = false;//TWI传输完成标志位设置为 false,表示传输未完成
ret_code_t err_code_tx; /*指示TWI硬件驱动API调用过程中发送数据接口函数调用的成功或失败*/
err_code_tx = nrf_drv_twi_tx(&m_twi, i2c_add, ®_add, 1, false);//发送要读取的目标寄存器地址,长度为1字节
APP_ERROR_CHECK(err_code_tx);/*检查写入过程的成功或失败*/
while (m_xfer_done == false);/*一直等待TWI总线传输完成,直到m_xfer_done置为true,跳出函数,结束写操作*/
/* 步骤一: 读寄存器
m_xfer_done = false;//TWI传输完成标志位设置为 false,表示传输未完
/* 从指定地址读取一个字节*/
ret_code_t err_code_rx = nrf_drv_twi_rx(&m_twi, i2c_add, data, sizeof(data));//将从指定寄存器读取的数据(一个字节)存入指针data指向的缓存区。
APP_ERROR_CHECK(err_code_rx);/*检查读取过程的成功或失败*/
while (m_xfer_done == false);/*一直等待TWI总线传输完成,直到m_xfer_done置为true,跳出函数,结束读操作*/
return 1;
}
2.4.多字节读MMC5603寄存器函数
int MMC5603_MultiRead_Reg(unsigned char i2c_add, unsigned char reg_add, int bytesNumber, unsigned char *dataBuffer)
{
/* i2c_add is the 7-bit i2c address of the sensor
* reg_add is the first register address to read
* num is the number of the register to read
* data is the first address of the buffer that need to store the register value
* I2C operating successfully, return 1, otherwise return 0;
*/
//先写寄存器,确定要读取的(只读)从机寄存器,此处不需要(无法)向目标寄存器写命令;
//再读寄存器,从slave目标(只读)寄存器读取数据到指定数据缓存区;
/* 步骤一: 写寄存器
m_xfer_done = false;//TWI传输完成标志位设置为 false,表示传输未完成
ret_code_t err_code_tx; /*指示TWI硬件驱动API调用过程中发送数据接口函数调用的成功或失败*/
err_code_tx = nrf_drv_twi_tx(&m_twi, i2c_add, ®_add, 1, true);//发送要读取的目标寄存器地址,长度为1字节,将no_stop置为true,表示连续写多个寄存器,写完一个寄存器后不停止。
APP_ERROR_CHECK(err_code_tx);/*检查写入过程的成功或失败*/
while (m_xfer_done == false);/*一直等待TWI总线传输完成,直到m_xfer_done置为true,跳出函数,结束写操作*/
/* 步骤一: 读寄存器
m_xfer_done = false;//TWI传输完成标志位设置为 false,表示传输未完成
/* 从指定地址读取一个字节*/
ret_code_t err_code_rx = nrf_drv_twi_rx(&m_twi, i2c_add, data, sizeof(data));//将从指定寄存器读取的数据(多个字节)存入指针data指向的缓存区。读取时寄存器地址自增,读取的数据依次不断改变,存入指针data指向的缓存区。
APP_ERROR_CHECK(err_code_rx);/*检查读取过程的成功或失败*/
while (m_xfer_done == false);/*一直等待TWI总线传输完成,直到m_xfer_done置为true,跳出函数,结束读操作*/
return 1;
}