传感器知识库

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

Sensors Knowledge Base

讨论

排序依据:
All, We are busily working to integrate Version 7.00 of the sensor fusion library into the Kinetis Expert (KEX) ecosystem.  ETA is early August.  I have attached here a preview copy of the user manual for that release.  This is subject to the usual disclaimers: content subject to change, no liability, yada yada yada.  There are a LOT of changes.    These are documented ad nauseum in the user guide.  I've also added a lot of our old blog content into the user guide, as I keep getting requests for them.  Please take a look and give me your feedback.   FYI, Here is a sample main() for the new fusion, running on FreeRTOS:   /* FreeRTOS kernel includes. */ #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "timers.h" #include "event_groups.h" // KSDK and ISSDK Headers #include "fsl_debug_console.h"  // KSDK header file for the debug interface #include "board.h"              // KSDK header file to define board configuration #include "pin_mux.h"            // KSDK header file for pin mux initialization functions #include "clock_config.h"       // KSDK header file for clock configuration #include "fsl_port.h"           // KSDK header file for Port I/O control #include "fsl_i2c.h"            // KSDK header file for I2C interfaces #include "Driver_I2C_SDK2.h"    // ISSDK header file for CMSIS I2C Driver #include "fxas21002.h"          // register address and bit field definitions #include "mpl3115.h"            // register address and bit field definitions #include "fxos8700.h"           // register address and bit field definitions // Sensor Fusion Headers #include "sensor_fusion.h"      // top level magCal and sensor fusion interfaces #include "control.h"           // Command/Streaming interface - application specific #include "status.h"            // Sta:tus indicator interface - application specific #include "drivers.h"           // NXP sensor drivers OR customer-supplied drivers // Global data structures SensorFusionGlobals sfg;                ///< This is the primary sensor fusion data structure ControlSubsystem controlSubsystem;      ///< used for serial communications StatusSubsystem statusSubsystem;        ///< provides visual (usually LED) status indicator PhysicalSensor sensors[3];              ///< This implementation uses three physical sensors EventGroupHandle_t event_group = NULL; static void read_task(void *pvParameters);              // FreeRTOS Task definition static void fusion_task(void *pvParameters);            // FreeRTOS Task definition /// This is a FreeRTOS (dual task) implementation of the NXP sensor fusion demo build. int main(void) {     ARM_DRIVER_I2C* I2Cdrv = &I2C_S_DRIVER_BLOCKING;       // defined in the <shield>.h file     BOARD_InitPins();                   // defined in pin_mux.c, initializes pkg pins     BOARD_BootClockRUN();               // defined in clock_config.c, initializes clocks     BOARD_InitDebugConsole();           // defined in board.c, initializes the OpenSDA port     I2Cdrv->Initialize(NULL);                                 // Initialize the KSDK driver for the I2C port     I2Cdrv->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);      // Configure the I2C bus speed     initializeControlPort(&controlSubsystem);                           // configure pins and ports for the control sub-system     initializeStatusSubsystem(&statusSubsystem);                        // configure pins and ports for the status sub-system     initSensorFusionGlobals(&sfg, &statusSubsystem, &controlSubsystem); // Initialize sensor fusion structures     // "install" the sensors we will be using     sfg.installSensor(&sfg, &sensors[0], FXOS8700_I2C_ADDR, 1, (void*) I2Cdrv, FXOS8700_Init,  FXOS8700_Read);     sfg.installSensor(&sfg, &sensors[1], FXAS21002_I2C_ADDR, 1, (void*) I2Cdrv, FXAS21002_Init, FXAS21002_Read);     sfg.installSensor(&sfg, &sensors[2], MPL3115_I2C_ADDR, 2, (void*) I2Cdrv, MPL3115_Init, MPL3115_Read);     sfg.initializeFusionEngine(&sfg);         // This will initialize sensors and magnetic calibration     event_group = xEventGroupCreate();     xTaskCreate(read_task, "READ", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL);     xTaskCreate(fusion_task, "FUSION", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);     sfg.setStatus(&sfg, NORMAL);                // If we got this far, let's set status state to NORMAL     vTaskStartScheduler();                      // Start the RTOS scheduler     sfg.setStatus(&sfg, HARD_FAULT);            // If we got this far, FreeRTOS does not have enough memory allocated     for (;;) ; } static void read_task(void *pvParameters) {     uint16_t i=0;                       // general counter variable     portTickType lastWakeTime;     const portTickType frequency = 1;   // tick counter runs at the read rate     lastWakeTime = xTaskGetTickCount();     while (1)     {         for (i=1; i<=OVERSAMPLE_RATE; i++) {             vTaskDelayUntil(&lastWakeTime, frequency);             sfg.readSensors(&sfg, i);              // Reads sensors, applies HAL and does averaging (if applicable)         }         xEventGroupSetBits(event_group, B0);     } } static void fusion_task(void *pvParameters) {     uint16_t i=0;  // general counter variable     while (1)     {         xEventGroupWaitBits(event_group,    /* The event group handle. */                             B0,             /* The bit pattern the event group is waiting for. */                             pdTRUE,         /* BIT_0 and BIT_4 will be cleared automatically. */                             pdFALSE,        /* Don't wait for both bits, either bit unblock task. */                             portMAX_DELAY); /* Block indefinitely to wait for the condition to be met. */         sfg.conditionSensorReadings(&sfg);  // magCal is run as part of this         sfg.runFusion(&sfg);                // Run the actual fusion algorithms         sfg.applyPerturbation(&sfg);        // apply debug perturbation (testing only)         sfg.loopcounter++;                  // The loop counter is used to "serialize" mag cal operations         i=i+1;         if (i>=4) {                         // Some status codes include a "blink" feature.  This loop                 i=0;                        // should cycle at least four times for that to operate correctly.                 sfg.updateStatus(&sfg);     // This is where pending status updates are made visible         }         sfg.queueStatus(&sfg, NORMAL);      // assume NORMAL status for next pass through the loop         sfg.pControlSubsystem->stream(&sfg, sUARTOutputBuffer);      // Send stream data to the Sensor Fusion Toolbox     } } /// \endcode
查看全文
        The FXTH87xx is a sensor for use in applications that monitor tire pressure and temperature. It contains the pressure and temperature sensors, an X-axis and a Z-axis accelerometer, a microcontroller, an LF receiver and an RF transmitter all within a single package.        Recently a customer requests help to connect FXTH87xx with Infineon TPMS receiver. We connect them each other through some testing and verification finally. The target of this document description is to replace external emitter with FXTH87xx. This document take an example to offer the users a method how to detect and decode an unknown sensor Emitter Packets using instrument provided by R&S or Anritsu, then duplicate this Emitter packets into FXTH87xx to form 315MHz, 433.92MHz TPMS emitter and receiver solution. Customer who adapts FXTH87xx can easily connect it with any external receiver using the similiar concept.
查看全文
         The FXTH87XXX is a sensor for use in applications that monitor tire pressure and temperature. It contains the pressure and temperature sensors, an X-axis and a Z-axis accelerometer, a microcontroller, an LF receiver and an RF transmitter all within a single package.          NCK2912 is a fully integrated single-chip receiver for use in an automotive environment. The device incorporated several commonly used building blocks including a crystal stabilized oscillator, a fractional-N based Phase Locked Loop(PLL) for a accurate frequency selection, Low Noise Amplifier(LNA), attenuator for Automatic Gain Control(AGC), I/Q down-mixer and two high resolution Analog to Digital Converters(ADC). By transforming signals in the digital domain in an early phase, one highly configurable RX channel is available including channel filter, ASK/FSK demodulator, clock-data recovery, bit processor and a micro-controller memory interface(DMA) allowing the micro-controller to complete the data handling and handshaking. NCK2912 has an embedded RISC micro-controller optimized for high performance and low power as well as an EROM for customer application.         
查看全文
All, We've had some problems with migration of Freescale blogs over to the NXP domain.  One set of listings that gets requested a fair bit are the postings on orientation representations.  The attached is a PDF version of the same material which will be contained in the upcoming Sensor Fusion Version 7.00 User Guide.
查看全文
You will have to add a .exe extension to the unzipped file.
查看全文
I am occasionally asked for the source code for the Android version of our Sensor Fusion Toolbox.  Well, here it is, complete with new NXP graphics and updated links.
查看全文
All, This is my personal "cheat sheet" that I use as reference whenever I have to code angular transformations from one frame of reference to another.  There's nothing unique here, it just organizes things in a way that I can find them quickly.  I hope you find it useful. Mike
查看全文
Hello community, As continuation of the Different pin styles in pressure sensors post, I would like to add some useful information about the pin styles mentioned on the datasheets. Some pressure sensors shows the following pin style configuration: But… What do V1, V2 and VEx actually mean? How should I connect those pins? Answer: V1, V2 and VEX pins are used for factory trimming and it is recommended to leave these pins unconnected. So, in case of unibody package, you will require only pin #1 (Vout), pin #2 (Ground), and pin #3 (Vs) as follow: I hope you find useful this information. Regards, David
查看全文
Hello community, As we know, The MMA8451Q has embedded single/double and directional tap detection. This post describes an example project using the Single Tap detection for the MMA8451Q included on the FRDM-KL25Z. Figure 1. Depending on the tapping direction, positive or negative of each axis, the RGB LED will turn into a different color. For more detailed information on how to configure the device for tap detection please refer to NXP application note, AN4072. Configuring the MCU Enable the I2C module of the KL25Z MCU and turn on all the corresponding clocks. In this case, the INT1 output of the MMA8451Q is connected to the PTA14 pin and both SCL and SDA lines are connected to the I2C0 module (PTE24 and PTE25 pins). Please review the FRDM-KL25Z schematic.      //I2C0 module initialization        SIM_SCGC4 |= SIM_SCGC4_I2C0_MASK;        // Turn on clock to I2C0 module        SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK;       // Turn on clock to Port E module        PORTE_PCR24 = PORT_PCR_MUX(5);           // PTE24 pin is I2C0 SCL line        PORTE_PCR25 = PORT_PCR_MUX(5);           // PTE25 pin is I2C0 SDA line        I2C0_F = 0x14;                           // SDA hold time = 2.125us, SCL start hold time = 4.25us, SCL stop hold time = 5.125us *        I2C0_C1 = I2C_C1_IICEN_MASK;             // Enable I2C0 module                   //Configure the PTA14 pin (connected to the INT1 of the MMA8451Q) for falling edge interrupts        SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;       // Turn on clock to Port A module        PORTA_PCR14 |= (0|PORT_PCR_ISF_MASK|     // Clear the interrupt flag        PORT_PCR_MUX(0x1)|           // PTA14 is configured as GPIO        PORT_PCR_IRQC(0xA));         // PTA14 is configured for falling edge interrupts                   //Enable PORTA interrupt on NVIC        NVIC_ICPR |= 1 << ((INT_PORTA - 16)%32);        NVIC_ISER |= 1 << ((INT_PORTA - 16)%32); Configure the RBG LED of the FRDM-KL25Z Based on FRDM-KL25Z User's Manual , the RGB LED signals are connected as follow: The pins mentioned, are configured as output.      //Configure PTB18, PTB19 and PTD1 as output for the RGB LED        SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK;    // Turn on clock to Port B module        SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK;    // Turn on clock to Port D module                   PORTB_PCR18 |= PORT_PCR_MUX(0x1);     // PTB18 is configured as GPIO        PORTB_PCR19 |= PORT_PCR_MUX(0x1);     // PTB19 is configured as GPIO        PORTD_PCR1 |= PORT_PCR_MUX(0x1);      // PTD1 is configured as GPIO                   GPIOB_PDDR |= (1 << 18);              //Port Data Direction Register (GPIOx_PDDR)        GPIOB_PDDR |= (1 << 19);              //Set GPIO direction set bit corresponding bit on the direction        GPIOD_PDDR |= (1 << 1);               //register for each port, set the bit means OUTPUT Initialize and configure the MMA8451Q for Tap Detection To utilize the single and/or double tap detection the following eight (8) registers must be configured. Register 0x21: PULSE_CFG Pulse Configuration Register Register 0x22: PULSE_SRC Pulse Source Register Register 0x23 - 0x25: PULSE_THSX,Y,Z Pulse Threshold for X, Y and Z Registers Register 0x26: PULSE_TMLT Pulse Time Window 1 Register Register 0x27: PULSE_LTCY Pulse Latency Timer Register Register 0x28: PULSE_WIND Second Pulse Time Window Register Please review the MMA8451Q datasheet in order to get more information about the registers mentioned. For a single tap event, the PULSE_TMLT, PULSE_THSX/Y/Z and PULSE_LTCY registers are key parameters to consider. Note in condition (a) the interrupt is asserted since the acceleration due to a pulse exceeds the specified acceleration threshold (value set in the PULSE_THSX) and crosses up and down before the specified Pulse Time Limit (value set in PULSE_TMLT) expires. Note that in condition (b) the acceleration due to a pulse exceeds the specified acceleration threshold limit, but does not go below the threshold before the specified Pulse Time Limit expires. Therefore, this is an invalid pulse and the interrupt will not be triggered. Also note that the Latency is not shown for this example.              unsigned char reg_val = 0, CTRL_REG1_val = 0;            I2C_WriteRegister(MMA845x_I2C_ADDRESS, CTRL_REG2, 0x40);             // Reset all registers to POR values                 do            // Wait for the RST bit to clear        {               reg_val = I2C_ReadRegister(MMA845x_I2C_ADDRESS, CTRL_REG2) & 0x40;        }      while (reg_val);            I2C_WriteRegister(MMA845x_I2C_ADDRESS, CTRL_REG1, 0x0C);             // ODR = 400Hz, Reduced noise, Standby mode        I2C_WriteRegister(MMA845x_I2C_ADDRESS, XYZ_DATA_CFG_REG, 0x00);      // +/-2g range -> 1g = 16384/4 = 4096 counts        I2C_WriteRegister(MMA845x_I2C_ADDRESS, CTRL_REG2, 0x02);             // High Resolution mode            I2C_WriteRegister(MMA845x_I2C_ADDRESS, PULSE_CFG_REG, 0x15);         //Enable X, Y and Z Single Pulse        I2C_WriteRegister(MMA845x_I2C_ADDRESS, PULSE_THSX_REG, 0x20);        //Set X Threshold to 2.016g        I2C_WriteRegister(MMA845x_I2C_ADDRESS, PULSE_THSY_REG, 0x20);        //Set Y Threshold to 2.016g        I2C_WriteRegister(MMA845x_I2C_ADDRESS, PULSE_THSZ_REG, 0x2A);        //Set Z Threshold to 2.646g        I2C_WriteRegister(MMA845x_I2C_ADDRESS, PULSE_TMLT_REG, 0x28);        //Set Time Limit for Tap Detection to 25 ms        I2C_WriteRegister(MMA845x_I2C_ADDRESS, PULSE_LTCY_REG, 0x28);        //Set Latency Time to 50 ms        I2C_WriteRegister(MMA845x_I2C_ADDRESS, CTRL_REG4, 0x08);             //Pulse detection interrupt enabled        I2C_WriteRegister(MMA845x_I2C_ADDRESS, CTRL_REG5, 0x08);             //Route INT1 to system interrupt            CTRL_REG1_val = I2C_ReadRegister(MMA845x_I2C_ADDRESS, CTRL_REG1);   //Active Mode        CTRL_REG1_val |= 0x01;        I2C_WriteRegister(MMA845x_I2C_ADDRESS, CTRL_REG1, CTRL_REG1_val); Handle the Interrupt The PULSE_SRC register indicates a double or single pulse event has occurred and also which direction. In this case the value of the register mentioned is passed to the PULSE_SRC_val variable and evaluated. Reading the PULSE_SRC register clears all bits. Reading the source register will clear the interrupt.      void PORTA_IRQHandler()      {             PORTA_PCR14 |= PORT_PCR_ISF_MASK;               // Clear the interrupt flag              PULSE_SRC_val = I2C_ReadRegister(MMA845x_I2C_ADDRESS, PULSE_SRC_REG); //Read Pulse Source Register      } Please find attached the complete source code written in the CodeWarrior for Microcontrollers-Eclipse IDE|NXP . As I mentioned before, you can find more detailed information at application note AN4072. Useful information about handling the MMA8451 can be founded in MMA8451Q - Bare metal example project. I hope you find useful and funny this sample project. Regards, David
查看全文
List of software examples published by NXP technical support: Sensors software examples published by NXP technical support * List of breakout boards designed by NXP technical support: Freescale Sensors Breakout Boards Designs – HOME * All of the source code placed in spaces above is for example use only. NXP does not accept liability for use of this code in the user’s application.
查看全文
Attached is a PDF dump of a classic blog post.  Please forgive the format problems.  I'll work with the web team in January to get it reposted to the NXP site. Mike
查看全文
The following video shows how to run the FRDM 6DOF Bare Board eCompass using the FRDM-K22. This algorithm uses the FXOS8700 contained on the Freedom Board. In order to get more information about the Sensor Fusion Library for Kinetis MCU's 5.0, please refer to the following link: Sensor Fusion|Freescale I hope this material will be useful for you. David
查看全文
This is a step-by-step guide document to set the FRDM-K64F-AGM01 on the Freescale Sensor Fusion Toolbox Software.
查看全文
The attached is the windows installer for the latest verson of the Windows version of the Freescale Sensor Fusion Toolbox.  This version must be used with Version 5.00 of the sensor fusion library.  It is NOT backward compatible, as the structure of the undocumented Kalman filter packet has changed. Please uninstall any prior versions of the toolbox before running this installer. As in prior releases, you can reflash your Freedom boards from within the application itself.  So if you want to try the new fusion without downloading the new library and firing up KDS or CodeWarrior, you can. Version 5.00 was posted to this same board just a few minutes ago in a separate post.  It contains full documentation, including algorithm development, datasheet and user guide. Regards, Mike Stanley
查看全文
You saw it here first! The attached zip file contains full documentation and source code (both CodeWarrior and KDS) for Version 5 of Freescale's Sensor Fusion Library for Kinetis MCUs. The 6 and 9-axis Kalman filters have been rewritten from scratch by fusion expert Mark Pedley.  The new versions have improved dynamic tracking and at-rest stability.  All documentation has been updated, and full implementation details are included.  We continue to use the BSD 3-clause software license, so you are virtually unlimited in how you use the library.   I will note that due to the Kalman filter changes, Mark made some changes to the undocumented Kalman filter packets which are utilized by the Windows Version of the Freescale Sensor Fusion Toolbox.  This breaks compatibility with older versions of the toolbox.  I will be posting a pre-release of the new one immediately after completing this post.  The Android version of the toolbox does not make use of the Kalman filter packet, and should be forward compatible - although an updated version of that is in the works as well.   Structure of the new library is very similar to Version 4.22, which was the previous production version.  There are changes, but I don't expect anyone to have problems adapting existing projects to the new version of the library.  I think you will get improved performance if you do.   Regards, Mike Stanley
查看全文
Hi Everyone, In this tutorial I intend to run through my simple bare metal example code I created for the Freescale FRDM-KL25Z platform and the FRDM-STBC-AGM01 board containing a three axis accelerometer + magnetometer (FXOS8700CQ) and a three axis gyroscope (FXAS21002C). I will not cover the Sensor Fusion library and the ISF which also support this board. The FreeMASTER tool is used to visualize all the data that are read from both sensors using an interrupt technique through the I 2 C interface. This example illustrates: 1. Initialization of the MKL25Z128 MCU (mainly I 2 C and PORT modules). 2. I 2 C data write and read operations. 3. Initialization of the FXOS8700CQ and FXAS21002C. 4. Simple accelerometer offset calibration based on the AN4069. 5. Output data reading using an interrupt technique. 6. Conversion of the output raw values to real values in g’s, µT, dps and °C. 7. Visualization of the calculated values in the FreeMASTER tool. 1. As you can see in the FRDM-STBC-AGM01 schematic, both sensors are controlled via I 2 C by default. With jumpers J6 and J7 in their default position (2-3), the I 2 C signals are routed to the I2C1 module (PTC1 and PTC2 pins) of the KL25Z MCU. The INT1_8700 output is connected to the PTD4 pin and the INT1_21002 pin to the PTA5 pin of the KL25Z MCU. These both interrupt pins are configured as push-pull active-low outputs, so the corresponding PTD4/PTA5 pin configuration is GPIO with an interrupt on falling edge. The MCU is, therefore, configured as follows. void MCU_Init(void) {      //I2C1 module initialization      SIM_SCGC4 |= SIM_SCGC4_I2C1_MASK;        // Turn on clock to I2C1 module      SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK;       // Turn on clock to Port C module      PORTC_PCR1 |= PORT_PCR_MUX(0x2);         // PTC1 pin is I2C1 SCL line      PORTC_PCR2 |= PORT_PCR_MUX(0x2);         // PTC2 pin is I2C1 SDA line      I2C1_F  |= I2C_F_ICR(0x14);              // SDA hold time = 2.125us, SCL start hold time = 4.25us, SCL stop hold time = 5.125us      I2C1_C1 |= I2C_C1_IICEN_MASK;            // Enable I2C1 module                       //Configure the PTD4 pin (connected to the INT1 of the FXOS8700CQ) for falling edge interrupts      SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK;       // Turn on clock to Port D module      PORTD_PCR4 |= (0|PORT_PCR_ISF_MASK|      // Clear the interrupt flag                       PORT_PCR_MUX(0x1)|      // PTD4 is configured as GPIO                       PORT_PCR_IRQC(0xA));    // PTD4 is configured for falling edge interrupts                   //Configure the PTA5 pin (connected to the INT1 of the FXAS21002) for falling edge interrupts      SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;       // Turn on clock to Port A module      PORTA_PCR5 |= (0|PORT_PCR_ISF_MASK|      // Clear the interrupt flag                       PORT_PCR_MUX(0x1)|      // PTA5 is configured as GPIO                       PORT_PCR_IRQC(0xA));    // PTA5 is configured for falling edge interrupts                          //Enable PORTD interrupt on NVIC      NVIC_ICPR |= 1 << ((INT_PORTD - 16)%32);      NVIC_ISER |= 1 << ((INT_PORTD - 16)%32);                //Enable PORTA interrupt on NVIC      NVIC_ICPR |= 1 << ((INT_PORTA - 16)%32);      NVIC_ISER |= 1 << ((INT_PORTA - 16)%32); } 2. The 7-bit I 2 C slave address of the FXOS8700CQ is 0x1E since both SA0 and SA1 pins are shorted to GND. The address of the FXAS21002C is 0x20 since SA0 pin is also shorted to GND. The two screenshots below show the write operation which writes the value 0x25 to the CTRL_REG1 (0x2A) of the FXOS8700CQ and 0x16 to the CTRL_REG1 (0x13) of the FXAS21002C. Here is the single byte read from the WHO_AM_I register. As you can see, it returns the correct value 0xC7 for the FXOS8700CQ and 0xD7 for the FXAS21002C. Finally, a burst read of 12 bytes from the FXOS8700CQ output data registers (0x01 – 0x06 and 0x33 – 0x38) and 6 bytes from the FXAS21002C output data registers (0x01 – 0x06) is shown below. 3. At the beginning of the initialization, all registers are reset to their default values by setting the RST bit of the CTRL_REG2 register. Then the FXOS8700CQ is initialized as shown below. void FXOS8700CQ_Init (void) {      I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, CTRL_REG2, 0x40);          // Reset all registers to POR values      Pause(0x631);          // ~1ms delay            I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, XYZ_DATA_CFG_REG, 0x00);   // +/-2g range with 0.244mg/LSB              I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, M_CTRL_REG1, 0x1F);        // Hybrid mode (accelerometer + magnetometer), max OSR      I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, M_CTRL_REG2, 0x20);        // M_OUT_X_MSB register 0x33 follows the OUT_Z_LSB register 0x06 (burst read)                       I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, CTRL_REG2, 0x02);          // High Resolution mode      I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, CTRL_REG3, 0x00);          // Push-pull, active low interrupt      I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, CTRL_REG4, 0x01);          // Enable DRDY interrupt      I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, CTRL_REG5, 0x01);          // DRDY interrupt routed to INT1 - PTD4      I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, CTRL_REG1, 0x25);          // ODR = 25Hz, Reduced noise, Active mode   } And here is the initialization of the FXAS21002C. void FXAS21002C_Init (void) {      I2C_WriteRegister(FXAS21002C_I2C_ADDRESS, GYRO_CTRL_REG1, 0x40);     // Reset all registers to POR values      Pause(0x631);        // ~1ms delay            I2C_WriteRegister(FXAS21002C_I2C_ADDRESS, GYRO_CTRL_REG0, 0x03);     // High-pass filter disabled, +/-250 dps range -> 7.8125 mdps/LSB = 128 LSB/dps      I2C_WriteRegister(FXAS21002C_I2C_ADDRESS, GYRO_CTRL_REG2, 0x0C);     // Enable DRDY interrupt, routed to INT1 - PTA5, push-pull, active low interrupt      I2C_WriteRegister(FXAS21002C_I2C_ADDRESS, GYRO_CTRL_REG1, 0x16);     // ODR = 25Hz, Active mode        } 4. A simple accelerometer offset calibration method is implemented according to the AN4069. void FXOS8700CQ_Accel_Calibration (void) {      char X_Accel_offset, Y_Accel_offset, Z_Accel_offset;            FXOS8700CQ_DataReady = 0;           while (!FXOS8700CQ_DataReady){}           // Is a first set of data ready?      FXOS8700CQ_DataReady = 0;            I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, CTRL_REG1, 0x00);          // Standby mode                 I2C_ReadMultiRegisters(FXOS8700CQ_I2C_ADDRESS, OUT_X_MSB_REG, 6, AccelMagData);          // Read data output registers 0x01-0x06                     Xout_Accel_14_bit = ((short) (AccelMagData[0]<<8 | AccelMagData[1])) >> 2;          // Compute 14-bit X-axis acceleration output value      Yout_Accel_14_bit = ((short) (AccelMagData[2]<<8 | AccelMagData[3])) >> 2;          // Compute 14-bit Y-axis acceleration output value      Zout_Accel_14_bit = ((short) (AccelMagData[4]<<8 | AccelMagData[5])) >> 2;          // Compute 14-bit Z-axis acceleration output value                   X_Accel_offset = Xout_Accel_14_bit / 8 * (-1);          // Compute X-axis offset correction value      Y_Accel_offset = Yout_Accel_14_bit / 8 * (-1);          // Compute Y-axis offset correction value      Z_Accel_offset = (Zout_Accel_14_bit - SENSITIVITY_2G) / 8 * (-1);          // Compute Z-axis offset correction value                   I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, OFF_X_REG, X_Accel_offset);                  I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, OFF_Y_REG, Y_Accel_offset);           I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, OFF_Z_REG, Z_Accel_offset);                        I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, CTRL_REG1, 0x25);          // Active mode again } 5. In the ISRs, only the interrupt flags are cleared and the DataReady variables are set to indicate the arrival of new data. void PORTD_IRQHandler() {      PORTD_PCR4 |= PORT_PCR_ISF_MASK;          // Clear the interrupt flag      FXOS8700CQ_DataReady = 1;  } void PORTA_IRQHandler() {      PORTA_PCR5 |= PORT_PCR_ISF_MASK;          // Clear the interrupt flag      FXAS21002C_DataReady = 1;  } 6. The output values from accelerometer registers 0x01 – 0x06 are first converted to signed 14-bit integer values and afterwards to real values in g’s. Similarly, the output values from magnetometer registers 0x33 – 0x38 are first converted to signed 16-bit integer values and afterwards to real values in microtesla (µT). if (FXOS8700CQ_DataReady)          // Is a new set of accel + mag data ready? {                  FXOS8700CQ_DataReady = 0;                                                                                                                          I2C_ReadMultiRegisters(FXOS8700CQ_I2C_ADDRESS, OUT_X_MSB_REG, 12, AccelMagData);         // Read FXOS8700CQ data output registers 0x01-0x06 and 0x33 - 0x38                     // 14-bit accelerometer data      Xout_Accel_14_bit = ((short) (AccelMagData[0]<<8 | AccelMagData[1])) >> 2;        // Compute 14-bit X-axis acceleration output value      Yout_Accel_14_bit = ((short) (AccelMagData[2]<<8 | AccelMagData[3])) >> 2;        // Compute 14-bit Y-axis acceleration output value      Zout_Accel_14_bit = ((short) (AccelMagData[4]<<8 | AccelMagData[5])) >> 2;        // Compute 14-bit Z-axis acceleration output value                              // Accelerometer data converted to g's      Xout_g = ((float) Xout_Accel_14_bit) / SENSITIVITY_2G;        // Compute X-axis output value in g's      Yout_g = ((float) Yout_Accel_14_bit) / SENSITIVITY_2G;        // Compute Y-axis output value in g's      Zout_g = ((float) Zout_Accel_14_bit) / SENSITIVITY_2G;        // Compute Z-axis output value in g's                               // 16-bit magnetometer data                   Xout_Mag_16_bit = (short) (AccelMagData[6]<<8 | AccelMagData[7]);          // Compute 16-bit X-axis magnetic output value      Yout_Mag_16_bit = (short) (AccelMagData[8]<<8 | AccelMagData[9]);          // Compute 16-bit Y-axis magnetic output value      Zout_Mag_16_bit = (short) (AccelMagData[10]<<8 | AccelMagData[11]);        // Compute 16-bit Z-axis magnetic output value                                                         // Magnetometer data converted to microteslas      Xout_uT = (float) (Xout_Mag_16_bit) / SENSITIVITY_MAG;        // Compute X-axis output magnetic value in uT      Yout_uT = (float) (Yout_Mag_16_bit) / SENSITIVITY_MAG;        // Compute Y-axis output magnetic value in uT      Zout_uT = (float) (Zout_Mag_16_bit) / SENSITIVITY_MAG;        // Compute Z-axis output magnetic value in uT              } Similarly, the output values from gyroscope registers 0x01 – 0x06 are first converted to signed 16-bit integer values and afterwards to real values in degrees per second. Temperature is also read out from the 0x12 register. if (FXAS21002C_DataReady)         // Is a new set of gyro data ready? {                  FXAS21002C_DataReady = 0;                                                                                                                                       I2C_ReadMultiRegisters(FXAS21002C_I2C_ADDRESS, GYRO_OUT_X_MSB_REG, 6, GyroData);         // Read FXAS21002C data output registers 0x01-0x06                                   // 16-bit gyro data      Xout_Gyro_16_bit = (short) (GyroData[0]<<8 | GyroData[1]);           // Compute 16-bit X-axis output value      Yout_Gyro_16_bit = (short) (GyroData[2]<<8 | GyroData[3]);           // Compute 16-bit Y-axis output value      Zout_Gyro_16_bit = (short) (GyroData[4]<<8 | GyroData[5]);           // Compute 16-bit Z-axis output value                                           // Gyro data converted to dps      Roll = (float) (Xout_Gyro_16_bit) / SENSITIVITY_250;          // Compute X-axis output value in dps      Pitch = (float) (Yout_Gyro_16_bit) / SENSITIVITY_250;         // Compute Y-axis output value in dps      Yaw = (float) (Zout_Gyro_16_bit) / SENSITIVITY_250;           // Compute Z-axis output value in dps                               // Temperature data      Temp = I2C_ReadRegister(FXAS21002C_I2C_ADDRESS, GYRO_TEMP_REG);                   }   7. The calculated values can be watched in the "Variables" window on the top right of the Debug perspective or in the FreeMASTER application. To open and run the FreeMASTER project, install the FreeMASTER application​ and FreeMASTER Communication Driver. I guess this is enough to let you start experimenting with the FRDM-STBC-AGM01 board. Attached you can find the complete source code written in the CW for MCU's v10.6 including the FreeMASTER project. If there are any questions regarding this simple application, do not hesitate to ask below. Your feedback or suggestions are also welcome. Regards, Tomas
查看全文
Hi Everyone, As I am often asked for a simple bare metal example code illustrating the use of the accelerometer vector-magnitude function, I have decided to share here one of my examples I created for the FXLS8471Q accelerometer while working with the Freescale FRDM-KL25Z platform and FRDM-FXS-MULT2-B sensor expansion board. This example code complements the Python code snippet from the AN4692. The FXLS8471Q is set for detection of a change in tilt angle exceeding 17.25° from the horizontal plane. Once an event is triggered, an interrupt will be generated on the INT1 pin: void FXLS8471Q_Init (void) {      FXLS8471Q_WriteRegister(A_VECM_THS_MSB_REG, 0x84);            // Threshold value set to 300mg or ~17.25°    FXLS8471Q_WriteRegister(A_VECM_THS_LSB_REG, 0xCC);          FXLS8471Q_WriteRegister(A_VECM_CNT_REG, 0x01);                // Debounce timer period set to 80ms          FXLS8471Q_WriteRegister(A_VECM_INITX_MSB_REG, 0x00);    FXLS8471Q_WriteRegister(A_VECM_INITX_LSB_REG, 0x00);    FXLS8471Q_WriteRegister(A_VECM_INITY_MSB_REG, 0x00);    FXLS8471Q_WriteRegister(A_VECM_INITY_LSB_REG, 0x00);    FXLS8471Q_WriteRegister(A_VECM_INITZ_MSB_REG, 0x10);          // Set Z-axis to 1g  as a reference value    FXLS8471Q_WriteRegister(A_VECM_INITZ_LSB_REG, 0x00);          FXLS8471Q_WriteRegister(A_VECM_CFG_REG, 0x78);                // Event latch enabled, A_VECM_INITX/Y/Z used as initial reference, acceleration vector-magnitude detection feature enabled          FXLS8471Q_WriteRegister(CTRL_REG4, 0x02);                     // Acceleration vector-magnitude interrupt enabled    FXLS8471Q_WriteRegister(CTRL_REG5, 0x02);                     // Acceleration vector-magnitude interrupt routed to INT1 - PTA5          FXLS8471Q_WriteRegister(CTRL_REG1, 0x29);                     // ODR = 12.5Hz, Active mode } In the ISR, only the interrupt flag is cleared and the  INT_SOURCE (0x0C) register is read in order to clear the SRC_A_VECM status bit and deassert the INT1 pin, as shown on the screenshot below. void PORTA_IRQHandler() {    PORTA_PCR5 |= PORT_PCR_ISF_MASK;                              // Clear the interrupt flag    IntSource = FXLS8471Q_ReadRegister(INT_SOURCE_REG);           // Read the INT_SOURCE register to clear the SRC_A_VECM bit   } Attached you can find the complete source code. If there are any questions regarding this simple example code, please feel free to ask below. Your feedback or suggestions are also welcome. Regards, Tomas
查看全文
clicktaleID