野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 15835|回复: 2

小白求助,用SPI读取FLASH的ID号,为啥始终显示0xffff

[复制链接]
发表于 2020-3-17 11:18:51 | 显示全部楼层 |阅读模式
#include "./flash/bsp_spi_flash.h"
#include "./usart/bsp_usart.h"               





static __IO uint32_t  SPITimeout = SPIT_LONG_TIMEOUT;   


static uint32_t SPI_TIMEOUT_UserCallback(uint8_t errorCode);



static void SPI_GPIO_Config(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;

        /* 使能与 SPI 有关的时钟 */
        FLASH_SPI_APBxClock_FUN ( FLASH_SPI_CLK, ENABLE );
        FLASH_SPI_GPIO_APBxClock_FUN ( FLASH_SPI_GPIO_CLK, ENABLE );
       


  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);
       
  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);       
       
        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);
       
        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;
       
}


/**
  * @brief  SPI 工作模式配置
  * @param  无
  * @retval 无
  */
static void SPI_Mode_Config(void)
{
  SPI_InitTypeDef  SPI_InitStructure;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
        SPI_InitStructure.SPI_CRCPolynomial = 0;
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
       
       
        /* SPI 初始化 */
  SPI_Init(FLASH_SPIx, &SPI_InitStructure);

        /* 使能 SPI */
  SPI_Cmd(FLASH_SPIx, ENABLE);   
}



void SPI_FLASH_Init(void)
{

  SPI_GPIO_Config();

  SPI_Mode_Config();

}

uint8_t SPI_FLASH_Send_Byte(uint8_t data)
{
          
        //检查并等待TX缓冲区为空
        while(SPI_I2S_GetFlagStatus(FLASH_SPIx, SPI_I2S_FLAG_TXE)==RESET);
        {
        if((SPITimeout--)==0)
                {
                        return SPI_TIMEOUT_UserCallback(0);
                }
        }
        //程序到此,TX缓冲区已空
        SPI_I2S_SendData(FLASH_SPIx, data);
       
        //检查并等待RX缓冲区为非空
        while(SPI_I2S_GetFlagStatus(FLASH_SPIx, SPI_I2S_FLAG_RXNE)==RESET);
        {
        if((SPITimeout--)==0)
                {
                        return SPI_TIMEOUT_UserCallback(0);
                }
        }
        //程序到此说明数据发送完毕,并接收到一个字节
        return SPI_I2S_ReceiveData(FLASH_SPIx);
}

uint8_t SPI_FLASH_Read_Byte(void)
{
        return SPI_FLASH_Send_Byte(DUMMY);
}

uint32_t SPI_Read_ID(void)
{
        uint32_t flash_id;
        FLASH_SPI_CS_LOW;
        SPI_FLASH_Send_Byte(READ_JEDEC_ID);
        flash_id = SPI_FLASH_Read_Byte();
        flash_id <<=8;
        flash_id |=SPI_FLASH_Read_Byte();
        flash_id <<=8;
        flash_id |=SPI_FLASH_Read_Byte();
        FLASH_SPI_CS_HIGH;
        return flash_id;
}




static  uint32_t SPI_TIMEOUT_UserCallback(uint8_t errorCode)
{
  /* Block communication and all processes */
  FLASH_ERROR("I2C 等待超时!errorCode = %d",errorCode);

  return 0;
}


以上是SPI的C文件
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
#ifndef __SPI_FLASH_H
#define        __SPI_FLASH_H


#include "stm32f10x.h"

#define             FLASH_SPIx                                SPI1
#define             FLASH_SPI_APBxClock_FUN                   RCC_APB2PeriphClockCmd
#define             FLASH_SPI_CLK                             RCC_APB2Periph_SPI1
#define             FLASH_SPI_GPIO_APBxClock_FUN              RCC_APB2PeriphClockCmd
#define             FLASH_SPI_GPIO_CLK                        (RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC)

#define             FLASH_SPI_SCK_PORT                         GPIOA   
#define             FLASH_SPI_SCK_PIN                          GPIO_Pin_5
#define             FLASH_SPI_MOSI_PORT                        GPIOA   
#define             FLASH_SPI_MOSI_PIN                         GPIO_Pin_7
#define             FLASH_SPI_MISO_PORT                        GPIOA
#define             FLASH_SPI_MISO_PIN                         GPIO_Pin_6
#define             FLASH_SPI_CS_PORT                          GPIOC
#define             FLASH_SPI_CS_PIN                           GPIO_Pin_0

#define             FLASH_SPI_CS_HIGH       GPIO_SetBits(FLASH_SPI_CS_PORT, FLASH_SPI_CS_PIN);
#define             FLASH_SPI_CS_LOW        GPIO_SetBits(FLASH_SPI_CS_PORT, FLASH_SPI_CS_PIN);

#define DUMMY  0x00
#define READ_JEDEC_ID 0x9f

/*等待超时时间*/
#define SPIT_FLAG_TIMEOUT         ((uint32_t)0x1000)
#define SPIT_LONG_TIMEOUT         ((uint32_t)(10 * SPIT_FLAG_TIMEOUT))


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

#define FLASH_INFO(fmt,arg...)           printf("<<-FLASH-INFO->> "fmt"\n",##arg)
#define FLASH_ERROR(fmt,arg...)          printf("<<-FLASH-ERROR->> "fmt"\n",##arg)
#define FLASH_DEBUG(fmt,arg...)          do{\
                                          if(FLASH_DEBUG_ON)\
                                          printf("<<-FLASH-DEBUG->> [%d]"fmt"\n",__LINE__, ##arg);\
                                          }while(0)

uint32_t SPI_Read_ID(void);
void SPI_FLASH_Init(void);


#endif


以上是SPI的H文件
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

#include "stm32f10x.h"
#include "./led/bsp_led.h"
#include "./usart/bsp_usart.h"
#include "./flash/bsp_spi_flash.h"
#include <string.h>


/**
  * @brief  主函数
  * @param  无
  * @retval 无
  */
int main(void)
{
        uint32_t id;

        USART_Config();
       
        SPI_FLASH_Init();
       
        printf("\r\n 这是一个SPI_FLASH_ID读写测试例程 \r\n");
       
        id= SPI_Read_ID();       

       printf("\r\n id=0x%x \r\n",id);       

}
以上是主函数
、、、、、、、、、、、、、、、、、、、、、、、、、、、

回复

使用道具 举报

发表于 2020-3-20 22:09:40 | 显示全部楼层
先仔细对比下和例程有没有不同
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-25 14:21:45 | 显示全部楼层
WishWish 发表于 2020-3-20 22:09
先仔细对比下和例程有没有不同

和例程对比了,一样
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-23 15:39 , Processed in 0.051908 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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