我正在研究 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 个字节
然后这就是当我使用注释掉的位而不是 在所有字节都相同时返回数据时得到的