OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5208|回复: 2

stm32f103通过SPI提取惯导数据

[复制链接]

1

主题

1

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2021-7-31
在线时间
1 小时
发表于 2021-8-16 17:44:12 | 显示全部楼层 |阅读模式
2金钱
各位大佬们,就剩两个金币了,帮帮忙,倾家荡产了。感谢🙏
目前有一个项目是使用stm32f103rct6这块板子,通过SPI进行提取惯导的数据,而目前所遇到的问题就是,要是想提取惯导数据就要通过SPI向惯导发送一个操作码让它进入配置模式,然后发送操作码进行配置,再发送测量操作码返回数据,进入配置的操作码是5个16进制数字:FA FF 30 00 D1,而正常返回的数据应该是FA FF 31 00 D0。我使用SPI一个一个发送到惯导后,发现返回的数据是不对的返回的是一串二进制,而且转化为16进制也不是FA FF等那一串指令码,但是在串口助手通过USB发送这一串数字是可以返回正常数据的,我想问问SPI发送怎么写才可以一下传5个16进制返回出正常的数据。或者说根本不是这个原因。---------------------------------------------------------------
下面是代码
---------------------------------------------------------------

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"         
#include "can.h"
#include "beep.h"

u8 data;

//led延时
void Delay(u32 count)
{
   u32 i=0;
   for(;i<count;i++);
}



//led初始设置
void led_test(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
         
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|
  RCC_APB2Periph_GPIOE, ENABLE);          
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                          
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         
  GPIO_Init(GPIOB, &GPIO_InitStructure);                             
  GPIO_SetBits(GPIOB,GPIO_Pin_5);                               
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                   
  GPIO_Init(GPIOE, &GPIO_InitStructure);                         
  GPIO_SetBits(GPIOE,GPIO_Pin_5);

}

void SPI2_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;

        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能
        RCC_APB1PeriphClockCmd(        RCC_APB1Periph_SPI2,  ENABLE );//SPI2时钟使能        

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //PB13/14/15复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB

        GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);  //PB13/14/15上拉

        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                //设置SPI工作模式:设置为主SPI
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                //设置SPI的数据大小:SPI发送接收8位帧结构
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                //串行同步时钟的空闲状态为高电平
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;        //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;                //定义波特率预分频的值:波特率预分频值为256
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
        SPI_InitStructure.SPI_CRCPolynomial = 7;        //CRC值计算的多项式
        SPI_Init(SPI2, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器

        SPI_Cmd(SPI2, ENABLE); //使能SPI外设
                 


}   

//SPI 速度设置函数
//SpeedSet:
//SPI_BaudRatePrescaler_2   2分频   
//SPI_BaudRatePrescaler_8   8分频   
//SPI_BaudRatePrescaler_16  16分频  
//SPI_BaudRatePrescaler_256 256分频

void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler)
{
  assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
        SPI2->CR1&=0XFFC7;
        SPI2->CR1|=SPI_BaudRatePrescaler;        //设置SPI2速度
        SPI_Cmd(SPI2,ENABLE);

}

//SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI2_ReadWriteByte(u8 TxData)
{               
        u8 retry=0;                                        
        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
                {
                retry++;
                if(retry>20)return 0;
                }                          
        SPI_I2S_SendData(SPI2, TxData); //通过外设SPIx发送一个数据
        retry=0;

        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
                {
                retry++;
                if(retry>20)return 0;
                }                                                              
        return SPI_I2S_ReceiveData(SPI2); //返回通过SPIx最近接收的数据                                            
}
void XX_Init(void)
{       
  GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;  // PB12 推挽
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_SetBits(GPIOB,GPIO_Pin_12);
        SPI2_Init();                           //初始化SPI
        SPI2_SetSpeed(SPI_BaudRatePrescaler_128);//设置为18M时钟,高速模式

}  
/*
u8 ReadSR(u16 word)   
{  
        u8 byte=0;   
        GPIO_ResetBits( GPIOB, GPIO_Pin_12 );                          //使能器件   
        SPI2_ReadWriteByte(word); //发送读取状态寄存器命令
        byte=SPI2_ReadWriteByte(0xff);          //读取一个字节  
        GPIO_SetBits( GPIOB, GPIO_Pin_12 );                          //取消片选     
        return byte;   
}
*/

int main(void)
{       
         

        u8 i2;
//        u8 i1;
         
        delay_init();                     //延时函数初始化          
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
        uart_init(11500);                 //串口初始化为115200
        LED_Init();                                  //初始化与LED连接的硬件接口
        LCD_Init();                                   //初始化LCD       
        KEY_Init();                                //按键初始化                 
        led_test();               
        SPI2_Init();
        XX_Init();
                /*                       
                                          GPIO_ResetBits( GPIOB, GPIO_Pin_12 );
                                        SPI2_ReadWriteByte(0xFA);
                                        SPI2_ReadWriteByte(0xFF);
                                        SPI2_ReadWriteByte(0x10);
                                        SPI2_ReadWriteByte(0x00);
                                        SPI2_ReadWriteByte(0xF1);
                                        GPIO_SetBits( GPIOB, GPIO_Pin_12 );                          //取消片选
        */

         
                                        GPIO_ResetBits( GPIOB, GPIO_Pin_12 );
                                        data=SPI2_ReadWriteByte(0xFA);
                                  LCD_ShowxNum(20+1*32,30+i2*20,data,3,16,0X80);        //显示数据
                                        data=SPI2_ReadWriteByte(0xFF);
                                  LCD_ShowxNum(20+2*32,30+i2*20,data,3,16,0X80);        //显示数据
                                        data=SPI2_ReadWriteByte(0x30);
                                  LCD_ShowxNum(20+3*32,30+i2*20,data,3,16,0X80);        //显示数据
                                        data=SPI2_ReadWriteByte(0x00);
                                  LCD_ShowxNum(20+4*32,30+i2*20,data,3,16,0X80);        //显示数据
                                        data=SPI2_ReadWriteByte(0xD1);
                                  LCD_ShowxNum(20+5*32,30+i2*20,data,3,16,0X80);        //显示数据
                                        GPIO_SetBits( GPIOB, GPIO_Pin_12 );                          //取消片选
         
         
         
         

  while(1)
        {

          GPIO_ResetBits(GPIOB,GPIO_Pin_5);
          GPIO_SetBits(GPIOE,GPIO_Pin_5);

                for(i2=0;i2<42;i2++)
                        {

//                                for(i1=0;i1<9;i1++)
//                        {
                                        GPIO_ResetBits( GPIOB, GPIO_Pin_12 );
                                        data=SPI2_ReadWriteByte(0xFA);
                                  LCD_ShowxNum(20+1*32,30+i2*20,data,3,16,0X80);        //显示数据
                                        data=SPI2_ReadWriteByte(0xFF);
                                  LCD_ShowxNum(20+2*32,30+i2*20,data,3,16,0X80);        //显示数据
                                        data=SPI2_ReadWriteByte(0x30);
                                  LCD_ShowxNum(20+3*32,30+i2*20,data,3,16,0X80);        //显示数据
                                        data=SPI2_ReadWriteByte(0x00);
                                  LCD_ShowxNum(20+4*32,30+i2*20,data,3,16,0X80);        //显示数据
                                        data=SPI2_ReadWriteByte(0xD1);
                                  LCD_ShowxNum(20+5*32,30+i2*20,data,3,16,0X80);        //显示数据
                                        GPIO_SetBits( GPIOB, GPIO_Pin_12 );                          //取消片选

//                        }

                        }

                GPIO_SetBits(GPIOB,GPIO_Pin_5);
                GPIO_ResetBits(GPIOE,GPIO_Pin_5);

        }
}
---------------------------------------------------------------
下面单片机返回数据图片
---------------------------------------------------------------


图片1.png




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

592

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1458
金钱
1458
注册时间
2019-7-28
在线时间
137 小时
发表于 2021-8-17 10:35:55 | 显示全部楼层
回复

使用道具 举报

233

主题

961

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1814
金钱
1814
注册时间
2011-10-9
在线时间
230 小时
发表于 2021-8-17 16:27:34 | 显示全部楼层
去买个便宜的逻辑分析器 就一百几十块  看看spi引脚的波形数据 就知道原因了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-28 03:52

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表