高中生
最后登录1970-1-1
在线时间 小时
注册时间2020-12-27
|
我用的板子是原子的,用的是SPI2口,FLASH是W25Q128。按照视频的代码写了读取JEDEC ID的程序,但是结果是总是出现ERROR0,那应该是发送数据时没有收到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)
{
}
}
|
|