【STM32学习】——续上:软件SPI读写W25Q64SPI通信外设硬件SPI读写W25Q64

 四、软件SPI读写W25Q64

工程思路与I2C类似,MySPI.c是通信底层,主要包括通信引脚封装、初始化、SPI通信的三个拼图(起始、终止和交换一个字节);基于此文件建立W25Q64.c,调用MySPI三个拼图,拼接成各种指令和功能的完整时序,如写使能、擦除、页编程、读数据等,可看作W25Q64芯片的硬件驱动层。在主函数调用驱动层函数:

//MySPI.c
#include "stm32f10x.h"  void MySPI_W_SS(uint8_t BitValue){//SS或CS,片选或从机选择。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(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;//推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4| GPIO_Pin_5 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;//上拉输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);MySPI_W_SS(1);//初始化后默认电平MySPI_W_SCK(0);//初始化后默认电平
}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 i,ByteReceive = 0x00;for(i=0;i<8;i++){MySPI_W_MOSI(ByteSend & (0x80)>> i);//放到线上。与从机同步的MySPI_W_SCK(1);//线上的数据被分别读走(交换)if(MySPI_R_MISO() == 1){ByteReceive |= (0x80 >> i);}//主机接收到的数据位存到ByteReceiveMySPI_W_SCK(0);}return ByteReceive;
}
//0x80 >> i的作用是用来挑出数据的某一位或者某几位(或屏蔽其他的无关位,是掩码操作思想)。好处是没改变传入参数ByteSend
//另一种更简洁的方法,但会改变ByteSend变量:
//uint8_t MySPI_SwapByte(uint8_t ByteSend){
//	uint8_t i;
//	for(i=0;i<8;i++){
//		MySPI_W_MOSI(ByteSend & 0x80);
//		ByteSend <<= 1;
//		MySPI_W_SCK(1);
//		if(MySPI_R_MISO() == 1){ByteSend |= 0x01;}
//			MySPI_W_SCK(0);
//	}
//	return ByteSend;//传入的参数变了,当作返回值返回
//}
//W25Q64.c
#include "stm32f10x.h"   
#include "MySPI.h"
#include "W25Q64_Ins.h"void W25Q64_Init(void){MySPI_Init();
}void W25Q64_ReadID(uint8_t* MID,uint16_t* DID){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){//等待忙MySPI_Start();MySPI_SwapByte(W25Q64_READ_STATUS_REGISTER_1);while((MySPI_SwapByte(W25Q64_DUMMY_BYTE)&0x01) == 0x01);//可设置等待时间,超时退出MySPI_Stop();
}void W25Q64_PageProgram(uint32_t Address,uint8_t* DataArray,uint16_t Count){//指定起始地址,给个数据数组和元素数量,就可帮我们发送数据(写)W25Q64_WriteEnable();//写使能(注意事项)uint16_t i;MySPI_Start();MySPI_SwapByte(W25Q64_PAGE_PROGRAM);MySPI_SwapByte(Address >> 16);MySPI_SwapByte(Address >>8);MySPI_SwapByte(Address);for(i=0;i<Count;i++){MySPI_SwapByte(DataArray[i]);}MySPI_Stop();W25Q64_WaitBusy();//等待Busy(注意事项)
}	void W25Q64_SectorErase(uint32_t Address){//擦除指定地址所在扇区(写)W25Q64_WriteEnable();//写使能(注意事项)MySPI_Start();MySPI_SwapByte(W25Q64_SECTOR_ERASE_4KB);MySPI_SwapByte(Address >> 16);MySPI_SwapByte(Address >>8);MySPI_SwapByte(Address);MySPI_Stop();W25Q64_WaitBusy();//等待Busy(注意事项)
}void W25Q64_ReadData(uint32_t Address,uint8_t* DataArray,uint32_t Count){//指定起始地址,给个接收数组和元素数量,就可帮我们读取数据(读)uint32_t i;MySPI_Start();MySPI_SwapByte(W25Q64_READ_DATA);MySPI_SwapByte(Address >> 16);MySPI_SwapByte(Address >>8);MySPI_SwapByte(Address);for(i=0;i<Count;i++){DataArray[i] = MySPI_SwapByte(W25Q64_DUMMY_BYTE);}MySPI_Stop();
}
//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);//写入0x01,0x02,0x03,0x04W25Q64_ReadData(0x000000,ArrayRead,4);//读出结果,实际上也是0x01,0x02,0x03,0x04OLED_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){}
}

五、SPI通信硬件外设

与I2C一样,除了软件读写方法,STM32内部也集成了硬件SPI收发电路,自动执行时钟生成、数据收发等功能,减轻CPU负担。

硬件手册的说明内容较为繁杂,可采用主线+分支的学习方法,先把简单的实现了,偏难知识点可不深究,后续再增加更多的功能&选择其他配置模式!下面加粗的是随后要代码实测的!

①可配置8位/16位数据帧、高位先行/低位先行。(串口是低位先行)

②时钟频率:外设时钟频率/(2,4,5,16,32,64,128,246)。最大72MHz/2=36MHz

③支持多主机模型、主或从操作。可精简为半双工/单工通信。支持DMA。

④兼容I2S协议:I2S是一种音频传输协议。

这里使用得STM32F103C8T6芯片外设资源:SPI1、SPI2SPI1挂载在APB2,外设时钟频率是72MHz,SPI2挂载在APB1,外设时钟频率是36MHz。

如下为SPI硬件框图

大致可以分为两部分,左上角是数据寄存器和移位寄存器的配合过程,与串口、I2C等的设计思路相似,可对比学习,都是为了实现连续的数据流。核心部分是移位寄存器(右移状态 低位先行),即右侧的数据一位一位从MOSI移出,MISO的数据一位一位移到左侧数据高位;改变LSBFIRST控制位可变为高位先行。MOSI与MISO处方框的交叉线是为了切换为从机模式使用。接收缓冲区RDR发送缓冲区TDR,实际是同一地址统称数据寄存器DR,配合移位寄存器实现连续的数据流,过程如下:

发送数据从数据总线先到TDR,再转到移位寄存器发送,发送的同时接收数据,接收到的数据转到RDR,再从RDR读取数据到数据总线,与串口、I2C的设计相似,但也有些许不同。SPI是全双工,发送和接收是同步进行的,DR的发送和接收缓冲区是分离的,移位寄存器发送和接收可共用;I2C是半双工,发送和接收不同步进行,它的DR和移位寄存器都是共用的;串口是全双工,且发送和接收可异步进行,DR和移位寄存器都是分离的。

右下角是一些控制逻辑,“寄存器的哪些位,控制哪些部分,会产生哪些效果”可通过手册查阅。波特率发生器主要用来产生SCK时钟,内部主要是分频器,输入时钟是PCLK(72M/36M),经过分频后输出到SCK引脚,输出时钟与移位寄存器同步,一个周期移入/出1bit。SPI_CR1寄存器的三个位BR0、BR1、BR2用来控制分频系数,其他具体可看手册。

只保留核心部的简化图:(移位寄存器这里为左移)

如何产生具体的时序呢?什么时候写DR,什么时候读DR呢?

 传输模式主模式全双工连接传输(效率高、程序复杂)和非连续传输(程序简单,推荐初学者)!

上图示例使用的是SPI模式3,所以第一行SCK默认是高电平,在第一个下降沿,MOSI和MISO移出数据,上升沿移入数据;第二行是MOSI和MISO的输出波形,跟随时钟变化,可见示例演示的是低位先行模式,实际使用时高位先行更多;第三行TXE是发送寄存器空标志位;第四行为TDR;第五行BSY由硬件自动设置和清除。后面三行演示的是数据输入(接收数据)的时序。每一个关键点都引出在图下标注,可对照理解。


若没有强制需求,我们更倾向于使用下面的非连续传输,更加简单适合入门者,且对于程序设计非常友好,实际使用时只需要4行代码

这里只演示了输出数据(发送数据),没演示输入数据(接收数据)!区别在于当TXE为1时,不着急立即把下一个数据写进去,而是一直等待,等到第一个时序结束,意味着接收第一个字节也结束了,这时接收的RXNE会置1,先把第一个接收的数据读出来,之后再写入下一个数据。这样拖慢了传输速度,但简洁了流程。


六、硬件SPI读写W25Q64

线路连接和软件SPI一样,但是硬件SPI只有这以一种接法(根据芯片手册连接,不得任意选择),软件SPI的接线可以任意选择。

PA5是SPI1的SCK,所以接到了W25Q64的CLK引脚;PA6是MISO,接到了W25Q64的DO引脚;PA7是MOSI,接到了W25Q64的DI引脚,这几个不可接错。W25Q64的CS接到PA4,VCC和GND不必多说。

//main.c文件
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "W25Q64.h"uint8_t MID;							//定义用于存放MID号的变量
uint16_t DID;							//定义用于存放DID号的变量uint8_t ArrayWrite[] = {0x01, 0x02, 0x03, 0x04};	//定义要写入数据的测试数组
uint8_t ArrayRead[4];								//定义要读取数据的测试数组int main(void)
{/*模块初始化*/OLED_Init();						//OLED初始化W25Q64_Init();						//W25Q64初始化/*显示静态字符串*/OLED_ShowString(1, 1, "MID:   DID:");OLED_ShowString(2, 1, "W:");OLED_ShowString(3, 1, "R:");/*显示ID号*/W25Q64_ReadID(&MID, &DID);			//获取W25Q64的ID号OLED_ShowHexNum(1, 5, MID, 2);		//显示MIDOLED_ShowHexNum(1, 12, DID, 4);		//显示DID/*W25Q64功能函数测试*/W25Q64_SectorErase(0x000000);					//扇区擦除W25Q64_PageProgram(0x000000, ArrayWrite, 4);	//将写入数据的测试数组写入到W25Q64中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){}
}

时序如下W25Q64.c文件:

//W25Q64.c
#include "stm32f10x.h"                  // Device header
#include "MySPI.h"
#include "W25Q64_Ins.h"/*** 函    数:W25Q64初始化* 参    数:无* 返 回 值:无*/
void W25Q64_Init(void)
{MySPI_Init();					//先初始化底层的SPI
}/*** 函    数:MPU6050读取ID号* 参    数:MID 工厂ID,使用输出参数的形式返回* 参    数:DID 设备ID,使用输出参数的形式返回* 返 回 值:无*/
void W25Q64_ReadID(uint8_t *MID, uint16_t *DID)
{MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_JEDEC_ID);			//交换发送读取ID的指令*MID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);	//交换接收MID,通过输出参数返回*DID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);	//交换接收DID高8位*DID <<= 8;									//高8位移到高位*DID |= MySPI_SwapByte(W25Q64_DUMMY_BYTE);	//或上交换接收DID的低8位,通过输出参数返回MySPI_Stop();								//SPI终止
}/*** 函    数:W25Q64写使能* 参    数:无* 返 回 值:无*/
void W25Q64_WriteEnable(void)
{MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_WRITE_ENABLE);		//交换发送写使能的指令MySPI_Stop();								//SPI终止
}/*** 函    数:W25Q64等待忙* 参    数:无* 返 回 值:无*/
void W25Q64_WaitBusy(void)
{uint32_t Timeout;MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_READ_STATUS_REGISTER_1);				//交换发送读状态寄存器1的指令Timeout = 100000;							//给定超时计数时间while ((MySPI_SwapByte(W25Q64_DUMMY_BYTE) & 0x01) == 0x01)	//循环等待忙标志位{Timeout --;								//等待时,计数值自减if (Timeout == 0)						//自减到0后,等待超时{/*超时的错误处理代码,可以添加到此处*/break;								//跳出等待,不等了}}MySPI_Stop();								//SPI终止
}/*** 函    数:W25Q64页编程* 参    数:Address 页编程的起始地址,范围:0x000000~0x7FFFFF* 参    数:DataArray	用于写入数据的数组* 参    数:Count 要写入数据的数量,范围:0~256* 返 回 值:无* 注意事项:写入的地址范围不能跨页*/
void W25Q64_PageProgram(uint32_t Address, uint8_t *DataArray, uint16_t Count)
{uint16_t i;W25Q64_WriteEnable();						//写使能MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_PAGE_PROGRAM);		//交换发送页编程的指令MySPI_SwapByte(Address >> 16);				//交换发送地址23~16位MySPI_SwapByte(Address >> 8);				//交换发送地址15~8位MySPI_SwapByte(Address);					//交换发送地址7~0位for (i = 0; i < Count; i ++)				//循环Count次{MySPI_SwapByte(DataArray[i]);			//依次在起始地址后写入数据}MySPI_Stop();								//SPI终止W25Q64_WaitBusy();							//等待忙
}/*** 函    数:W25Q64扇区擦除(4KB)* 参    数:Address 指定扇区的地址,范围:0x000000~0x7FFFFF* 返 回 值:无*/
void W25Q64_SectorErase(uint32_t Address)
{W25Q64_WriteEnable();						//写使能MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_SECTOR_ERASE_4KB);	//交换发送扇区擦除的指令MySPI_SwapByte(Address >> 16);				//交换发送地址23~16位MySPI_SwapByte(Address >> 8);				//交换发送地址15~8位MySPI_SwapByte(Address);					//交换发送地址7~0位MySPI_Stop();								//SPI终止W25Q64_WaitBusy();							//等待忙
}/*** 函    数:W25Q64读取数据* 参    数:Address 读取数据的起始地址,范围:0x000000~0x7FFFFF* 参    数:DataArray 用于接收读取数据的数组,通过输出参数返回* 参    数:Count 要读取数据的数量,范围:0~0x800000* 返 回 值:无*/
void W25Q64_ReadData(uint32_t Address, uint8_t *DataArray, uint32_t Count)
{uint32_t i;MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_READ_DATA);			//交换发送读取数据的指令MySPI_SwapByte(Address >> 16);				//交换发送地址23~16位MySPI_SwapByte(Address >> 8);				//交换发送地址15~8位MySPI_SwapByte(Address);					//交换发送地址7~0位for (i = 0; i < Count; i ++)				//循环Count次{DataArray[i] = MySPI_SwapByte(W25Q64_DUMMY_BYTE);	//依次在起始地址后读取数据}MySPI_Stop();								//SPI终止
}

由于涉及的文件较多,这里不全部列举,下面是文件下载链接:

百度网盘打开icon-default.png?t=N7T8http://xn--https-bl8js66z7n7i//pan.baidu.com/s/1T0yRNeCorQgHZuZWtdnf7g?pwd=eqld%20%20%E6%8F%90%E5%8F%96%E7%A0%81%EF%BC%9Aeqld软硬件波形对比:

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flutter插件开发指南01: 通道Channel的编写与实现

Flutter插件开发指南01: 通道Channel的编写与实现 视频 https://www.bilibili.com/video/BV1ih4y1E7E3/ 前言 本文将会通过一个加法计算&#xff0c;来实现 Channel 的双向通讯&#xff0c;让大家有个一个体会。 Flutter插件 Flutter插件是Flutter应用程序与原生平台之间的桥…

ES6内置对象 - Set

Set&#xff08;es6提供的一种数据结构&#xff0c;类似数组&#xff0c;是一个集合&#xff0c;可以存储任何类型的元素且唯一、不重复&#xff0c;so,多用于元素去重&#xff09; 如上图&#xff0c;Set数据结构自带一些方法 1.Set对象创建 let a new Set([1,2,3,3,1,2,4,…

linux 系统的目录结构

为什么某些执行程序位于/bin、/sbin、/usr/bin或/usr/sbin目录下&#xff1f;例如&#xff0c;less命令位于/usr/bin目录下。为什么不是/bin、/sbin或/usr/sbin&#xff1f;这些目录之间有什么区别呢&#xff1f; 在这篇文章中&#xff0c;让我们主要讲述一下Linux文件系统结构…

【代码随想录算法训练营Day24】● 回溯法理论基础 ● 77. 组合

文章目录 Day 24 第七章 回溯算法part01理论基础什么是回溯使用原因 & 解决的问题如何理解回溯法 77. 组合思路剪枝代码 Day 24 第七章 回溯算法part01 今日内容&#xff1a; ● 理论基础● 77. 组合 理论基础 其实在讲解二叉树的时候&#xff0c;就给大家介绍过回溯&am…

计算机服务器中了DevicData勒索病毒怎么办?DevicData勒索病毒解密数据恢复

网络技术的发展与更新为企业提供了极大便利&#xff0c;让越来越多的企业走向了正规化、数字化&#xff0c;因此&#xff0c;企业的数据安全也成为了大家关心的主要话题&#xff0c;但网络是一把双刃剑&#xff0c;即便企业做好了安全防护&#xff0c;依旧会给企业的数据安全带…

python(23)——while循环

前言 在Python中&#xff0c;while 循环用于重复执行一段代码块&#xff0c;只要指定的条件保持为真&#xff08;True&#xff09;。一旦条件变为假&#xff08;False&#xff09;&#xff0c;循环就会终止。while 循环通常用于在不知道循环将执行多少次的情况下进行迭代。 w…

2024.02.22作业

1. 将互斥机制的代码实现重新敲一遍 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <time.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <…

世界顶级名校计算机专业学习使用教材汇总

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-IauYk2cGjEyljid0 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

GIS、RS、VORS模型、CCDM模型、geodetecto、GWR模型集成的生态系统健康的耦合协调分析

详情V&#xff1a;gjt0312765817632教授如何集成多源数据&#xff0c;依托ArcGIS Pro和R语言环境&#xff0c;采用“活力-组织力-恢复力-贡献力”&#xff08;VORS&#xff09;模型定量测算生态系统健康指数&#xff08;EHI&#xff09;&#xff1b;如何从经济城镇化&#xff0…

瑞_Redis_初识Redis(含安装教程)

文章目录 1 初识Redis1.1 认识NoSQL1.1.1 结构化与非结构化1.1.2 关联和非关联1.1.3 查询方式1.1.4 事务1.1.5 总结 1.2 认识Redis1.2.1 介绍1.2.2 特征1.2.3 优势 1.3 安装Redis ★★★1.3.1 Linux安装Redis1.3.1.1 安装Redis依赖 1.3.2 Windows安装Redis1.3.2.1 安装步骤1.3.…

ETL快速拉取物流信息

我国作为世界第一的物流大国&#xff0c;但是在目前的物流信息系统还存在着几大的痛点。主要包括以下几个方面&#xff1a; 数据孤岛&#xff1a;有些物流企业各个部门之间的数据标准不一致&#xff0c;难以实现数据共享和协同&#xff0c;容易导致信息孤岛。 操作繁琐&#x…

数据结构D3作业

1. 2. 按位插入 void insert_pos(seq_p L,datatype num,int pos) { if(LNULL) { printf("入参为空&#xff0c;请检查\n"); return; } if(seq_full(L)1) { printf("表已满&#xff0c;不能插入\n"); …

unity学习(34)——角色选取界面(跨场景坑多)

先把SelectMenu中的camera的audio listener去掉。 现在还是平面&#xff0c;直接在camera下面添加两个panel即可&#xff0c;应该是用不到canvas了&#xff0c;都是2D的UI。 加完以后问题来了&#xff0c;角色选择界面的按钮跑到主界面上边了&#xff0c;而且现在账号密码都输…

CoordConv(NeurIPS 2018)

paper&#xff1a;An Intriguing Failing of Convolutional Neural Networks and the CoordConv Solution official implementation&#xff1a;https://github.com/uber-research/coordconv 存在的问题 本文揭示并分析了CNN在两种不同类型空间表示之间转换能力的欠缺&#…

远程连接 vscode 出错 “远程主机可能不符合 glibc 和 libstdc++ VS Code 服务器的先决条件”

原因&#xff1a; vscode 版本是 1.86&#xff0c;服务器上的 glibc 和 libstdc 版本不满足 要求(2.28 和 3.4.25)。 解决&#xff1a; 1、下载 1.85.2&#xff0c;解压直接运行 Code.exe。 2、回退 Remote-ssh 到 0.107.1。 参考&#xff1a; vscode 1.86版本远程ssh不兼容旧…

Leetcode155(设计最小栈)

例题&#xff1a; 分析&#xff1a; 题目要求我们必须在常数时间内检索到最小元素。 我们可以使用两个栈&#xff08;A、B&#xff09;来实现&#xff0c;A栈用来正常存储数据、弹出数据&#xff0c; B栈用于存储A栈中的最小元素&#xff0c;如下图&#xff1a; 刚开始&#…

Spring 类型转换、数值绑定与验证(一)— DataBinder

DataBinder 是Spring用于数据绑定、类型转换及验证的类。使用场景有&#xff1a;1&#xff09;xml配置文件定义bean,Spring 内部使用DataBinder 来完成属性的绑定&#xff1b;2&#xff09;Web请求参数绑定&#xff0c;在Spring MVC 中&#xff0c;Controller的方法参数通常会自…

Stable Diffusion 模型分享:Indigo Furry mix(人类与野兽的混合)

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十

开启智能互动新纪元——ChatGPT提示词工程的引领力

目录 提示词工程的引领力 高效利用ChatGPT提示词方法 提示词工程的引领力 近年来&#xff0c;随着人工智能技术的迅猛发展&#xff0c;ChatGPT提示词工程正逐渐崭露头角&#xff0c;为智能互动注入了新的活力。这一技术的引入&#xff0c;使得人机交流更加流畅、贴近用户需求&…

2.22作业

test.c #include "test.h" seq_p creat_list(){seq_p L(seq_p)malloc(sizeof(seq_list));if(LNULL){printf("申请空间失败\n");return 0;}L->len0;return L; } int seq_p_empt(seq_p L){if(LNULL){return -12;}return L->len0?1:0; } int seq_p_fu…