打印
[信息]

SPI读取FLASH的JEDEC ID,发送数据失败

[复制链接]
2352|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
两只袜子|  楼主 | 2021-8-9 10:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用的板子是原子的战舰V3,MCU型号是STM32F103ZET6。硬件用的是SPI2口,FLASH是W25Q128。


按照视频教程的代码写了读取JEDEC ID的程序,但是结果是总是出现<SPI等待超时!errorCode=0>,从程序上看,应该是发送数据时没有收到SPI2的TXE的信号。看了一天的程序了,也没找出原因,程序如下,请大神帮我看看



bsp_spi.h
#ifndef __SPI_FLASH_H
#define        __SPI_FLASH_H

#include "stm32f10x.h"
#include "stm32f10x_spi.h"

/********************SPI参数定义********************/
#define        FLASH_SPIx                                                                                SPI2
#define FLASH_SPI_APBxclock_Cmd                                RCC_APB1PeriphClockCmd
#define FLASH_SPI_CLK                                                                        RCC_APB1Periph_SPI2
#define FLASH_SPI_GPIO_APBxCLock_Cmd        RCC_APB2PeriphClockCmd
#define FLASH_SPI_GPIO_CLK                                                RCC_APB2Periph_GPIOB

#define FLASH_SPI_MISO_PORT                                                GPIOB
#define FLASH_SPI_MISO_PIN                                                GPIO_Pin_14
#define FLASH_SPI_MOSI_PORT                                                GPIOB
#define FLASH_SPI_MOSI_PIN                                                GPIO_Pin_15
#define FLASH_SPI_SCK_PORT                                                GPIOB
#define FLASH_SPI_SCK_PIN                                                        GPIO_Pin_13
#define FLASH_SPI_CS_PORT                                                        GPIOB
#define FLASH_SPI_CS_PIN                                                        GPIO_Pin_12

/* SPI分频因子 */
#define FLASH_SPI_BaudRatePrescaler   SPI_BaudRatePrescaler_2
/* SPI模式3,时钟极性1,时钟相位1 */
#define FLASH_SPI_Clock_Phase                                        SPI_CPHA_2Edge
#define FLASH_SPI_Clock_Polarity                        SPI_CPOL_High
/* 不适用crc校验 */
#define FLASH_SPI_CRCPolynomial                                0
#define FLASH_SPI_DataSize                                                SPI_DataSize_8b
#define FLASH_SPI_data_direction_mode        SPI_Direction_2Lines_FullDuplex
#define FLASH_SPI_MSB_LSB_transmission         SPI_FirstBit_MSB
#define FLASH_SPI_master_slave_mode                SPI_Mode_Master
#define FLASH_SPI_Slave_Select_management        SPI_NSS_Soft

/* 定义超时时间 */
#define SPI_FLAG_TIMEOUT                               ((uint32_t)0x1000)
#define SPI_LONG_TIMEOUT                               ((uint32_t)(10*SPI_FLAG_TIMEOUT))

#define DUMMY                                                                                                0x00
#define READ_JEDEC_ID                                                                0x9f

/* SPI片选信号CS控制 */
#define FLASH_SPI_CS_HIGH()                                        GPIO_SetBits(FLASH_SPI_CS_PORT,FLASH_SPI_CS_PIN)
#define FLASH_SPI_CS_LOW()                                        GPIO_ResetBits(FLASH_SPI_CS_PORT,FLASH_SPI_CS_PIN)

/* 信息输出 */
#define SPI_FLASH_debug_ON                                               0

#define SPI_FLASH_INFO(fmt,arg...)       printf("<<-SPI_FLASH-INFO->>"fmt"\n",##arg)      
#define SPI_FLASH_ERROR(fmt,arg...)      printf("<<-SPI_FLASH-ERROR->>"fmt"\n",##arg)      
#define SPI_FLASH_DEBUG(fmt,arg...)      do{\
                                                                                                                                                if(EEPROM_DEBUG_ON)\
                                                                                                                                                printf("<<-SPI_FLASH-DEBUG->>[%d]"fmt"\n",__LINE__,##arg);\
                                                                                                                                                }while(0)

void SPI_FLASH_Init(void);
void SPI2_Init(void);
uint32_t SPI_Read_Device_ID(void);
                                                                                                                                               
#endif /* __SPI_FLASH_H */
--------------------------------------------------------------------------------------------

bsp_spi.c

#include "bsp_spi.h"
#include "bsp_usart.h"

static uint32_t SPI_Timeout;
static uint32_t SPI_FLASH_TIMEOUT_UserCallback(uint8_t errorCode);

/*
* 函数名:SPI_FLASH_GPIO_Config
* 描述  :SPI1 I/O配置
* 输入  :无
* 输出  :无
* 调用  :内部调用
*/

static void SPI_FLASH_GPIO_Config(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;

        /* 使能与SPI2有关的时钟 */
        FLASH_SPI_GPIO_APBxCLock_Cmd(FLASH_SPI_GPIO_CLK,ENABLE);
  FLASH_SPI_APBxClock_Cmd(FLASH_SPI_CLK,ENABLE);  

  /* PB15-SPI_MOSI*/
  GPIO_InitStructure.GPIO_Pin =  FLASH_SPI_MOSI_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;               // 复用推挽输出
  GPIO_Init(FLASH_SPI_MOSI_PORT, &GPIO_InitStructure);
      
          /* PB13-SPI_SCK*/
  GPIO_InitStructure.GPIO_Pin =  FLASH_SPI_SCK_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;               // 复用推挽输出
  GPIO_Init(FLASH_SPI_SCK_PORT, &GPIO_InitStructure);
      
         /* PB14-SPI_MIS0*/
  GPIO_InitStructure.GPIO_Pin =  FLASH_SPI_MISO_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;         // 浮空输入
  GPIO_Init(FLASH_SPI_MISO_PORT, &GPIO_InitStructure);
      
         /* PB12-SPI_CS*/
  GPIO_InitStructure.GPIO_Pin =  FLASH_SPI_CS_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;             // 通用推挽输出
  GPIO_Init(FLASH_SPI_CS_PORT, &GPIO_InitStructure);
      
        FLASH_SPI_CS_HIGH();
}

/*
* 函数名:SPI_Configuration
* 描述  :SPI 工作模式配置
* 输入  :无
* 输出  :无
* 调用  :内部调用
*/
static void SPI_Mode_Config(void)
{
  SPI_InitTypeDef  SPI_InitStructure;

  /* SPI 配置 */
  SPI_InitStructure.SPI_BaudRatePrescaler = FLASH_SPI_BaudRatePrescaler;
  SPI_InitStructure.SPI_CPHA                                                        = FLASH_SPI_Clock_Phase;
        SPI_InitStructure.SPI_CPOL                                                        = FLASH_SPI_Clock_Polarity;
        SPI_InitStructure.SPI_CRCPolynomial                        = FLASH_SPI_CRCPolynomial;
        SPI_InitStructure.SPI_DataSize                                        = FLASH_SPI_DataSize;
        SPI_InitStructure.SPI_Direction                                        = FLASH_SPI_data_direction_mode;
        SPI_InitStructure.SPI_FirstBit                                        = FLASH_SPI_MSB_LSB_transmission;
        SPI_InitStructure.SPI_Mode                                                        = FLASH_SPI_master_slave_mode;
        SPI_InitStructure.SPI_NSS                                                                = FLASH_SPI_Slave_Select_management;
      
  /* SPI2 初始化 */
  SPI_Init(FLASH_SPIx, &SPI_InitStructure);
      
  /* 使能 SPI */
  SPI_Cmd(FLASH_SPIx, ENABLE);
}

/*
* 函数名:SPI_FLASH_Init
* 描述  :SPI外设FLASH初始化
* 输入  :无
* 输出  :无
* 调用  :外部调用
*/

void SPI_FLASH_Init(void)
{
  SPI_FLASH_GPIO_Config();
  SPI_Mode_Config();
}

//发送一个字节
uint8_t SPI_FLASH_Write_Read_Byte(uint8_t data)
{
        //超时设置为1000
        SPI_Timeout = SPI_FLAG_TIMEOUT;
        //等待检查TXE发送寄存器为空
        while(SPI_I2S_GetITStatus(FLASH_SPIx, SPI_I2S_IT_TXE)==RESET)
        {
                if((SPI_Timeout--)==0)        return SPI_FLASH_TIMEOUT_UserCallback(0);
        }
      
        //发送数据
        SPI_I2S_SendData(FLASH_SPIx, data);

        //超时设置为1000
        SPI_Timeout = SPI_FLAG_TIMEOUT;
        //等待检查TXE接收寄存器为非空
        while(SPI_I2S_GetITStatus(FLASH_SPIx, SPI_I2S_IT_RXNE)==RESET)
        {
                if((SPI_Timeout--)==0)        return SPI_FLASH_TIMEOUT_UserCallback(1);
        }
      
        //返回接收的数据
        return SPI_I2S_ReceiveData(FLASH_SPIx);
}

//接收一个字节
uint8_t SPI_FLASH_ReadByte(void)
{
return SPI_FLASH_Write_Read_Byte(DUMMY);
}

//读取FLASH的Manufacturer/Device ID
uint32_t SPI_Read_Device_ID(void)
{
        uint32_t JEDEC_ID=0;
      
        //选中FLASH片选信号
        FLASH_SPI_CS_LOW();
      
        SPI_FLASH_Write_Read_Byte(READ_JEDEC_ID);
      
        JEDEC_ID = SPI_FLASH_Write_Read_Byte(DUMMY);
      
        JEDEC_ID <<= 8;
      
        JEDEC_ID |= SPI_FLASH_Write_Read_Byte(DUMMY);
      
        JEDEC_ID <<= 8;
      
        JEDEC_ID |= SPI_FLASH_Write_Read_Byte(DUMMY);
      
        FLASH_SPI_CS_HIGH();
      
        return JEDEC_ID;
}

/*
* 函数名:SPI_FLASH_TIMEOUT_UserCallback
* 描述  :basic management of timeout situation
* 输入  :errorCode:错误代码可以用来定位是哪个环节出错
* 输出  :无
* 返回  :返回0表示SPI_FLASH读取失败
* 调用  :
*/
static uint32_t SPI_FLASH_TIMEOUT_UserCallback(uint8_t errorCode)
{
        SPI_FLASH_ERROR("SPI等待超时!errorCode=%d",errorCode);
      
        return 0;
}
/******************** (C) COPYRIGHT 2011 迷你嵌入式开发工作室 ********************/
-----------------------------------------------------------------------------------------------



main.c

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "core_cm3.h"
#include "stdint.h"
#include "system_stm32f10x.h"
#include "bsp_key.h"
#include "bsp_LED.h"
#include "bsp_led.h"
#include "bsp_rccclkconfig.h"
#include "bsp_exti.h"
#include "bsp_systick.h"
#include "bsp_usart.h"
#include "bsp_spi.h"

int main(void)
{
        uint32_t FlashID;
      
        //时钟配置为72M
        HSE_SetSysClk(RCC_PLLMul_9);
      
        //串口初始化
        USART_Config();      

        //SPI_FLASH_Init();
      
        printf("这是一个SPI_FLASH试验\n");
      
        FlashID = SPI_Read_Device_ID();
      
        printf("\nFlash device ID=0x%x\n",FlashID);
      
        while(1)
        {
        }
}      

使用特权

评论回复
沙发
磨砂| | 2021-9-8 09:40 | 只看该作者
具体现象什么啊

使用特权

评论回复
板凳
八层楼| | 2021-9-8 10:27 | 只看该作者
有返回的失败码吗

使用特权

评论回复
地板
观海| | 2021-9-8 10:32 | 只看该作者
希望楼主详细描述一下

使用特权

评论回复
5
guanjiaer| | 2021-9-8 10:40 | 只看该作者
其他数据可以成功读取吗

使用特权

评论回复
6
heimaojingzhang| | 2021-9-8 12:05 | 只看该作者
供电电压测量是多少啊

使用特权

评论回复
7
SantaBunny| | 2023-3-5 21:44 | 只看该作者
你先测试读写数据是否正常,如果数据不正常,那肯定是你的时序不对。

使用特权

评论回复
8
bqyj| | 2023-8-7 19:42 | 只看该作者
具体现象?

使用特权

评论回复
9
wenfen| | 2023-8-7 19:43 | 只看该作者
有返回的失败码吗

使用特权

评论回复
10
zhuhuis| | 2023-8-7 19:45 | 只看该作者
**楼主详细描述一下

使用特权

评论回复
11
tian111| | 2023-8-7 19:47 | 只看该作者
其他数据可以成功读取吗

使用特权

评论回复
12
songqian17| | 2023-8-7 19:49 | 只看该作者
供电电压测量是多少啊

使用特权

评论回复
13
chenho| | 2023-8-7 19:50 | 只看该作者
先测试读写数据是否正常

使用特权

评论回复
14
houcs| | 2023-8-7 19:51 | 只看该作者
如果数据不正常,那肯定是你的时序不对。

使用特权

评论回复
15
Mowergy| | 2023-10-22 11:01 | 只看该作者
读写数据正常吗

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2103

主题

7903

帖子

11

粉丝