基于STM32实现W25Q16读写操作(spi)

article/2025/11/7 13:37:54

文章目录

  • 前言
  • 一、W25Q16
    • 1.介绍
    • 2.SPI
      • 2.1. 简介
      • 2.2. 特性
      • 2.3. 功能说明
      • 2.4. 工作模式
      • 2.5. 引脚说明
  • 二、代码开发
    • 1.SPI初始化
    • 2.读取厂商ID
      • 2.1.读写字节
      • 2.2.读取ID
    • 3.其他的一些操作
    • 4.完整代码
  • 三、效果演示


前言

在之前我们学习了flash闪存,这个更多的是内部数据存储,容量也是会比较小。这次我们来学习一下更多的存储单元w25q16,顺便了解spi———串行外围设备接口。

一、W25Q16

1.介绍

在我们的核心板子上基本都会有这么一块芯片,只是有的容量会计较大,大家可以查看板子的原理图,如图所示:
在这里插入图片描述
有的板子可能是w25q32或者其他,后面的数字代表的是容量,用法都是一样的,从图中或者产品手册我们可以看到芯片是spi协议通信的。

2.SPI

2.1. 简介

串行外设接口 (SPI) 可与外部器件进行半双工/全双工的同步串行通信。该接口可配置为主模式,在这种情况下,它可为外部从器件提供通信时钟 (SCK)。该接口还能够在多主模式配置 下工作。

它可用于多种用途,包括基于双线的单工同步传输,其中一条可作为双向数据线,或使用CRC 校验实现可靠通信。

2.2. 特性

● 基于三条线的全双工同步传输
● 基于双线的单工同步传输,其中一条可作为双向数据线
● 8 位或 16 位传输帧格式选择
● 主模式或从模式操作
● 多主模式功能
● 8 个主模式波特率预分频器(最大值为 fPCLK/2)
● 从模式频率(最大值为 fPCLK/2)
● 对于主模式和从模式都可实现更快的通信
● 对于主模式和从模式都可通过硬件或软件进行 NSS 管理:动态切换主/从操作
● 可编程的时钟极性和相位
● 可编程的数据顺序,最先移位 MSB 或 LSB
● 可触发中断的专用发送和接收标志
● SPI 总线忙状态标志
● SPI TI 模式
● 用于确保可靠通信的硬件 CRC 功能:
— 在发送模式下可将 CRC 值作为最后一个字节发送
— 根据收到的最后一个字节自动进行 CRC 错误校验
● 可触发中断的主模式故障、上溢和 CRC 错误标志
● 具有 DMA 功能的 1 字节发送和接收缓冲器:发送和接收请求

2.3. 功能说明

在这里插入图片描述
通常,SPI 通过 4 个引脚与外部器件连接:

● MISO:主输入/从输出数据。此引脚可用于在从模式下发送数据和在主模式下接收数据。
● MOSI:主输出/从输入数据。此引脚可用于在主模式下发送数据和在从模式下接收数据。
● SCK:用于 SPI 主器件的串行时钟输出以及 SPI 从器件的串行时钟输入。
● NSS:从器件选择。这是用于选择从器件的可选引脚。

2.4. 工作模式

SPI总线有四种工作方式,其中使用的最为广泛的是模式0和模式3方式。

CPOL(Clock Polarity):时钟极性选择,为0时SPI总线空闲时,时钟线为低电平 ;为1时SPI总线空闲时,时钟线为高电平。

CPHA(Clock Phase):时钟相位选择,为0时在SCLK第一个跳变沿,主机对MISO引脚电平采样;为1时在SCLK第二个跳变沿,主机对MISO引脚电平采样。
在这里插入图片描述

在这里插入图片描述

2.5. 引脚说明

在这里插入图片描述

二、代码开发

1.SPI初始化

在原理图中我们可以看到板子上直接是使用了PB3、4、5、14引脚,接下来我们进行初始化。

void w25qxx_init(void)
{//PB硬件时钟使能	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);//配置PB3 PB5 PB14为输出模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_5|GPIO_Pin_14;		//第3 4 5根引脚GPIO_InitStructure.GPIO_Mode= GPIO_Mode_OUT;	//输出模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;	//推挽输出,增加输出电流能力。GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//高速响应GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	//没有使能上下拉电阻GPIO_Init(GPIOB,&GPIO_InitStructure);	//看时序图,工作在模式3,时钟线引脚PB3,初始电平为高电平PBout(3)=1;//看时序图,片选引脚PB14,初始电平为高电平	PBout(14)=1;	//PB4配置输入模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;		//第4根引脚GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN;		//输入模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;	//推挽输出,增加输出电流能力。GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//高速响应GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	//没有使能上下拉电阻GPIO_Init(GPIOB,&GPIO_InitStructure);		SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全双工SPI_InitStructure.SPI_Mode = SPI_Mode_Master;						//主机模式SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;				//8位数据位SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;						//SPI FLASH可以设置为高电平SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;					//MISO在第二边沿采样数据SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;						//片选引脚由代码控制SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //clk=84MHZ/8=10.5MHzSPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;		//以最高有效位发送SPI_Init(SPI1, &SPI_InitStructure);SPI_Cmd(SPI1, ENABLE);}

2.读取厂商ID

我们需要根据产品手册来进行这以操作,我们可以看到这样一张图(如下图),这可能看起来有点复杂,不知道从哪里下手,我们需要一点一点慢慢来。
在这里插入图片描述
我们将上下两张图拼接起来,其实是一张图,如下图:

在这里插入图片描述
这里可以把它分为7各部分。

2.1.读写字节

在这里插入图片描述
这里我们使用的是模式3,从图中可以看出需要从高位先写入,每次8位,读取也是一样的。

uint8_t spi1_send_byte(uint8_t byte)
{int32_t i=0;uint8_t d=0;for(i=7; i>=0; i--){//对byte每个bit进行判断if(byte & (1<<i)){//MOSI引脚输出高电平PBout(5)=1;}else{//MOSI引脚输出低电平PBout(5)=0;		}//时钟线输出低电平PBout(3)=0;//延时一会,MOSI引脚已经发送到对方delay_us(1);//时钟线输出高电平PBout(3)=1;//延时一会delay_us(1);	//读取MISO引脚电平if(PBin(4))d|=1<<i;}return d;
}

2.2.读取ID

按照时序图的说明我们编写出一下代码

void w25qxx_read_id(uint8_t *m_id,uint8_t *d_id)
{//片选引脚输出低电平PBout(14)=0;//发送90h命令spi1_send_byte(0x90);//发送24bit地址,该数值全为0spi1_send_byte(0x00);spi1_send_byte(0x00);spi1_send_byte(0x00);	//传递任意参数,读取厂商id*m_id=spi1_send_byte(0xFF);//传递任意参数,读取设备id*d_id=spi1_send_byte(0xFF);	//片选引脚输出高电平PBout(14)=1;	
}

3.其他的一些操作

在这里插入图片描述
在产品手册里有很多不同指令操作,这里不一一介绍,但是都和上面读取ID的操做差不多,如果有兴趣可以根据产品手册编写代码,下面会给出完整的代码,包括一些常见的操作。

4.完整代码

#include "stm32f4xx.h"
#include "sys.h"
#include <stdio.h>static GPIO_InitTypeDef 		GPIO_InitStructure;
static NVIC_InitTypeDef 		NVIC_InitStructure;
static USART_InitTypeDef 		USART_InitStructure;
static SPI_InitTypeDef  		SPI_InitStructure;#pragma import(__use_no_semihosting_swi)
struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
FILE __stdin;int fputc(int ch, FILE *f) {USART_SendData(USART1,ch);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);USART_ClearFlag(USART1,USART_FLAG_TXE);return ch;
}
void _sys_exit(int return_code) {}void delay_us(uint32_t n)
{SysTick->CTRL = 0; 			// Disable SysTick,关闭系统定时器SysTick->LOAD = (168*n)-1; // 配置计数值(168*n)-1 ~ 0SysTick->VAL  = 0; 		// Clear current value as well as count flagSysTick->CTRL = 5; 		// Enable SysTick timer with processor clockwhile ((SysTick->CTRL & 0x10000)==0);// Wait until count flag is setSysTick->CTRL = 0; 		// Disable SysTick	
}void delay_ms(uint32_t n)
{while(n--){SysTick->CTRL = 0; 				// Disable SysTick,关闭系统定时器SysTick->LOAD = (168000)-1; 	// 配置计数值(168000)-1 ~ 0SysTick->VAL  = 0; 		// Clear current value as well as count flagSysTick->CTRL = 5; 		// Enable SysTick timer with processor clockwhile ((SysTick->CTRL & 0x10000)==0);// Wait until count flag is set}SysTick->CTRL = 0; 		// Disable SysTick	}void usart1_init(uint32_t baud)
{//打开PA硬件时钟	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//打开串口1硬件时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//配置PA9和PA10为复用功能模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;		//第9 10根引脚GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF;	//多功能模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;	//推挽输出,增加输出电流能力。GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//高速响应GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	//没有使能上下拉电阻GPIO_Init(GPIOA,&GPIO_InitStructure);//将PA9和PA10引脚连接到串口1的硬件GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);	//配置串口1相关参数:波特率、无校验位、8位数据位、1个停止位......USART_InitStructure.USART_BaudRate = baud;										//波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b;						//8位数据位USART_InitStructure.USART_StopBits = USART_StopBits_1;							//1个停止位USART_InitStructure.USART_Parity = USART_Parity_No;								//无奇偶校验USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;	//无硬件流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;					//允许收发数据USART_Init(USART1, &USART_InitStructure);//配置串口1的中断触发方法:接收一个字节触发中断USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//配置串口1的中断优先级NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);//使能串口1工作USART_Cmd(USART1, ENABLE);
}void w25qxx_init(void)
{//PB硬件时钟使能	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);//配置PB3 PB5 PB14为输出模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_5|GPIO_Pin_14;		//第3 4 5根引脚GPIO_InitStructure.GPIO_Mode= GPIO_Mode_OUT;	//输出模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;	//推挽输出,增加输出电流能力。GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//高速响应GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	//没有使能上下拉电阻GPIO_Init(GPIOB,&GPIO_InitStructure);	//看时序图,工作在模式3,时钟线引脚PB3,初始电平为高电平PBout(3)=1;//看时序图,片选引脚PB14,初始电平为高电平	PBout(14)=1;	//PB4配置输入模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;		//第4根引脚GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN;		//输入模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;	//推挽输出,增加输出电流能力。GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//高速响应GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	//没有使能上下拉电阻GPIO_Init(GPIOB,&GPIO_InitStructure);		SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全双工SPI_InitStructure.SPI_Mode = SPI_Mode_Master;						//主机模式SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;				//8位数据位SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;						//SPI FLASH可以设置为高电平SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;					//MISO在第二边沿采样数据SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;						//片选引脚由代码控制SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //clk=84MHZ/8=10.5MHzSPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;		//以最高有效位发送SPI_Init(SPI1, &SPI_InitStructure);SPI_Cmd(SPI1, ENABLE);}uint8_t spi1_send_byte(uint8_t byte)
{int32_t i=0;uint8_t d=0;for(i=7; i>=0; i--){//对byte每个bit进行判断if(byte & (1<<i)){//MOSI引脚输出高电平PBout(5)=1;}else{//MOSI引脚输出低电平PBout(5)=0;		}//时钟线输出低电平PBout(3)=0;//延时一会,MOSI引脚已经发送到对方delay_us(1);//时钟线输出高电平PBout(3)=1;//延时一会delay_us(1);	//读取MISO引脚电平if(PBin(4))d|=1<<i;}return d;
}//读取w25qxxState Regist(状态寄存器)值
uint8_t w25qxx_read_SR()
{uint8_t RS1 = 0;//片选引脚输出低电平PBout(14)=0;//发送90h命令spi1_send_byte(0x05);//接收指定字节数据RS1=spi1_send_byte(0xFF);//片选引脚输出高电平PBout(14)=1;return RS1;
}//w25qxx读取数据
void w25qxx_read_data(uint8_t *data,uint32_t dataaddr,uint32_t size)
{int8_t i=0;//片选引脚输出低电平PBout(14)=0;//发送90h命令spi1_send_byte(0x03);//发送24bit地址,该数值全为0//例如发送地址:0x123456spi1_send_byte((uint8_t)(dataaddr>>16));spi1_send_byte((uint8_t)(dataaddr>>8));spi1_send_byte((uint8_t)dataaddr);	//接收指定字节数据for(i=0;i<size;i++)//传递任意参数,读取数据data[i]=spi1_send_byte(0xFF);//片选引脚输出高电平PBout(14)=1;	
}//w25qxx写使能
void w25qxx_write_enable()
{//片选引脚输出低电平PBout(14)=0;//发送90h命令spi1_send_byte(0x06);//片选引脚输出高电平PBout(14)=1;}//w25qxx写使不能
void w25qxx_write_disable()
{//片选引脚输出低电平PBout(14)=0;//发送90h命令spi1_send_byte(0x04);//片选引脚输出高电平PBout(14)=1;}//扇区擦除
void w25qxx_erase_sector(uint32_t sectoraddr)
{w25qxx_write_enable();PBout(14) = 0;//等待BUSY位清空//while(w25qxx_read_SR()&0x01 == 0x01);//发送扇区擦除命令spi1_send_byte(0x20);//发送24bit地址,该数值全为0spi1_send_byte((uint8_t)(sectoraddr>>16));spi1_send_byte((uint8_t)(sectoraddr>>8));spi1_send_byte((uint8_t)sectoraddr);PBout(14) = 1;	//等待BUSY位清空while(w25qxx_read_SR()&0x01 == 0x01);}void w25qxx_page_write(uint8_t *data,uint32_t dataaddr,uint16_t size)
{uint16_t i=0;//写使能w25qxx_write_enable();PBout(14) = 0;//发送页存储指令spi1_send_byte(0x02);//发送存储地址spi1_send_byte((uint8_t)(dataaddr>>16));spi1_send_byte((uint8_t)(dataaddr>>8));spi1_send_byte(dataaddr);//循环发送数据for(i=0;i<size;i++)spi1_send_byte(data[i]);PBout(14) = 1;//等待BUSY位清空while(w25qxx_read_SR()&0x01 == 0x01);	//添加写保护w25qxx_write_disable();}void w25qxx_read_id(uint8_t *m_id,uint8_t *d_id)
{//片选引脚输出低电平PBout(14)=0;//发送90h命令spi1_send_byte(0x90);//发送24bit地址,该数值全为0spi1_send_byte(0x00);spi1_send_byte(0x00);spi1_send_byte(0x00);	//传递任意参数,读取厂商id*m_id=spi1_send_byte(0xFF);//传递任意参数,读取设备id*d_id=spi1_send_byte(0xFF);	//片选引脚输出高电平PBout(14)=1;	
}int main(void)
{int32_t i=0;uint8_t m_id,d_id;uint8_t data[256] = {0};//使能(打开)端口F的硬件时钟,就是对端口F供电RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//串口1波特率:115200bpsusart1_init(115200);	//初始化GPIO引脚GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;		//第9根引脚GPIO_InitStructure.GPIO_Mode= GPIO_Mode_OUT;	//输出模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;	//推挽输出,增加输出电流能力。GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//高速响应GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	//没有使能上下拉电阻GPIO_Init(GPIOF,&GPIO_InitStructure);PFout(9)=1;//初始化SPI1连接的w25qxxw25qxx_init();w25qxx_read_id(&m_id,&d_id);printf("m_id=%x,d_id=%x\r\n",m_id,d_id);printf("read data at addr 0:\r\n");w25qxx_read_data(data,0,64);for(i=0;i<64;i++)printf("%02X ",data[i]);//扇区擦除printf("\r\nerase sector 0:\r\n");	w25qxx_erase_sector(0);printf("read data at addr 0:\r\n");	w25qxx_read_data(data,0,64);for(i=0;i<64;i++)printf("%02X ",data[i]);//页写入printf("write data at addr 0:\r\n");		for(i=0;i<256;i++)data[i]=0x88;w25qxx_page_write(data,0,256);printf("read data at addr 0:\r\n");	w25qxx_read_data(data,0,256);for(i=0;i<256;i++)printf("%02X ",data[i]);printf("\r\n");while(1){}
}void USART1_IRQHandler(void)
{uint8_t d;//检测标志位if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET){//接收数据d=USART_ReceiveData(USART1);//清空标志位USART_ClearITPendingBit(USART1,USART_IT_RXNE);}}

三、效果演示

这里还是使用串口来调试看我们做出来的效果,如下图所示:
在这里插入图片描述


http://chatgpt.dhexx.cn/article/ZJhkasVa.shtml

相关文章

GD32F303访问W25Q32异常问题解决

最近在使用国产化GD32F303替换STM32F103芯片&#xff0c;驱动代码使用的STM32的库函数&#xff0c;调试过程中发现MCU通过SPI访问W25Q32芯片时&#xff0c;会出现写入异常的情况&#xff0c;不是全部错误&#xff0c;是中间某段数据错误。 左侧&#xff1a;待写入文件内容 右侧…

stm32读写w25qxx

一&#xff0c;w25qxx简介。 二&#xff0c;stm32CubeIDE配置。 三&#xff0c;代码 1,w25qxx.c #include "W25Qxx.h"/*********************************************************************************** 函数功能: 模块初始化*/ uint8_t BSP_W25Qx_Init(void) …

STM32(八)W25Q(16/32/64/128)芯片学习总结

系列文章目录 文章目录 系列文章目录前言一、硬件和数据手册部分翻译1.W25Q64硬件设计2.数据手册解读 二、指令 前言 按项目需求&#xff0c;近期调试了W25Q32芯片&#xff0c;W25Q系列芯片是华邦公司推出的大容量SPI FLASH产品&#xff0c;W25Q32是3V&#xff0c;32M-bit 串行…

STC89C52驱动W25Q32测试笔记

STC89C52是经典的C51单片机&#xff0c;该芯片不自带硬件SPI接口&#xff0c;正好有手上一块W25Q32的存储模块&#xff08;某宝上买的2.2元&#xff09;&#xff0c;试着使用89C52模拟SPI接口驱动W25Q32&#xff0c;在驱动的过程中遇到了几个问题&#xff0c;首先的问题是电平不…

SPI Flash芯片W25Q32英文版数据手册解读(二)---------存储器知识,寄存器

接着上一篇文章&#xff0c;由于W25Q32芯片是一个存储器芯片&#xff0c;先对这个芯片有关存储器的一些概念进行解读。 一、存储器相关知识 1、存储器的三个单位&#xff1a; 存储器三个等级&#xff1a;页&#xff08;Page&#xff09;&#xff0c;扇区&#xff08;sector&a…

SPI Flash芯片W25Q32英文版数据手册解读(一)---------引脚功能,工作模式

W25Q32芯片是一个可以通过SPI&#xff08;串行外围设备接口&#xff09;操作的flash存储器&#xff0c;这篇文章备忘和总结一下英文版数据手册的一些解读。有关时序及具体用STC单片机编写程序的内容等下一篇文章。 一、芯片引脚功能 我买的是8引脚、SOIC封装的芯片&#xff0…

w25q32 内存分布

说明 ESP826612F/E里面使用w25q32作为了flash存储. 提前说下哈,bit代表位 也就是 0 1 0 1 , Bit代表字节 ,一字节就是8位 w25q32的容量是32Mbit 也就是 32/8 4MB字节 4*1024 4096KB字节 然后 w25q32 这个芯片规定每 64KB字节作为一个块 所以呢w25q32总共分成了 4096…

基于STM32+SPI+W25Qxx存储芯片指令,时序和函数讲解

前言 本次我们学习一下STM32F103关于SPI对存储芯片的读写&#xff0c;介绍W25QXX芯片和对芯片内部讲解和代码解读&#xff0c;学习W25QXX芯片的各种读写指令&#xff0c;操作芯片读写&#xff0c;认识底层驱动&#xff0c;本篇内容主要目的是教会大家看手册写代码&#xf…

ButterKnife9.0.0-rc2 配置

升级了AndroidStudio到3.4之后&#xff0c;发现项目中的很多依赖库都不能用&#xff0c;原因是随着AS升级之后&#xff0c;Gradle随之升级到3.4.1&#xff0c;很多第三方库也需要更高版本的支撑&#xff0c;今天遇到ButterKnife失效的问题&#xff0c;原本是8.5.1的版本&#x…

How to install Bromine3 RC2

When I install Bromine RC2, I met bellow issues: “Server could not contact itself at the specified address: 127.0.0.1:80” “Error: Database table jobs for model job was not found.” etc. Now I show my exact way to install RC2 successfully: 1. Downl…

fabric1.4.0-rc2快速入门

软件环境 VMware 10.0.4 CentOS-7-x86_64-Minimal-1708 搭建过程 go安装 docker安装 docker-compose安装 一、fabric的编译和安装 1. 创建目录&#xff08;GOPATH变量在安装go的时候就配置好了&#xff09; mkdir -p $GOPATH/src/github.com/hyperledger 2. 下载fabri…

Cocos2d-JS v3.0 RC2发布说明

Cocos2d-JS是Cocos2d-x的Javascript版本&#xff0c;融合了Cocos2d-html5和Cocos2d-x JavaScript Bindings。它支持Cocos2d-x的所有特性并提供更简单易用的Javascript风格API。 核心特性 极大改进了ccui控件布局库的性能和稳定性&#xff0c;ccui在RC0中被大幅度重构&#xff0…

【GCC】1: RTCP RR接收端生成

m79 代码。参考bytewoods 大神的以下文章:WebRTC 基于GCC的拥塞控制(上) WebRTC 基于GCC的拥塞控制(下)虽然可以拿到估算的带宽但是rtcp 总是malformed packet个 有必要带着问题跟进下整个过程 RR报文 基于丢包率的码率控制运行在发送端,依靠RTCP RR报文进行工作。* report b…

STM32之RCC

STM32 RCC复位与时钟配置&#xff0c;我首先忽略掉复位&#xff0c;首先学习时钟配置&#xff0c;复位以后用到再学习 STM32有多个时钟源&#xff0c;分别是 HSI:上电默认启动&#xff0c;因精度不高所以先不采用&#xff0c;以后如果需要再使用 HSE&#xff1a;外部高速时钟&…

Apache ShardingSphere 4.0.0-RC2发布

处暑无三日,新凉直万金。处暑之日,Apache ShardingSphere 4.0.0-RC2已经发布,欢迎测试使用&#xff01; 本次发布的4.0.0-RC2版本将前不久发布的4.0.0-RC1版本的核心功能不断打磨优化&#xff0c;修复社区反馈的问题&#xff0c;且持续进行微内核重构打磨&#xff1b;在社区建设…

macOS Ventura 13.4 RC2(22F63)发布

系统介绍 根据黑果魏叔官网提供&#xff1a;5 月 12 日消息&#xff0c;苹果今天面向开发人员&#xff0c;发布了 macOS Ventura 13.4 的第 2 个候选 RC 版本&#xff08;内部版本号 22F63&#xff09;&#xff0c;距离上个候选版本相隔数天时间。 macOS Ventura 带来了台前调…

.NET 6 RC2 版本发布

原文&#xff1a;bit.ly/3FS9xm7作者&#xff1a;Richard日期&#xff1a;2021-10-12翻译&#xff1a;精致码农-王亮说明&#xff1a;文中有大量的超链接&#xff0c;这些链接在公众号文章中被自动剔除&#xff0c;一部分包含超链接列表的小段落被我删减了&#xff0c;如果你对…

c#加密:三、对称加密 AES、DES、RC2、Rijndael

一、c#中的对称加密概述 对称加密算法在加密和解密时使用相同的密钥。Framework提供了四种对称加密算法。AES、DES、Rijndael、RC2。 DES&#xff1a;全称为Data Encryption Standard&#xff0c;即数据加密标准&#xff0c;是一种使用密钥加密的块算法&#xff0c;1977年被美…

MFC的.rc 和.rc2文件

一、介绍 rc和rc2都是资源文件,包含了应用程序中用到的所有的资源。它们两指向的是同一个资源。 两者不同在于&#xff1a;rc2文件中的资源可以直接在VS集成环境中以可视化的方法进行编辑和修改; 而rc中的资源是根据需要手工地进行编辑。 二、实例 工程 rc文件 #include …

SEO搜索引擎优化方式

SEO搜索引擎优化方式 SEO搜索引擎优化方式 文章目录 SEO搜索引擎优化方式[TOC](文章目录) 前言一、黑帽SEO1、关键字的堆叠2、隐藏文本3、门页 二、白帽SEO1、 TDK2、 提高网站语义化的html标签占比3、 SSR 总结 前言 利用搜索引擎的规则提高网站在有关搜索引擎内的自然排名&…