0

我正在研究 stm32f3discovery 并试图从板上的 l3gd20 陀螺仪读取数据。当我尝试从 OUT_X_L 到 OUT_Z_H 连续读取 6 个字节(这是用于从陀螺仪读取读数的所有数据)时,发送的前三个字节与发送的最后三个字节相同。

当我尝试单独读取每个寄存器时,所有字节都相同,我在示波器上检查过,寄存器在 MOSI 线上发生变化,但响应是 6 个重复字节。

WHO_AM_I 和 OUT_TEMP 寄存器都工作得很好,所以我知道实际的 SPI 不是问题。

这是任何适当的代码,任何帮助或正确方向的指示将不胜感激,谢谢。

Main.rs

#![no_std]
#![no_main]

extern crate panic_itm; // logs messages over ITM; requires ITM support

use cortex_m::{asm, iprintln, iprint, Peripherals as core_peripherals};
use cortex_m_rt::entry;
use cortex_m_semihosting::{debug, hprintln};
use stm32f3::stm32f303;

mod my_api;
mod sensor;


#[entry]
fn main() -> ! {
    let periph = stm32f303::Peripherals::take().unwrap();
    let mut core_p = core_peripherals::take().unwrap();

    let itm = &mut core_p.ITM.stim[0];


    let gpioa = periph.GPIOA;
    let gpioe = periph.GPIOE;
    let rcc = periph.RCC
    let flash = periph.FLASH;
    let spi1 = periph.SPI1;

    set_to_72MHz(&rcc, &flash);

    let spi = my_api::spi_mod::spi_func::new(&rcc, &gpioa, &gpioe, &spi1);

    let mut gyro = sensor::Gyro::gyro::new(&spi, &spi1).init(&spi, &spi1, &gpioe);

    loop {

        iprintln!(itm, "{:?}", gyro.read_data(&spi, &spi1, &gpioe));
    }
}

fn set_to_72MHz(rcc: &stm32f3::stm32f303::RCC, flash: &stm32f3::stm32f303::FLASH){
    rcc.cr.modify(|_,w| w.hseon().set_bit()); //turns on the external oscillator
    while rcc.cr.read().hserdy().bit_is_clear(){} //wait for it to be ready
    flash.acr.modify(|_,w| {
        w.prftbe().set_bit(); //turn on prefetch
        unsafe{w.latency().bits(0b010)} //set latency for 72MHz
    }); 

    rcc.cfgr.modify(|_,w| {
        w.pllxtpre().clear_bit();
        unsafe{w.pllsrc().bits(0b10)};
        w.pllmul().bits(0b0111);
        unsafe{w.hpre().bits(0b0000);
        w.ppre1().bits(0b100);
        w.ppre2().bits(0b000)}
    });

    rcc.cr.modify(|_,w| w.pllon().set_bit());
    while rcc.cr.read().pllrdy().bit_is_clear(){}

    rcc.cfgr.modify(|_,w| unsafe{w.sw().bits(0b10)});
    while rcc.cfgr.read().sws().bits() != 0b10{}
}

my_api.rs

    pub mod spi_mod{
    pub struct spi_func{}

    impl spi_func{
        pub fn new(rcc: &stm32f3::stm32f303::RCC, gpioa: &stm32f3::stm32f303::GPIOA, gpioe: &stm32f3::stm32f303::GPIOE, spi: &stm32f3::stm32f303::SPI1) -> Self {
            rcc.apb2enr.modify(|_,w| w.spi1en().set_bit()); //enable spi clock

            rcc.ahbenr.modify(|_,w| w.iopaen().set_bit()); // enable gpio clocks
            rcc.ahbenr.modify(|_,w| w.iopeen().set_bit());

            gpioe.moder.modify(|_,w| w.moder3().bits(0b01)); //CS pin
            gpioe.otyper.modify(|_,w| w.ot3().clear_bit());
            gpioe.odr.modify(|_,w| w.odr3().set_bit()); //bring pe3 high to disable gyro com

            // PA5 -> SCL  // PA6 -> MISO  // PA7 -> MOSI
            gpioa.moder.modify(|_,w| {
                w.moder5().bits(0b10); // output type
                w.moder6().bits(0b10);
                w.moder7().bits(0b10)});

            gpioa.otyper.modify(|_,w| {
                w.ot5().clear_bit();// push pull type
                w.ot6().clear_bit();
                w.ot7().clear_bit()});

            gpioa.ospeedr.modify(|_,w| {
                w.ospeedr5().bits(0b11);// fast mode
                w.ospeedr6().bits(0b11);
                w.ospeedr7().bits(0b11)});

            gpioa.afrl.modify(|_,w| {
                w.afrl5().bits(0b0101);//Alternate function 5
                w.afrl6().bits(0b0101);
                w.afrl7().bits(0b0101)
            });

            spi.cr1.modify(|_,w| {
                w.bidimode().clear_bit(); //bidirectional mode
                w.ssm().set_bit(); // hardware slave management disabled
                w.ssi().set_bit(); // slave not selected    -------------------------------
                w.br().bits(0b011); // bring rate from 72MHz to 72/16MHz = 4.5MHz as gyro cant go above 10MHz
                w.mstr().set_bit(); // set to master mode
                w.cpol().set_bit(); // set to mode 3 to work for the l3gd20
                w.cpha().set_bit()
            });

            spi.cr2.modify(|_,w| {
                //unsafe{w.ds().bits(0b0111)}; // data size = 8 bits
                w.errie().clear_bit();
                w.txeie().set_bit(); //enable interupt flags   
                w.rxneie().set_bit();
                w.ssoe().clear_bit() //set to single master mode
            });

            spi.cr1.modify(|_,w| w.spe().set_bit()); // enable spi

            spi_func{}

        }

        fn check_faults(&self, spi1: &stm32f3::stm32f303::SPI1) -> bool {
            if spi1.sr.read().ovr().bit_is_set(){ //checks through all the flags
                false
            }else if spi1.sr.read().modf().bit_is_set(){
                false
            }else if spi1.sr.read().crcerr().bit_is_set(){
                false
            }else if spi1.sr.read().udr().bit_is_set(){
                false
            } else {
                true
            }
        }

        pub fn write(&self, spi1: &stm32f3::stm32f303::SPI1, data: u16) {
            if self.check_faults(&spi1){
                spi1.dr.modify(|_,w| w.dr().bits(data)); //write to the dr register
                while spi1.sr.read().bsy().bit_is_set(){}
            }
        }

        pub fn read(&self, spi1: &stm32f3::stm32f303::SPI1) -> u8 {
            if self.check_faults(&spi1){
                while spi1.sr.read().bsy().bit_is_set(){}
                return (spi1.dr.read().dr().bits() >> 8) as u8 //read from the dr register
            }
            0

        }

        pub fn write_data(&self, spi1: &stm32f3::stm32f303::SPI1, reg_address: u8, data: u8) {
            let total_data: u16 = ((data as u16) << 8) + (reg_address as u16);
            self.write(&spi1, total_data);
        }

        pub fn read_register(&self, spi1: &stm32f3::stm32f303::SPI1, reg_address: u8) -> u8{
            self.write(&spi1, (reg_address | 0x80) as u16); //set the bit to read mode and send
            self.read(&spi1) //read the result
        }

        pub fn read_multiple_register(&self, spi1: &stm32f3::stm32f303::SPI1, reg_address: u8, rx_data: &mut [u8]){
            self.write(&spi1, (reg_address | 0x80 | 0x40) as u16);
            for d in rx_data.iter_mut(){
                self.write(&spi1, 0x00);
                *d = self.read(&spi1);
            }

        }

    }
}

传感器

    pub mod Gyro{
    pub use crate::my_api::spi_mod;
    const WHO_AM_I: u8 = 0x0F;
    const CTRL_REG1: u8 = 0x20;
    const CTRL_REG4: u8 = 0x23;
    const OUT_TEMP: u8 = 0x26;
    const OUT_X_L: u8 = 0x28;
    const OUT_X_H: u8 = 0x29;
    const OUT_Y_L: u8 = 0x2A;
    const OUT_Y_H: u8 = 0x2B;
    const OUT_Z_L: u8 = 0x2C;
    const OUT_Z_H: u8 = 0x2D;

    pub struct gyro{
        pub x: i16,
        pub y: i16,
        pub z: i16,
        offset_x: i32,
        offset_y: i32,
        offset_z: i32,
        pub temp: i8
    }

    impl gyro{
        pub fn new(my_spi_mod: &spi_mod::spi_func, spi1: &stm32f3::stm32f303::SPI1) -> Self {
            gyro{
                x: 0,
                y: 0,
                z: 0,
                offset_x: 0,
                offset_y: 0,
                offset_z: 0,
                temp: 0,
            }
        }

        pub fn init(self, spi: &spi_mod::spi_func, spi1: &stm32f3::stm32f303::SPI1, gpioe: &stm32f3::stm32f303::GPIOE) -> Self{
            self.cs_low(&gpioe);
            spi.write_data(&spi1, CTRL_REG1, 0x3F); //power on the gyro 
            self.cs_high(&gpioe);

            self.cs_low(&gpioe);
            spi.write_data(&spi1, CTRL_REG4, 0x10); //power on the gyro 
            self.cs_high(&gpioe);

            self
        }

        pub fn who_am_i(&self, spi: &spi_mod::spi_func, spi1: &stm32f3::stm32f303::SPI1, gpioe: &stm32f3::stm32f303::GPIOE) -> u8 {
            self.cs_low(&gpioe);
            let data = spi.read_register(&spi1, WHO_AM_I);
            self.cs_high(&gpioe);
            data
        }

        pub fn read_temp(&mut self, spi: &spi_mod::spi_func, spi1: &stm32f3::stm32f303::SPI1, gpioe: &stm32f3::stm32f303::GPIOE) {
            self.cs_low(&gpioe);
            self.temp = spi.read_register(&spi1, OUT_TEMP) as i8;
            self.cs_high(&gpioe);

        }


        pub fn read_data(&mut self, spi: &spi_mod::spi_func, spi1: &stm32f3::stm32f303::SPI1, gpioe: &stm32f3::stm32f303::GPIOE) -> [u8;6]{
            let mut data: [u8;6] = [0,0,0,0,0,0];

            self.cs_low(&gpioe);
            spi.read_multiple_register(&spi1, OUT_X_L, &mut data);

            // data[0] = spi.read_register(&spi1, OUT_X_L);
            // data[1] = spi.read_register(&spi1, OUT_X_H);

            // data[2] = spi.read_register(&spi1, OUT_Y_L);
            // data[3] = spi.read_register(&spi1, OUT_Y_H);

            // data[4] = spi.read_register(&spi1, OUT_Z_L);
            // data[5] = spi.read_register(&spi1, OUT_Z_H);

            self.cs_high(&gpioe);

            self.x = ((data[0] as u16) + ((data[1] as u16) << 8)) as i16;
            self.y = ((data[2] as u16) + ((data[3] as u16) << 8)) as i16;
            self.z = ((data[4] as u16) + ((data[5] as u16) << 8)) as i16;

            data            

        }

        fn cs_low(&self, gpioe: &stm32f3::stm32f303::GPIOE){
            gpioe.odr.modify(|_,w| w.odr3().clear_bit());
        }

        fn cs_high(&self, gpioe: &stm32f3::stm32f303::GPIOE){
            gpioe.odr.modify(|_,w| w.odr3().set_bit());
        }

    }
}

这是使用 sensor.rs -> read_data() -> spi.read_multiple_register(&spi1, OUT_X_L, &mut data); 时的结果。 从板返回数据,重复 3 个字节

然后这就是当我使用注释掉的位而不是 在所有字节都相同时返回数据时得到的

4

1 回答 1

0

您是否尝试过在 0x27H 使用 STATUS_REG?第 3.2 节 第 10 页

于 2020-06-13T10:22:38.857 回答