历史上的今天
返回首页

历史上的今天

今天是:2024年08月29日(星期四)

正在发生

2019年08月29日 | STM32F429 >> 13. SPI 通讯(code)

2019-08-29 来源:eefocus

=========================== SPI 详细教程在这 ===============================


bsp_spi_flash.h

/**

  ******************************************************************************

  * @file    bsp_spi_flash.h

  * @author  Waao

  * @version V1.0.0

  * @date    19-Jan-2019

  * @brief   This file contains some board support package's definitions for the SPI.

  *            

  ******************************************************************************

  * @attention

  *

  * None

*

  ******************************************************************************

  */

#ifndef _BSP_SPI_FLASH_H_

#define _BSP_SPI_FLASH_H_



#include

#include

#include



#define SPIT_FLAG_TIMEOUT          ((uint32_t)0x1000)

#define SPIT_LONG_TIMEOUT          ((uint32_t)(10*SPIT_FLAG_TIMEOUT))


#define SPI_FLASH_PageSize              256

#define SPI_FLASH_PerWritePageSize      256


#define FLASH_ERROR(fmt, arg...)   printf("Error Code:"fmt"n", ##arg)


//============================ SPI =================================

#define SPI_                       SPI5 

#define SPI_CLK                    RCC_APB2Periph_SPI5


//====================== Signal Line GPIO ==========================

#define SPI_GPIO_CLK               RCC_AHB1Periph_GPIOF

#define SPI_GPIO_PORT              GPIOF


//=== NSS ===

#define SPI_NSS_GPIO_PORT          GPIOF          

#define SPI_NSS_GPIO_PIN           GPIO_Pin_6          

#define SPI_NSS_GPIO_RCC           RCC_AHB1Periph_GPIOF  


//=== SCK ===

#define SPI_SCK_GPIO_PORT          GPIOF          

#define SPI_SCK_GPIO_PIN           GPIO_Pin_7          

#define SPI_SCK_GPIO_RCC           RCC_AHB1Periph_GPIOF  

#define SPI_SCK_GPIO_PinSource     GPIO_PinSource7

#define SPI_SCK_GPIO_AF            GPIO_AF_SPI5


//=== MISO ===

#define SPI_MISO_GPIO_PORT         GPIOF          

#define SPI_MISO_GPIO_PIN          GPIO_Pin_8          

#define SPI_MISO_GPIO_RCC          RCC_AHB1Periph_GPIOF  

#define SPI_MISO_GPIO_PinSource    GPIO_PinSource8

#define SPI_MISO_GPIO_AF           GPIO_AF_SPI5

  

//=== MOSI ===

#define SPI_MOSI_GPIO_PORT         GPIOF          

#define SPI_MOSI_GPIO_PIN          GPIO_Pin_9          

#define SPI_MOSI_GPIO_RCC          RCC_AHB1Periph_GPIOF          

#define SPI_MOSI_GPIO_PinSource    GPIO_PinSource9

#define SPI_MOSI_GPIO_AF           GPIO_AF_SPI5


//=== CS/NSS Control ===

#define SPI_FLASH_CS_1             {SPI_NSS_GPIO_PORT->BSRRL=SPI_NSS_GPIO_PIN;}

#define SPI_FLASH_CS_0             {SPI_NSS_GPIO_PORT->BSRRH=SPI_NSS_GPIO_PIN;}

//================================================================


//=== Commonly Used Command ===

#define W25X_WriteEnable        0x06 

#define W25X_WriteDisable        0x04 

#define W25X_ReadStatusReg      0x05 

#define W25X_WriteStatusReg      0x01 

#define W25X_ReadData          0x03 

#define W25X_FastReadData        0x0B 

#define W25X_FastReadDual        0x3B 

#define W25X_PageProgram        0x02 

#define W25X_BlockErase        0xD8 

#define W25X_SectorErase        0x20 

#define W25X_ChipErase        0xC7 

#define W25X_PowerDown        0xB9 

#define W25X_ReleasePowerDown      0xAB 

#define W25X_DeviceID          0xAB 

#define W25X_ManufactDeviceID    0x90 

#define W25X_JedecDeviceID      0x9F 


#define WIP_Flag                   0x01  /* Write In Progress (WIP) flag */

#define Dummy_Byte                 0xFF



void SPI_GPIO_Config(void);

void SPI_Config(void);

uint8_t SPI_FLASH_SendByte(uint8_t byte);

uint8_t SPI_FLASH_ReadByte(void);

uint32_t SPI_FLASH_ReadID(void);

u32 SPI_FLASH_ReadDeviceID(void);

void SPI_FLASH_WriteEnable(void);

u8 SPI_FLASH_WaitForWriteEnd(void);

void SPI_FLASH_SectorErase(u32 SectorAddr);

void SPI_FLASH_PageWrite(u8 *pBuffer, u32 WriteAddr, u16 NumByteToWrite);

void SPI_FLASH_BufferWrite(u8 *pBuffer, u32 WriteAddr, u16 NumByteToWrite);

void SPI_FLASH_BufferRead(u8 *pBuffer, u32 ReadAddr, u16 NumByteToWrite);

uint8_t SPI_TIMEOUT_Callback(uint8_t errorcode);



#endif



bsp_spi_flash.c

/**

  ******************************************************************************

  * @file    bsp_spi_flash.c

  * @author  Waao

  * @version V1.0.0

  * @date    19-Jan-2019

  * @brief   This file contains some board support package's functions for the SPI.

  *            

  ******************************************************************************

  * @attention

  *

  * None

*

  ******************************************************************************

  */


#include



static __IO uint32_t SPITimeout = SPIT_LONG_TIMEOUT;

static uint32_t WAITING_TIME = SPIT_FLAG_TIMEOUT;


/**

  * @brief  Initialize the SPI_GPIO.

  * @param  None  

  * @retval None

  */

void SPI_GPIO_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHB1PeriphClockCmd(SPI_GPIO_CLK, ENABLE);

GPIO_PinAFConfig(SPI_SCK_GPIO_PORT, SPI_SCK_GPIO_PinSource, SPI_SCK_GPIO_AF);

GPIO_PinAFConfig(SPI_MISO_GPIO_PORT, SPI_MISO_GPIO_PinSource, SPI_MISO_GPIO_AF);

GPIO_PinAFConfig(SPI_MOSI_GPIO_PORT, SPI_MOSI_GPIO_PinSource, SPI_MOSI_GPIO_AF);

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

//SCK

GPIO_InitStructure.GPIO_Pin = SPI_SCK_GPIO_PIN;

GPIO_Init(SPI_SCK_GPIO_PORT, &GPIO_InitStructure);

//MISO

GPIO_InitStructure.GPIO_Pin = SPI_MISO_GPIO_PIN;

GPIO_Init(SPI_MISO_GPIO_PORT, &GPIO_InitStructure);

//MOSI

GPIO_InitStructure.GPIO_Pin = SPI_MOSI_GPIO_PIN;

GPIO_Init(SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);

//NSS

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

GPIO_InitStructure.GPIO_Pin = SPI_NSS_GPIO_PIN;

GPIO_Init(SPI_NSS_GPIO_PORT, &GPIO_InitStructure);

SPI_FLASH_CS_1;

}



/**

  * @brief  Initialize the SPI.

  * @param  None  

  * @retval None

  */

void SPI_Config(void)

{

SPI_InitTypeDef SPI_InitStructure;

SPI_GPIO_Config();

RCC_APB2PeriphClockCmd(SPI_CLK, ENABLE);

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;

SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;

SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;

SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

//Since we not use the CRC verify mode, so this CRCPolynomial is invalid

SPI_InitStructure.SPI_CRCPolynomial = 7;

SPI_Init(SPI_, &SPI_InitStructure);

SPI_Cmd(SPI_, ENABLE);

}



/**

  * @brief  Send a byte of data.

* @param  byte: The data you want to transmit  

  * @retval The data have been received from flash.

  */

u8 SPI_FLASH_SendByte(u8 byte)

{

//Waiting the transmit register to be empty

WAITING_TIME = SPIT_FLAG_TIMEOUT;

while(!SPI_I2S_GetFlagStatus(SPI_, SPI_I2S_FLAG_TXE))

{

if((WAITING_TIME--) == 0)

{

printf("timeout");

return SPI_TIMEOUT_Callback(0);

}

}

SPI_I2S_SendData(SPI_, byte);

//Waiting the receive register to be not empty

WAITING_TIME = SPIT_FLAG_TIMEOUT;

while(!SPI_I2S_GetFlagStatus(SPI_, SPI_I2S_FLAG_RXNE))

{

if((WAITING_TIME--) == 0)

{

printf("timeout");

return SPI_TIMEOUT_Callback(1);

}

}

return SPI_I2S_ReceiveData(SPI_);

}



/**

  * @brief  Receive a byte of data.

* @param  Since the process of receiving and sending is synchronous, So we must

*  sending a byte of data if we want to read data from flash, the send data is random.

  * @retval The data have been received from flash.

  */

u8 SPI_FLASH_ReadByte(void)

{

return (SPI_FLASH_SendByte(Dummy_Byte));

}



/**

  * @brief  Read the flash's ID

* @param  None 

* @retval temp: The ID of the FLASH

  */

u32 SPI_FLASH_ReadID(void)

{

u32 temp = 0, temp_1 = 0, temp_2 = 0, temp_3 = 0;

SPI_FLASH_CS_0;

SPI_FLASH_SendByte(W25X_JedecDeviceID);

temp_1 = SPI_FLASH_ReadByte();

temp_2 = SPI_FLASH_ReadByte();

temp_3 = SPI_FLASH_ReadByte();

SPI_FLASH_CS_1;

temp = (temp_1 << 16) | (temp_2 << 8) | temp_3;

return temp;

}



/**

  * @brief  Read the flash device's ID

* @param  None 

推荐阅读

史海拾趣

东晶(ECEC)公司的发展小趣事

东晶电子自创立以来,始终将技术创新作为公司发展的核心动力。在21世纪初,随着通信技术的迅猛发展,对高性能、高稳定性的石英晶体元器件需求急剧增加。东晶电子凭借其强大的研发团队,成功研发出一系列高精度、高稳定的石英晶体谐振器和振荡器,打破了国外厂商的技术垄断,为中国通信产业提供了关键元器件支持。这一技术突破为公司赢得了市场口碑,也奠定了其在电子行业中的领先地位。

启臣微(Chip)公司的发展小趣事

在成都启臣微电子股份有限公司成立之初,公司就致力于集成电路及系统产品的设计、生产与销售。面对激烈的市场竞争,启臣微坚持创新,投入大量研发资源,终于在高性能功率管理集成电路领域取得了重大技术突破。这一突破不仅提升了公司的市场竞争力,也为公司赢得了业界的广泛认可。

乾坤(Cyntec)公司的发展小趣事

乾坤(Cyntec)公司在电子行业初创时期面临着诸多挑战。由于市场上已经存在多家知名的电子产品制造商,作为一家新兴公司,乾坤必须要在激烈的市场竞争中找到自己的定位。公司创始人深知,只有通过技术创新和产品差异化,才能在市场中站稳脚跟。于是,他们投入大量资源进行研发,专注于开发高性能、高稳定性的电子元器件。经过一段时间的努力,乾坤成功推出了一系列具有自主知识产权的新型电子元器件,这些产品很快在市场上获得了良好的口碑,为公司的后续发展奠定了坚实的基础。

General Semiconductor ( Vishay )公司的发展小趣事

Vishay一直致力于技术创新和产品升级。在2001年,公司收购了全球二极管和整流器领先制造商General Semiconductor,这一收购极大地增强了Vishay在二极管和整流器领域的实力。同时,Vishay还通过收购RFWaves公司,涉足无线领域,为公司带来了新的增长动力。此外,Vishay还在全球范围内布局制造基地和销售办事处,确保能够为客户提供优质的产品和服务。

Global Mixed-Mode Technology Inc公司的发展小趣事
校准和测试三相缺相报警灯电路的准确性,可以使用专业的测试仪器(如万用表、示波器等)来检测三相电的电压情况。首先,在正常情况下检查电路是否误报;然后,人为制造缺相情况(如断开某一相的电源),检查报警灯是否准确亮起并发出警报。通过反复测试和调整,可以确保电路的准确性和可靠性。
ADI Electronics Inc公司的发展小趣事

ADI在发展过程中始终坚持创新,不断推出新产品和新技术。例如,在数字化转型的浪潮中,ADI积极拥抱变革,推出了一系列针对物联网、人工智能等新兴领域的解决方案。这些创新举措不仅满足了客户的需求,也进一步巩固了ADI在电子行业的领先地位。

问答坊 | AI 解惑

国半推出新款PWM降压控制器,采用低噪音仿电流模式结构

美国国家半导体公司宣布推出一款新的脉冲宽度调制(PWM)降压控制器,其特点是采用美国国家半导体独有的仿电流模式(ECM)结构,确保输出电压时占空比可以降至最低,而开关频率可以高达1.5MHz。 这款型号为LM3495的降压控制器可为ASIC、FPGA、数字信号 ...…

查看全部问答>

DSP芯片的原理和开发应用(3)

2.4 TI浮点DSP芯片 2.4.1 TMS320C3X TMS320C3X是TI的第三代产品,也是第一代浮点DSP芯片。TMS320C3X中目前具有TMS320C 30、TMS320C31和TMS320C32三种。TMS320C31是TMS320C30的简化和改进型,它在TMS320 C30的基础上去掉了一般用户不常用的 ...…

查看全部问答>

为何在数字信号处理系统价格如此低廉而且功能如此强大时,仍推荐模拟信号处理?

解答:因为有些时候模拟信号处理价格甚至更为低廉,而且可以完成数字信号处理不能完成的功能。模拟信号处理电路的销量可以证明这种说法。   伦敦南肯辛顿(South Kensington)科学博物馆建于维多利亚女王统治时期。尽管它运行良好而且很值得参 ...…

查看全部问答>

09电赛猜题群!信号+控制类!

本帖最后由 paulhyde 于 2014-9-15 09:01 编辑 QQ号:89212186 集各省高手,猜09赛题! 大家抓紧时间,多多交流,争取缩小赛题!  …

查看全部问答>

外企机械工程师的二十年职业感悟

89年毕业,国企4年,民企2年,港企7年,意企5年,日韩合资企业2年,经历非标设备、玩具、电子、自动化设备行业。 在珠三角亲历了“中国制造”的繁荣壮大,也感受到目前金融海啸带来的凛冽气息,对“中国制造”有一些管窥之见,结合本人的经历,在 ...…

查看全部问答>

如何用 diff及其他工具写一个版本控制系统?

摘自:arm linux fpga 嵌入0群  49900581(超级群)  群主在坛子里ID:wangkj wangkj:32. 如何用 diff 及其他工具写一个版本控制系统?(要有 check in, check out, file lock .. 等功能) 先知_找到了:不是都有免费 ...…

查看全部问答>

请教关于CE下右键功能消失的问题

请教各位:    在正常情况下,手按住触摸屏会出现一个小圆圈,然后弹出菜单:图标排列方式、刷新、粘贴、新建文件夹、属性等 类似鼠标右键功能 但是我的PDA用一段时间后就没有这个功能了,长按触摸屏,相当于只按左键,并不弹出菜单 ...…

查看全部问答>

VxWorks5.5是否支持PCI Express

vxworks5.5是否对PCI Express能够支持? 还是只要BSP中对其支持就可以了? 刚学VxWorks不是很长时间,对很多问题不是很清楚,希望各位能够帮我解答这个问题,还有就是在VxWorks下写PCI Express设备的驱动与PCI设备的驱动区别大吗?…

查看全部问答>

信号线与电源线共用的问题

我现在有两个电路模块,需要互相通信,数据量少,采用类似485的通信就可以了。但是我想用通信线由其中的一块电路板给另外电路板供电,即两根线既用来通信又做电源线,请问大家有做个类似项目的吗?给点思路啊。谢谢!…

查看全部问答>

压力传感器!!!!

有没有高手用过压力传感器啊,用凌阳单片机采集信息。 主要内容:从一个容器向另一个容器注水,用压力传感器测出容器中水量变化,传给单片机处理。 有人推荐我使用MPX5010,但是以前没有用过,还请高手们指点啊!!!!!!!!!…

查看全部问答>