当前位置: 首页 > news >正文

stm32使用SPI写W25Q32

SPI.h

#ifndef __SPI_H
#define __SPI_H#include "stm32f10x.h"#define SPI_CS_H GPIO_SetBits(GPIOB, GPIO_Pin_12)
#define SPI_CS_L GPIO_ResetBits(GPIOB, GPIO_Pin_12)#define SPI_SCK_H GPIO_SetBits(GPIOB, GPIO_Pin_13)
#define SPI_SCK_L GPIO_ResetBits(GPIOB, GPIO_Pin_13)#define SPI_MISO_H GPIO_SetBits(GPIOB, GPIO_Pin_14)
#define SPI_MISO_L GPIO_ResetBits(GPIOB, GPIO_Pin_14)#define SPI_MOSI_H GPIO_SetBits(GPIOB, GPIO_Pin_15)
#define SPI_MOSI_L GPIO_ResetBits(GPIOB, GPIO_Pin_15)#define READDATALENGTH 255void SPI_GPIO_Init(void);
uint8_t SPI_WriteRead_Byte(uint8_t byte);void Write_Enable(void);
void Write_Disable(void);
uint8_t Read_StatusR1(void);
uint8_t* Read_Data(uint8_t addr2, uint8_t addr1, uint8_t addr0, uint8_t num2read);void Page_Program(uint8_t addr2, uint8_t addr1, uint8_t addr0, uint8_t *data);
void Sector_Erase(void);#endif

SPI.C

#include "spi.h"void SPI_GPIO_Init(void)
{//SPI2-NSS PB12:PIN25 --CS//SPI2-SCK PB13:PIN26//SPI2-MISO PB14:PIN27     W25Q32:DO//SPI2-MOSI PB15:PIN28     W25Q32:DI
GPIO_InitTypeDef    GPIO_InitStruct;  SPI_InitTypeDef    SPI_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Pin =  GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStruct);GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStruct);SPI_CS_H;
//    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
//    
//    GPIO_Init(GPIOB, &GPIO_InitStruct);
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;SPI_InitStruct.SPI_CRCPolynomial = 7;SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;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(SPI2, &SPI_InitStruct);SPI_Cmd(SPI2, ENABLE);}uint8_t SPI_WriteRead_Byte(uint8_t byte)
{SPI_I2S_SendData(SPI2, byte);while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);return SPI_I2S_ReceiveData(SPI2);
}void Write_Enable(void)
{SPI_CS_L;SPI_WriteRead_Byte(0x06); //set WEL bit 1
    SPI_CS_H;}//一般不需要调用,编程或是擦除操作,WEL会自动清零
void Write_Disable(void)
{SPI_CS_L;SPI_WriteRead_Byte(0x04); //set WEL bit 0
    SPI_CS_H;
}//判断忙标志
uint8_t Read_StatusR1(void)
{uint8_t res = 0;SPI_CS_L;SPI_WriteRead_Byte(0x05); //S0 BUSY bit 1: busy ;    S0 BUSY bit 0: free ;res = SPI_WriteRead_Byte(0x05);SPI_CS_H;if((res & 0x01)== 0x01){return 1;}else{return 0;}
}//读1/2个字节数据
uint8_t* Read_Data(uint8_t addr2, uint8_t addr1, uint8_t addr0, uint8_t num2read)
{static uint8_t res[READDATALENGTH] = {0};uint8_t i = 0;SPI_CS_L;SPI_WriteRead_Byte(0x03);SPI_WriteRead_Byte(addr2);SPI_WriteRead_Byte(addr1);SPI_WriteRead_Byte(addr0);for(i = 0; i < num2read; i ++){res[i] = SPI_WriteRead_Byte(0xff);    }SPI_CS_H;return res;
}void Page_Program(uint8_t addr2, uint8_t addr1, uint8_t addr0, uint8_t *data)
{Write_Enable();SPI_CS_L;SPI_WriteRead_Byte(0x02);//02H页写
SPI_WriteRead_Byte(addr2);//设定写入数据的起始地址
      SPI_WriteRead_Byte(addr1);SPI_WriteRead_Byte(addr0);//      SPI_WriteRead_Byte(data[0]);//1个字节数据
//      SPI_WriteRead_Byte(data[1]);while(*data != '\0'){SPI_WriteRead_Byte(*data);data ++;}SPI_CS_H;
}void Sector_Erase(void)
{Write_Enable();SPI_CS_L;SPI_WriteRead_Byte(0x20);//20H扇区擦除
SPI_WriteRead_Byte(0x00);//擦除的数据的起始地址SPI_WriteRead_Byte(0x00);SPI_WriteRead_Byte(0x00);SPI_CS_H;
}

MAIN.C

#include "stm32f10x.h"
#include "spi.h"uint8_t val[4] = {0};
uint8_t *p;
//uint8_t send[4] = {0xa8, 0x8a, 0x55, 0xaa};
uint8_t *send = "hello, world";int main(void)
{SPI_GPIO_Init();SPI_CS_L;SPI_WriteRead_Byte(0X90);SPI_WriteRead_Byte(0X90);SPI_WriteRead_Byte(0X90);SPI_WriteRead_Byte(0X00);val[0] = SPI_WriteRead_Byte(0X90);val[1] = SPI_WriteRead_Byte(0X90);SPI_CS_H;    Sector_Erase();while(Read_StatusR1());Page_Program(0x0, 0x0, 0x0, send);while(Read_StatusR1());p = Read_Data(0x0, 0x0, 0x0, 12);while(1);
}

主要学习数组作为参数传递,函数返回数组

http://www.jsqmd.com/news/37820/

相关文章:

  • 2025年济南画室培训机构最新推荐:济南画室/济南艺考画室/山东美术艺考培训/山东画室/专业教学,个性化辅导新标杆
  • Flutter零基础极速入门到进阶实战(视频教程) - 教程
  • 题解 P13524 [KOI 2025 #2] 跳跃
  • SOS DP
  • docker - 1 安装
  • 11月10日
  • 最小二乘困难详解5:非线性最小二乘求解实例
  • ##题解##洛谷P1578##最大子矩形 扫描线法
  • 【Azure Developer】azd 安装最新版无法登录中国区问题二:本地Windows环境遇问题
  • 密码校验函数
  • 英语_阅读_The progress of technology_待读
  • Mac 下载 VMware 11.1.0-1.dmg 后如何安装?超简单教程(附安装包)
  • 机动车登记证识别技术如何通过深度学习实现泛化能力提升
  • 在R中生成交互地图leaflet包
  • 深入解析:51单片机基础-矩阵按键
  • gmssl 国密标准下载
  • 没有路由器的情况下如何通过电脑网口连接开发板
  • 重练算法(代码随想录版) day 7 -哈希表part2
  • 团队作业2——《需求规格说明书》
  • gmssl常用命令 - 需要持续更新
  • 实用指南:根据用户行为数据中的判断列表在 Elasticsearch 中训练 LTR 模型
  • 转转客服IM聊天系统背后的技术挑战和实践分享
  • 英语_阅读_Computers_待读
  • 202511.11 - A
  • AT_arc160_c [ARC160C] Power Up
  • 英语_阅读_Life in cities_待读
  • 实验 5:ViT Swin Transformer
  • 一个强大的排序工具
  • 数据采集_2
  • chatTTS源码版本地部署踩的坑