This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C1294NCPDT:TivaWare 传感器库 LSM303DLHC 磁力计问题

Guru**** 2320870 points
Other Parts Discussed in Thread: TM4C1294NCPDT
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/579090/tm4c1294ncpdt-tivaware-sensor-library-lsm303dlhc-magnetometer-issue

器件型号:TM4C1294NCPDT

Howdy、

我有一个定制板、该板应通过 I2C 与 TM4C1294NCPDT 微控制器进行通信。 我之前使用过外设驱动程序来成功地使用 UART 和 GPIO 功能。 我一直在通过 I2C 外设库进行读取、 传感器库中的 I2C 主驱动程序和传感器库中的 LSM303DLHC 驱动程序、我已尽力将其设置为仅在循环中读取、但在 SCL 或 SDA 线上没有任何内容(使用逻辑分析仪查看、 均保持高电平)。 我复制了下面的代码并对重要事项进行了注释。 我在项目的其他部分有一些功能、但它们根本没有被使用。 感谢您的任何帮助!!

#include
#include
#include
#include
#include
#include
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "inc/hw_gpio.h"
#include "piconfconfig.h"//设置引脚
#include "inc/hw_i2c.h"//在 i2c 中使用
#include "inc/hw_timer.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom_map.h"
#include "driverlib/gpio.h"
#include "driverlib/timer.h"
#include "driverlib/fpu.h"
#include "driverlib/uart.h"
#include "driverlib/i2c.h"//在 i2c 中使用
#include "sensorlib/i2cm_drv.c"//在 i2c 中使用
#include "sensorlib/i2cm_drv.h"//在 i2c 中使用
#include "sensorlib/lsm303dlhc_mag.c"//用于 i2c
#include "sensorlib/lsm303dlhc_mag.h"//用于 i2c
#include "sensorlib/hw_lsm303dlhc.h"//用于 i2c

//typedef 结构
//{
//浮动纬度;//忽略此项
//浮点经度;
//}位置;
//原型函数
void pinconfig (void);//调用配置引脚的函数
//void UartInit (void);
//void GpsConfigTX (void);
//Position GpsRXData (空);
//float convert_decime_degrees (float num);
//双 Azi (浮点 lat1、浮点 lon1、浮点 late2、浮点 lon2);//忽略这些
//void TimerSetup (void);
//void delay (uint32_t);
//void speedprofile (float、float、float、double);

tI2CMInstance sI2CInst;
volatile bool g_bLSM303DLHCCMagDone;

void inthandler (void);//创建了此函数,由中断处理程序调用

void LSM303DLHCMagCallback (void * pvCallbackData、uint_fast8_t ui8状态)

//查看是否发生错误。
if (ui8Status!= I2CM_STATUS_SUCCESS)

//发生了错误,所以如果需要,请在此处处理。 //这来自传感器库

//指示 LSM303DLHCMag 事务已完成。
G_bLSM303DLHCMADone = true;


int main (空)

//将时钟频率设置为120MHz
uint32_t freq = SysCtlClockFreqSet (SYSCTL_OSC_MAIN|SYSCTL_USE_PLL|SYSCTL_XTAL_25MHz | SYSCTL_CFG_VCO_480、120000000);
传感器库中的//变量
fMag[3]浮点型;
tLSM303DLHCMag sLSM303DLHCMag;
针对 SDA+SCL 的//configure 引脚(与引脚配置功能中的所有其他引脚一起完成
pinconfig();
//启用系统外设,并等到其就绪后再继续
SysCtlPeripheralEnable (SYSCTL_Periph_I2C7);
while (!SysCtlPeripheralReady (SYSCTL_Periph_I2C7))


//将 I2C 外设配置为 true 以实现快速数据传输
I2CMasterInitExpClk (I2C7 _BASE、120000000、TRUE);
//清除主中断
I2CMasterIntClear (I2C7 _BASE);
//声明指向 i2c 主中断处理程序的函数指针
void (*处理程序)(void);
handler =收件人;
//未启用 I2C 中断

//为启用的 I2C 中断注册中断处理程序
I2CIntRegister (I2C3_base、(*处理程序));
//初始化磁力计(param #2可能是 I2C 的基址)
int maginit = LSM303DLHCMagInit (&sLSM303DLHCMag、&sI2CInst、0x3D、LSM303DLHCMagCallback、0);
//连续读取
while (1)

G_bLSM303DLHCMADONE = false;
LSM303DLHCCMagDataRead (&sLSM303DLHCMag、LSM303DLHCCMagCallback、0);
while (!g_bLSM303DLHCMagDone)//在此处卡住


//
//获取新的磁力计读数。
//
LSM303DLHCMagDataMagnetoGetFloat (&sLSM303DLHCMag、&fMag[0]、&fMag[1]、&fMag[2]);


空收款人(空)

I2CMIntHandler (sI2CInst);

///------------------------------------------------
void pinconfig (void)

//启用外设时钟
MAP_SysCtlPeripheralEnable (SYSCTL_Periph_EPHY0);
MAP_SysCtlPeripheralEnable (SYSCTL_Periph_I2C7);
MAP_SysCtlPeripheralEnable (SYSCTL_Periph_UART4);
MAP_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
MAP_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);
MAP_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);
MAP_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOK);

//
MAP_GPIOPinTypeGPIOOutput (GPIO_PORTK_base、GPIO_PIN_4);
//
MAP_GPIOPinTypeGPIOOutput (GPIO_PORTK_base、GPIO_PIN_6);
// GPIOOutput 的使能引脚 PA4
MAP_GPIOPinTypeGPIOOutput (GPIO_Porta_base、GPIO_PIN_4);
// GPIOOutput 的使能引脚 PA5
MAP_GPIOPinTypeGPIOOutput (GPIO_Porta_base、GPIO_PIN_5);
// GPIOOutput 的使能引脚 PA0
MAP_GPIOPinTypeGPIOOutput (GPIO_Porta_base、GPIO_PIN_0);
// GPIOOutput 的使能引脚 PA1
MAP_GPIOPinTypeGPIOOutput (GPIO_Porta_base、GPIO_PIN_1);
// GPIOOutput 的使能引脚 PA2
MAP_GPIOPinTypeGPIOOutput (GPIO_Porta_base、GPIO_PIN_2);
// GPIOOutput 的使能引脚 PA3
MAP_GPIOPinTypeGPIOOutput (GPIO_Porta_base、GPIO_PIN_3);
// GPIOOutput 的使能引脚 PF0
MAP_GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、GPIO_PIN_0);
// I2C7 I2C7SCL 的使能引脚 PD0
MAP_GPIOPinConfigure (GPIO_PD0_I2C7SCL);
MAP_GPIOPinTypeI2CSCL (GPIO_PORTD_BASE、GPIO_PIN_0);
// I2C7 I2C7SDA 的使能引脚 PD1
MAP_GPIOPinConfigure (GPIO_PD1_I2C7SDA);
MAP_GPIOPinTypeI2C (GPIO_PORTD_BASE、GPIO_PIN_1);
// UART4 U4RX 的使能引脚 PK0
MAP_GPIOPinConfigure (GPIO_PK0_U4RX);
MAP_GPIOPinTypeUART (GPIO_PORTK_base、GPIO_PIN_0);
// UART4 U4TX 的使能引脚 PK1
MAP_GPIOPinConfigure (GPIO_PK1_U4TX);
MAP_GPIOPinTypeUART (GPIO_PORTK_base、GPIO_PIN_1);

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    在调用 LSM303DLHCMMagInit()之前,我看不到您首先调用 I2CMInit()来准备 I2C 主设备和驱动程序以进行操作。 当您调用 I2CMInit()时,它会准备状态结构,稍后 LSM303DLHCCMagInit()将引用该结构。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢!
    我添加了该行、并且在 SDA 或 SCL 行上仍然没有任何东西。 这是更新后的代码。


    tI2CMInstance sI2CInst;
    volatile bool g_bLSM303DLHCCMagDone;

    void inthandler (void);//创建了此函数,由中断处理程序调用

    void LSM303DLHCMagCallback (void * pvCallbackData、uint_fast8_t ui8状态)

    //查看是否发生错误。
    if (ui8Status!= I2CM_STATUS_SUCCESS)

    //发生了错误,所以如果需要,请在此处处理。//这来自传感器库

    //指示 LSM303DLHCMag 事务已完成。
    G_bLSM303DLHCMADone = true;



    int main (空)

    //将时钟频率设置为120MHz
    uint32_t freq = SysCtlClockFreqSet (SYSCTL_OSC_MAIN|SYSCTL_USE_PLL|SYSCTL_XTAL_25MHz | SYSCTL_CFG_VCO_480、120000000);
    传感器库中的//变量
    fMag[3]浮点型;
    tLSM303DLHCMag sLSM303DLHCMag;
    针对 SDA+SCL 的//configure 引脚(与引脚配置功能中的所有其它引脚一起完成)
    pinconfig();
    //启用系统外设,并等到其就绪后再继续
    SysCtlPeripheralEnable (SYSCTL_Periph_I2C7);
    while (!SysCtlPeripheralReady (SYSCTL_Periph_I2C7))


    //将 I2C 外设配置为 true 以实现快速数据传输
    I2CMasterInitExpClk (I2C7 _BASE、120000000、TRUE);
    //清除主中断
    I2CMasterIntClear (I2C7 _BASE);
    //声明指向 i2c 主中断处理程序的函数指针
    void (*处理程序)(void);
    handler =收件人;
    //未启用 I2C 中断

    //为启用的 I2C 中断注册中断处理程序
    I2CIntRegister (I2C3_base、(*处理程序));
    //初始化 I2C 主驱动程序
    I2CMInit (&sI2CInst、I2C7_BASE、INT_I2C7、0xff、0xff、120000000);
    //初始化磁力计(param #2可能是 I2C 的基址)
    int maginit = LSM303DLHCMagInit (&sLSM303DLHCMag、&sI2CInst、0x3D、LSM303DLHCMagCallback、0);
    //连续读取
    while (1)

    G_bLSM303DLHCMADONE = false;
    LSM303DLHCCMagDataRead (&sLSM303DLHCMag、LSM303DLHCCMagCallback、0);
    while (!g_bLSM303DLHCMagDone)//在此处卡住


    //
    //获取新的磁力计读数。
    //
    LSM303DLHCMagDataMagnetoGetFloat (&sLSM303DLHCMag、&fMag[0]、&fMag[1]、&fMag[2]);



    空收款人(空)

    I2CMIntHandler (sI2CInst);
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我注意到的一点是、我认为 I2C 从地址不正确。 从器件地址为0x1E。 您提供的是包含读取位的0x3D。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我尝试了0x1E、但它并没有真正的改变。 我现在要仔细检查所有硬件、以确保没有任何问题。 我担心的是、该特定器件的传感器库和 I2C 主驱动器严重记录在案。 我理解发生什么事的一般想法、但我似乎无法连接这些点。

    您是否有关于这两个的实例数据的更多信息? 我认为这是问题的一部分。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这是我的最终功能代码。 事实证明、它报告的是 x、z、y、而不是 x、y、z 此外、我不知道发生在哪里、而是字节交换方式的某个位置。


    由中断处理程序调用的 void Maginthandler (void)//函数

    I2CMIntHandler (&g_sI2CInst);//此 API 命令指定在此函数中使用


    静态空 MagCallback (void *pvCallbackData,uint_fast8_t ui8Status)

    //查看是否发生错误。
    if (ui8Status!= I2CM_STATUS_SUCCESS)

    //发生了错误,所以如果需要,请在此处处理。//这来自传感器库

    //指示 LSM303DLHCMag 事务已完成。
    G_bLSM303DLHCMADone = true;

    void MagInit (void)

    //I2C 设置
    ///----------------------------------------------------------
    //启用系统外设,并等到其就绪后再继续
    SysCtlPeripheralEnable (SYSCTL_Periph_I2C7);
    while (!SysCtlPeripheralReady (SYSCTL_Periph_I2C7))


    //配置 I2C 外设,true 可实现快速数据传输(请尝试删除此项)
    I2CMasterInitExpClk (I2C7 _BASE、120000000、TRUE);
    //清除主中断(尝试删除此中断)
    I2CMasterIntEnable (I2C4_base);
    //声明指向 i2c 主中断处理程序的函数指针
    void (*处理程序)(void);
    handler = Maginthandler;
    //为启用的 I2C 中断注册中断处理程序
    I2CIntRegister (I2C3_base、(*处理程序));
    //初始化 I2C 主驱动程序
    I2CMInit (&g_sI2CInst、I2C7_BASE、INT_I2C7、0xff、0xff、120000000);
    // LSM303DLHC 磁力计配置
    ///----------------------------------------------------------
    //磁力计忙
    G_bLSM303DLHCMADONE = false;
    //初始化磁力计
    int maginit = LSM303DLHCMagInit (&g_sLSM303DLHCMag、&g_sI2CInst、0x1E、MagCallback、0);
    //等待初始化完成
    while (g_bLSM303DLHCMagDone=false)


    //磁力计忙
    G_bLSM303DLHCMADONE = false;
    //配置75Hz 更新速率
    LSM303DLHCMADReadModifyWrite (&g_sLSM303DLHCMag、LSM303DLHC_MAG_CRA、~LSM303DLHC_MAG_CRA_DO_M、LSM303DLHC_MAG_CRA_DO_75Hz、MagCallback、0);
    //等待配置完成
    while (g_bLSM303DLHCMagDone=false)


    //磁力计忙
    G_bLSM303DLHCMADONE = false;
    //配置连续测量
    LSM303DLHCCMagReadModifyWrite (&g_sLSM303DLHCMag、LSM303DLHC_MAG_MR、~LSM303DLHC_MAG_MR_MODE_M、LSM303DLHC_MAG_MR_MODE_Continuous、MagCallback、0);
    //等待配置完成
    while (g_bLSM303DLHCMagDone=false)


    //磁力计忙
    G_bLSM303DLHCMADONE = false;
    //针对+/- 2.5高斯输入范围进行配置
    LSM303DLHCCMagReadModifyWrite (&g_sLSM303DLHCMag、LSM303DLHC_MAG_CRB、~LSM303DLHC_MAG_CRB_GAIN_M、LSM303DLHC_MAG_CRB_GAIN_5_6GAUSS、MagCallback、0);
    //等待配置完成
    while (g_bLSM303DLHCMagDone=false)



    float getHeading (空)

    //磁力计忙
    G_bLSM303DLHCMADONE = false;
    //读取磁力计上的数据寄存器
    LSM303DLHCMagDataRead (&g_sLSM303DLHCMag、MagCallback、0);
    while (g_bLSM303DLHCMagDone=false)


    //获取最新的原始磁力计数据
    LSM303DLHCMagDataMagnetoGetRaw (&g_sLSM303DLHCMag、&g_fMag[0]、&g_fMagg[1]、&g_fMagg[2]);
    //转换为无符号16位整数
    uint16_t x =(g_fMag[0]);
    //交换字节
    uint16_t 交换=(x << 8)|(x >> 8);
    //二进制补码到有符号整数转换
    int16_t X =交换;
    //硬铁偏移校准
    X =(X+7808.5);
    //转换为无符号16位整数
    uint16_t z =(g_fMag[1]);
    //交换字节
    交换=(z << 8)|(z >> 8);
    //二进制补码到有符号整数转换
    int16_t Z =交换;
    //转换为16位无符号整型
    uint16_t y =(g_fMag[2]);
    //交换字节
    交换=(y << 8)|(y >> 8);
    //将二进制补码转换为有符号整数
    int16_t Y =已交换;
    //硬铁偏移校准
    Y=(Y+3);
    //计算标题
    float heading =MagnetoHeadingCompute (X、Y、Z、0、0);
    //将弧度转换为度
    标题=(标题*180)/PI;
    返回标题;
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Justin、

     TH 寄存器在器件中按 X、Z、Y 顺序排列? 请看下面的寄存器地址映射。 也许这就是原因。