江协科技STM32学习- P38 软件SPI读写W25Q64

        🚀write in front🚀  
🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 

💬本系列哔哩哔哩江科大STM32的视频为主以及自己的总结梳理📚 

🚀Projeet source code🚀   

💾工程代码放在了本人的Gitee仓库:iPickCan (iPickCan) - Gitee.com

引用:

STM32入门教程-2023版 细致讲解 中文字幕_哔哩哔哩_bilibili

Keil5 MDK版 下载与安装教程(STM32单片机编程软件)_mdk528-CSDN博客

STM32之Keil5 MDK的安装与下载_keil5下载程序到单片机stm32-CSDN博客

0. 江协科技/江科大-STM32入门教程-各章节详细笔记-查阅传送门-STM32标准库开发_江协科技stm32笔记-CSDN博客

【STM32】江科大STM32学习笔记汇总(已完结)_stm32江科大笔记-CSDN博客

江科大STM32学习笔记(上)_stm32博客-CSDN博客

STM32学习笔记一(基于标准库学习)_电平输出推免-CSDN博客

STM32 MCU学习资源-CSDN博客

stm32学习笔记-作者: Vera工程师养成记

stem32江科大自学笔记-CSDN博客

术语:

英文缩写描述
GPIO:General Purpose Input Onuput通用输入输出
AFIO:Alternate Function Input Output复用输入输出
AO:Analog Output模拟输出
DO:Digital Output数字输出
内部时钟源 CK_INT:Clock Internal内部时钟源
外部时钟源 ETR:External Trigger 时钟源 External 触发
外部时钟源 ETR:External Trigger mode 1外部时钟源 External 触发 时钟模式1
外部时钟源 ETR:External Trigger mode 2外部时钟源 External 触发 时钟模式2
外部时钟源 ITRx:Internal Trigger inputs外部时钟源,ITRx (Internal trigger inputs)内部触发输入
外部时钟源 TIx:exTernal Input pin 外部时钟源 TIx (external input pin)外部输入引脚
CCR:Capture/Comapre Register捕获/比较寄存器
OC:Output Compare输出比较
IC:Input Capture输入捕获
TI1FP1:TI1 Filter Polarity 1Extern Input 1 Filter Polarity 1,外部输入1滤波极性1
TI1FP2:TI1 Filter Polarity 2Extern Input 1 Filter Polarity 2,外部输入1滤波极性2
DMA:Direct Memory Access直接存储器存取

正文:

0. 概述

从 2024/06/12 定下计划开始学习下江协科技STM32课程,接下来将会按照哔站上江协科技STM32的教学视频来学习入门STM32 开发,本文是视频教程 P2 STM32简介一讲的笔记。

感兴趣的一件事:

STM32HAL-最简单的长、短、多击按键框架

STM32HAL-最简单的长、短、多击按键框架(多按键)-CSDN博客


这就是一个简易的操作系统代码(瞎说的),基于时间片调度,没有抢占,但是有任务优先级。也就100行。
https://www.zhihu.com/question/658017543

1.🚚 软件SPI读写W25Q64

接线图

CS(片选)接到PA4 ,DO(从机输出)接到PA6 ,CLK时钟接到PA5 ,DI(从机输入)接到PA7,当然我这里引脚其实并不是任意选的,实际上是接到了硬件SPI的引脚上,这样的话软件SPI和硬件SPI都可以任意切换。

PA6为上拉输出入,PA4,PA5 ,PA7为推挽输出
交换字节:W25Q64支持模式0和模式3,这里一般选择模式0

程序的整体框架:

在这里插入图片描述

指令集:读取ID号时序:起始,先交换发送指令9F,随后连续交换接收3个字节,停止
第一个字节是厂商ID,后两个是设备ID,其中设备ID高8位,表示存储器类型,低8位表示容量。

  • 💎第一个是写使能指令,发送一个指令码06
  • 💎第二个是读状态寄存器1,作用是判断芯片是不是忙状态,要读取BUSY位,是否置1,1表示芯片在忙,0表示芯片不忙了。还要实现一个等待BUSY为0的函数,调用这个函数,BUSY为1,进入等待;BUSY为0,函数执行完毕。
  • 💎第三个是页编程函数,先发送一个指令码02,再发3个字节的地址,最后发数据。
  • 💎第四个扇区擦除,执行扇区擦除,先发送指令20,再发送3个字节的地址,这样指定地址,所在的扇区就会擦除。

 

最后一个读取数据,流程是:交换发送指令03,再发送3个字节的地址,随后转入接收,就可以依次接收数据

MySPI.c

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


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

void MySPI_W_SCK(uint8_t bitValue)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_5, (BitAction)bitValue);
}


void MySPI_W_MOSI(uint8_t bitValue)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_7, (BitAction)bitValue);
}


uint8_t MySPI_R_MISO(void)
{
	return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6);
}

void MySPI_Init()
{
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef gpioInitStructure;
	gpioInitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	gpioInitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7;
	gpioInitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &gpioInitStructure);
	
	gpioInitStructure.GPIO_Mode = GPIO_Mode_IPU;
	gpioInitStructure.GPIO_Pin = GPIO_Pin_6;
	gpioInitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &gpioInitStructure);
	
	
	
	MySPI_W_SS(1);
	MySPI_W_SCK(0);	//use SPI mode0
	
}

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

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

uint8_t MySPI_SwapByte(uint8_t byteSend)
{
	uint8_t byteRecv = 0;
	
	for(int i=0; i<8; i++)
	{
		MySPI_W_MOSI(byteSend & (0x80 >> i));		//SPI MOSI发送数据
		MySPI_W_SCK(1);								//SPI CLK上升沿
		if(MySPI_R_MISO()) byteRecv |= (0x80 >> i);	//SPI MISO读取数据
		MySPI_W_SCK(0);								//SPI下降沿
	}

	
	return byteRecv;
}

W25Q64.c

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

void W25Q64_Init(void)
{
	MySPI_Init();

}


void W25Q64_ReadID(uint8_t *MID, uint16_t *DID)
{
	uint8_t Data =  0;
	
	MySPI_Start();	//SPI Start
	
	MySPI_SwapByte(0x9F);
	*MID = MySPI_SwapByte(0xFF);
	Data = MySPI_SwapByte(0xFF);
	Data = Data<< 8 | MySPI_SwapByte(0xFF);
	*DID = Data;
	
	MySPI_Stop();	//SPI Stop
}

Main.c

#include "stm32f10x.h"                  // Device header
#include "oled.h"
#include "Countersensor.h"
#include "Encoder.h"
#include "Timer.h"
#include "AD.h"
#include "Delay.h"
#include "MyDMA.h"
#include "UART.h"
#include <stdio.h>
#include "Key.h"
#include "String.h"
#include "LED.h"
#include "MyI2C.h"
#include "MP6050.h"
#include "MP6050_Reg.h"
#include "W25Q64.h"



uint8_t MID;
uint16_t DID;

int main(int argc, char *argv[])
{

	
	OLED_Init();

	
	W25Q64_Init();
	W25Q64_ReadID(&MID, &DID);
	OLED_ShowHexNum(1, 1, MID, 2);
	OLED_ShowHexNum(1, 4, DID, 4);

	while(1)                                                                                 
	{

	}
	
	return 1;
}

💎现象
注意:写入数据前必须擦除,如不执行擦除,读出的数据=原始数据&写入的数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/910957.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

P5665 [CSP-S2019] 划分

P5665 [CSP-S2019] 划分 难度&#xff1a;省选/NOI-。 考点&#xff1a;单调队列、贪心、前缀和。 题意&#xff1a; 没有题目大意&#xff0c;本题题目描述较长&#xff0c;认真阅读每一个信息。 ​ 这个题的样例有 n n n 组数据&#xff0c;数据从 1 ∼ n 1 \sim n 1∼n…

ThreadX在STM32上的移植:F1,F4通用启动文件tx_initialize_low_level.s

在嵌入式系统开发中&#xff0c;实时操作系统&#xff08;RTOS&#xff09;的选择对于系统性能和稳定性至关重要。ThreadX是一种广泛使用的RTOS&#xff0c;它以其小巧、快速和可靠而闻名。在本文中&#xff0c;我们将探讨如何将ThreadX移植到STM32微控制器上&#xff0c;特别是…

RTT 内核基础学习

RT-Thread 内核介绍 内核是操作系统的核心&#xff0c;负责管理系统的线程、线程间通信、系统时钟、中断以及内存等。 内核位于硬件层之上&#xff0c;内核部分包括内核库、实时内核实现。 内核库是为了保证内核能够独立运行的一套小型的类似C库的函数实现子集。 这部分根据编…

qt QPixmapCache详解

1、概述 QPixmapCache是Qt框架中提供的一个功能强大的图像缓存管理工具类。它允许开发者在全局范围内缓存QPixmap对象&#xff0c;从而有效减少图像的重复加载&#xff0c;提高图像加载和显示的效率。这对于需要频繁加载和显示图像的用户界面应用来说尤为重要&#xff0c;能够…

纯css制作声波扩散动画、js+css3波纹催眠动画特效、【css3动画】圆波扩散效果、雷达光波效果完整代码

一、纯css制作声波扩散动画 参考文章&#xff1a;纯css制作声波扩散动画 播放效果通过音频状态来控制 效果如下 完整代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>波纹动画特效…

CocosCreator 构建透明背景应用(最新版!!!)

文章目录 透明原理补充设置截图以及代码step1: electron-js mian.jsstep2:ENABLE_TRANSPARENT_CANVASstep3:SOLID_COLOR Transparentstep:4 Build Web phonestep5:package electron-js & change body background-color 效果图补充 透明原理 使用Cocos creator 做桌面应用开…

在数据抓取的时候,短效IP比长效IP有哪些优势?

在数据抓取领域&#xff0c;代理IP的选择对于任务的成功率和效率至关重要。短效IP和长效IP各有其特点和适用场景&#xff0c;但在数据抓取过程中&#xff0c;短效IP因其独特的优势而受到青睐。本文将和大家一起探讨短效IP在数据抓取中相比长效IP的优势。 短效IP的定义与特点 …

FTP文件传输操作步骤

FTP文件传输操作步骤 步骤一&#xff1a;运行FTPServer.exe程序 步骤二、设置用户名和密码密码 步骤三、设置共享文件夹 步骤五、点击启动 步骤六、查看电脑ip(FTP server端) 步骤七、连接FTP 此电脑&#xff0c;地址栏输入&#xff1a;ftp://192.168.1.100 回车即可&…

【react使用AES对称加密的实现】

react使用AES对称加密的实现 前言使用CryptoJS库密钥存放加密方法解密方法结语 前言 项目中要求敏感信息怕被抓包泄密必须进行加密传输处理&#xff0c;普通的md5加密虽然能解决传输问题&#xff0c;但是项目中有权限的用户是需要查看数据进行查询的&#xff0c;所以就不能直接…

【网络原理】关于HTTP状态码以及请求的构造的哪些事

前言 &#x1f31f;&#x1f31f;本期讲解关于HTTP协议的重要的机制~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1f386;那么废话不…

苹果发布iOS 18.2首个公测版:Siri接入ChatGPT、iPhone 16拍照按钮有用了

今天凌晨&#xff0c;苹果正式发布了iOS 18.2首个公测版&#xff0c;将更多AI功能大批量推送给用户。其中最重要的就是Siri接入ChatGPT了&#xff0c;用户不必创建账户就可以免费使用ChatGPT&#xff0c;Siri将利用ChatGPT的专业知识回答用户问题&#xff0c;并在查询之前征求用…

前端 Canvas 绘画 总结

目录 一、使用案例 1、基础使用案例 2、基本案例改为直接JS实现 二、相关资料 1、API教程文档 2、炫酷案例 一、使用案例 1、基础使用案例 使用Canvas的基本步骤&#xff1a; 1、需要一个canvas标签 2、需要获取 画笔 对象 3、使用canvas提供的api进行绘图 <!--…

高级 <HarmonyOS主题课>借助AR引擎帮助应用实现虚拟与现实交互的能力的课后习题

持而盈之&#xff0c;不如其已&#xff1b; 揣而锐之&#xff0c;不可长保。 金玉满堂&#xff0c;莫之能守&#xff1b; 富贵而骄&#xff0c;自遗其咎。 功成身退&#xff0c;天之道也。 VR (Virtual Reality): 虚拟现实技术 AR (Augmented Reality): 增强现实) XR.(Extend…

tp接口 入口文件 500 错误原因

一、描述 二、可能的原因 1、runtime目录没权限 2、关闭了Tp记录日志的功能 3、关闭debug调试模式 4、关闭了debug模式还是报错 一、描述 Thinkphp项目本地正常&#xff0c;上传到线上后静态文件访问正常&#xff0c;访问tp接口报500错误。 经调试发现&#xff0c;在php入…

解决:ros进行gazebo仿真,rviz没有显示传感器数据

目录 前言解决总结 前言 看了很多urdf、xacro文件的编写&#xff0c;每次看了都觉得自己会了&#xff0c;然后自己写一点&#xff0c;就是废物了。 在我这里的案例是&#xff0c;我在一个大方块上面&#xff0c;添加了两个VLP-16的雷达&#xff0c;然后我想获取雷达扫描的数据…

C语言 | Leetcode C语言题解之第546题移除盒子

题目&#xff1a; 题解&#xff1a; int dp[100][100][100];int calculatePoints(int* boxes, int l, int r, int k) {if (l > r) {return 0;}if (dp[l][r][k] 0) {int r1 r, k1 k;while (r1 > l && boxes[r1] boxes[r1 - 1]) {r1--;k1;}dp[l][r][k] calcu…

基于开源 AI 智能名片、S2B2C 商城小程序的用户获取成本优化分析

摘要&#xff1a;本文围绕用户获取成本&#xff08;CAC&#xff09;这一关键指标展开深入剖析&#xff0c;详细阐述其计算方式&#xff0c;并紧密结合开源 AI 智能名片与 S2B2C 商城小程序的独特性质&#xff0c;从多个维度探讨如何通过挖掘新的获客渠道、巧妙运用私域流量池等…

实践出真知:MVEL表达式中for循环的坑

目录标题 背景MVEL脚本(有问题的)MVEL脚本(正确的)结论分析 背景 需要从一个URL的拼接参数中解析出id的值并输出 比如&#xff1a; 存在URLhttps://xxxxxxxxxx?id999999&type123&name345 然后需要输出id999999 MVEL脚本(有问题的) 入参&#xff1a;parseThisUrlhttp…

【C#】使用.net9在C#中向现有对象动态添加属性

在 C# 中向现有对象动态添加属性并不像在 Python 或 JavaScript 中那样容易&#xff0c;因为 C# 是一种强类型语言。 但是&#xff0c;我们可以通过使用一些技术和库来实现这一点&#xff0c;例如扩展方法、字典等。本文将详细介绍如何在 C# 中实现这一点。ExpandoObject 方法 …

工作流初始错误 泛微提交流程提示_泛微协同办公平台E-cology8.0版本后台维护手册(11)–系统参数设置

工作流初始错误 泛微提交流程提示_泛微协同办公平台E-cology8.0版本后台维护手册(11)–系统参数设置...-CSDN博客 工作流初始错误 泛微提交流程提示_泛微OA 工作流WebService接口使用说明 工作流初始错误 泛微提交流程提示_泛微OA 工作流WebService接口使用说明-CSDN博客 工作…