首页 > 其他分享 >20_SPI通信外设

20_SPI通信外设

时间:2024-03-06 14:57:30浏览次数:19  
标签:20 void W25Q64 MySPI SPI GPIO 外设 define

SPI通信外设

SPI外设简介

image-20240305223555836

SPI框图

image-20240305224705480

SPI基本结构

image-20240305231223010

主模式全双工连续传输

image-20240305231358674

非连续传输

image-20240305231453167

软件/硬件波形对比

image-20240306003126735

image-20240306003137897

硬件SPI读写W25Q64

接线图

image-20240306124017589

代码

MySPI.c

#include "stm32f10x.h"                  // Device header

void MySPI_W_SS(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA,GPIO_Pin_4,(BitAction)BitValue);
}

void MySPI_Init(void) //SPI模式0
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_7;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU; //上拉输入
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	SPI_InitTypeDef SPI_InitStruct;
	SPI_InitStruct.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_128; //分频
	SPI_InitStruct.SPI_CPHA=SPI_CPHA_1Edge; //时钟相位:第一个边沿采样数据
	SPI_InitStruct.SPI_CPOL=SPI_CPOL_Low; //时钟极性:空闲时间,SCK=0
	SPI_InitStruct.SPI_CRCPolynomial=7; //CRC校验多项式
	SPI_InitStruct.SPI_DataSize=SPI_DataSize_8b; //8位数据帧
	SPI_InitStruct.SPI_Direction=SPI_Direction_2Lines_FullDuplex; //双线全双工
	SPI_InitStruct.SPI_FirstBit=SPI_FirstBit_MSB; //高位先行
	SPI_InitStruct.SPI_Mode=SPI_Mode_Master; //主机
	SPI_InitStruct.SPI_NSS=SPI_NSS_Soft; //软件从机选择
	SPI_Init(SPI1,&SPI_InitStruct);
	
	SPI_Cmd(SPI1,ENABLE);
	
	MySPI_W_SS(1);
	
}

void MySPI_Start(void)
{
	MySPI_W_SS(0);
}

void MySPI_Stop(void)
{
	MySPI_W_SS(1);
}

uint8_t MySPI_SwapByte(uint8_t ByteSend)  //交换一个字节
{
	while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)!=SET);
	SPI_I2S_SendData(SPI1,ByteSend);
	while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)!=SET);
	return SPI_I2S_ReceiveData(SPI1);
}

MySPI.h

#ifndef __MYSPI_H__
#define __MYSPI_H__

void MySPI_Init(void);
void MySPI_Start(void);
void MySPI_Stop(void);
uint8_t MySPI_SwapByte(uint8_t ByteSend);

#endif

W25Q64.c

#include "stm32f10x.h"                  // Device header
#include "MySPI.h"
#include "W25Q64_Ins.h"
#include "W25Q64.h"

void W25Q64_Init(void)
{
	MySPI_Init();
}

void W25Q64_ReadID(uint8_t *MID, uint16_t *DID) //厂商ID 设备ID
{
	MySPI_Start();
	MySPI_SwapByte(W25Q64_JEDEC_ID);
	*MID=MySPI_SwapByte(W25Q64_DUMMY_BYTE);
	*DID=MySPI_SwapByte(W25Q64_DUMMY_BYTE);
	*DID<<=8;
	*DID|=MySPI_SwapByte(W25Q64_DUMMY_BYTE);
	MySPI_Stop();
}

void W25Q64_WriteEnable(void)
{
	MySPI_Start();
	MySPI_SwapByte(W25Q64_WRITE_ENABLE); //写使能
	MySPI_Stop();
}

void W25Q64_WaitBusy(void)
{
	uint32_t Timeout=100000; //超时时间
	MySPI_Start();
	MySPI_SwapByte(W25Q64_READ_STATUS_REGISTER_1);
	while((MySPI_SwapByte(W25Q64_DUMMY_BYTE)&0x01)==0x01) //等待BUSY为0
	{
		Timeout--;
		if(Timeout==0)
		{
			break;
		}
	}
	MySPI_Stop();
}

void W25Q64_PageProgram(uint32_t Address,uint8_t *DataArray,uint16_t Count) //数组页写入
{
	W25Q64_WaitBusy();
	W25Q64_WriteEnable();
	MySPI_Start();
	MySPI_SwapByte(W25Q64_PAGE_PROGRAM);
	MySPI_SwapByte(Address>>16);
	MySPI_SwapByte(Address>>8);
	MySPI_SwapByte(Address);
	for(int8_t i=0;i<Count;i++)
	{
		MySPI_SwapByte(DataArray[i]);
	}
	MySPI_Stop();
}

void W25Q64_SectorErase(uint32_t Address) //扇区擦除(4KB)
{
	W25Q64_WaitBusy();
	W25Q64_WriteEnable();
	MySPI_Start();
	MySPI_SwapByte(W25Q64_SECTOR_ERASE_4KB);
	MySPI_SwapByte(Address>>16);
	MySPI_SwapByte(Address>>8);
	MySPI_SwapByte(Address);
	MySPI_Stop();
}

void W25Q64_ReadData(uint32_t Address,uint8_t *DataArray,uint32_t Count) //读取数据
{
	W25Q64_WaitBusy();
	MySPI_Start();
	MySPI_SwapByte(W25Q64_READ_DATA);
	MySPI_SwapByte(Address>>16);
	MySPI_SwapByte(Address>>8);
	MySPI_SwapByte(Address);
	for(uint32_t i=0;i<Count;i++)
	{
		DataArray[i]=MySPI_SwapByte(W25Q64_DUMMY_BYTE);
	}
	MySPI_Stop();
}

W25Q64.h

#ifndef __W25Q64_H__
#define __W25Q64_H__

void W25Q64_Init(void);
void W25Q64_ReadID(uint8_t *MID, uint16_t *DID);
void W25Q64_WriteEnable(void);
void W25Q64_WaitBusy(void);
void W25Q64_PageProgram(uint32_t Address,uint8_t *DataArray,uint16_t Count);
void W25Q64_SectorErase(uint32_t Address);
void W25Q64_ReadData(uint32_t Address,uint8_t *DataArray,uint32_t Count);

#endif

W25Q64_Ins.h

#ifndef __W25Q64_INS_H__
#define __W25Q64_INS_H__

#define W25Q64_WRITE_ENABLE							0x06
#define W25Q64_WRITE_DISABLE						0x04
#define W25Q64_READ_STATUS_REGISTER_1				0x05
#define W25Q64_READ_STATUS_REGISTER_2				0x35
#define W25Q64_WRITE_STATUS_REGISTER				0x01
#define W25Q64_PAGE_PROGRAM							0x02
#define W25Q64_QUAD_PAGE_PROGRAM					0x32
#define W25Q64_BLOCK_ERASE_64KB						0xD8
#define W25Q64_BLOCK_ERASE_32KB						0x52
#define W25Q64_SECTOR_ERASE_4KB						0x20
#define W25Q64_CHIP_ERASE							0xC7
#define W25Q64_ERASE_SUSPEND						0x75
#define W25Q64_ERASE_RESUME							0x7A
#define W25Q64_POWER_DOWN							0xB9
#define W25Q64_HIGH_PERFORMANCE_MODE				0xA3
#define W25Q64_CONTINUOUS_READ_MODE_RESET			0xFF
#define W25Q64_RELEASE_POWER_DOWN_HPM_DEVICE_ID		0xAB
#define W25Q64_MANUFACTURER_DEVICE_ID				0x90
#define W25Q64_READ_UNIQUE_ID						0x4B
#define W25Q64_JEDEC_ID								0x9F
#define W25Q64_READ_DATA							0x03
#define W25Q64_FAST_READ							0x0B
#define W25Q64_FAST_READ_DUAL_OUTPUT				0x3B
#define W25Q64_FAST_READ_DUAL_IO					0xBB
#define W25Q64_FAST_READ_QUAD_OUTPUT				0x6B
#define W25Q64_FAST_READ_QUAD_IO					0xEB
#define W25Q64_OCTAL_WORD_READ_QUAD_IO				0xE3

#define W25Q64_DUMMY_BYTE							0xFF

#endif

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "W25Q64.h"

uint8_t MID;
uint16_t DID;

uint8_t ArrayWrite[]={0x01,0x02,0x03,0x04};
uint8_t ArrayRead[4];

int main(void)
{
	OLED_Init();
	W25Q64_Init();
	OLED_ShowString(1,1,"MID:   DID:   ");
	OLED_ShowString(2,1,"W:   ");
	OLED_ShowString(3,1,"R:   ");
	W25Q64_ReadID(&MID,&DID);
	OLED_ShowHexNum(1,5,MID,2);
	OLED_ShowHexNum(1,12,DID,4);
	W25Q64_SectorErase(0x000000);
	W25Q64_PageProgram(0x000000,ArrayWrite,4);
	W25Q64_ReadData(0x000000,ArrayRead,4);
	OLED_ShowHexNum(2,3,ArrayWrite[0],2);
	OLED_ShowHexNum(2,6,ArrayWrite[1],2);
	OLED_ShowHexNum(2,9,ArrayWrite[2],2);
	OLED_ShowHexNum(2,12,ArrayWrite[3],2);
	OLED_ShowHexNum(3,3,ArrayRead[0],2);
	OLED_ShowHexNum(3,6,ArrayRead[1],2);
	OLED_ShowHexNum(3,9,ArrayRead[2],2);
	OLED_ShowHexNum(3,12,ArrayRead[3],2);
	while(1)
	{
		
	}
}

标签:20,void,W25Q64,MySPI,SPI,GPIO,外设,define
From: https://www.cnblogs.com/mzx233/p/18056602

相关文章

  • 【2024-02-29】连岳摘抄
    23:59一蔸雨水一蔸禾,每个人头顶上都有一块天,都会有雨水的滋润。                                                 ——蔡皋人不是靠体格竞争的低等动物,人是靠头脑竞......
  • 如何简洁高效的搭建一个SpringCloud2023的maven工程
    前言依赖管理有gradle和maven,在这里选择比较常用和方便的Maven作为工程项目和依赖管理工具来搭建SpringCloud实战工程。主要用到的maven管理方式是多模块和bom依赖管理。什么是maven的多模块依赖管理Maven多模块项目相对于单模块项目而言,依赖是不共享的,但父模块提供了全局共享......
  • 2024-03-06 Module '"@nestjs/platform-express"' has no exported member 'Expr
    问题描述:nestjs后端开发,遇到跨域问题,打算用express来配合处理,结果引入express的一个模块失败。app.modules.tsimport{MiddlewareConsumer,Module,NestModule}from'@nestjs/common';import{AppController}from'./app.controller';import{AppService}from'.......
  • 2024-03-06 NestJs学习日志之跨域
    新建一个跨域中间件(如:cors.middleware.ts),并把它导入到项目根目录的app.modules.ts里面使用。中间件代码如下:import{Injectable,NestMiddleware}from"@nestjs/common";@Injectable()//跨域中间件exportclassCorsMiddlewareimplementsNestMiddleware{use(r......
  • 2024-03-06:用go语言,每一种货币都给定面值val[i],和拥有的数量cnt[i], 想知道目前拥有的
    2024-03-06:用go语言,每一种货币都给定面值val[i],和拥有的数量cnt[i],想知道目前拥有的货币,在钱数为1、2、3...m时,能找零成功的钱数有多少?也就是说当钱数的范围是1~m,返回这个范围上有多少可以找零成功的钱数。比如只有3元的货币,数量是5张,m=10。那么在1~10范围上,只有钱数是3、6......
  • 联合省选 2024 游记
    来不及踩剎车就匆匆来到这一路上的曲折翻页也忘了不晓得这身躯壳还能走多远呢如果我只剩今夜我能留下什么前言考前一直在复习模板和以前的做题笔记,中间试机的时候还反向挂分AK了一场模拟赛,消耗rp,rp--。考前的晚上有点紧张,和父母聊了聊,他们说无论如何你这个水平的都......
  • 生成式AI大爆发后,2024年人工智能行业有哪些新趋势
    在MenloVentures的AI趋势研究报告中,对美国和欧洲的450多名企业高管进行了调查,并与另外十几位高管进行了交谈,以了解当今企业应用AI的状况。尽管大肆宣传,与其他软件类别相比,企业对生成式AI的投资仍然小得惊人。将创造的大部分价值仍有待观察。虽然现有企业在当今市场占据主导......
  • 2024-03-05 NestJs学习日志之新建nest项目,运行启动命令nest start报错:Could not find
    如题,低级错误。具体报错:CouldnotfindTypeScriptconfigurationfile"tsconfig.json".Please,ensurethatyouarerunningthiscommandintheappropriatedirectory(insideNestworkspace)找不到TypeScript配置文件“tsconfig.json”。请确保您在适当的目录(Nest工作......
  • 20240305-日记(补-含0303-0304)
    我今天要是再不补,我这个目标可能就戛然而止了。这三天过得就跟三明治一样,搬家-加班-搬家。虽然想象中能搬到新家,会很开心,但是怎么说呢,还是没有一种很踏实的归属感。而且有时候我说话就是很绝,断自己和他人后路的想法。这几天也不算一点时间都挤不出来,看完了《降世神通3》,《致命游......
  • 分享一个能让你的研发效率提升超过20%的工具
    本文分享自华为云社区《CodeArtsSnap智能开发助手,让开发者们研发效率提升超过20%》,作者:华为云PaaS服务小智。突破10倍研发效能赋能千行百业。华为云CodeArts覆盖从需求、开发、测试、部署运维等软件开发全生命周期的各个环节,为开发者提供一站式、全云化的研发体验平台。并已携......