侵權投訴

完善資料讓更多小伙伴認識你,還能領取20積分哦, 立即完善>

3天內不再提示

STM32:SPI總線、W25Q64(FLASH)的詳細介紹

DS小龍哥-嵌入式技術 ? 來源:DS小龍哥-嵌入式技術 ? 作者:DS小龍哥-嵌入式技 ? 2022-03-03 17:06 ? 次閱讀

一、環境介紹

編程軟件: keil5

操作系統: win10

MCU型號: STM32F103ZET6

STM32編程方式: 寄存器開發 (方便程序移植到其他單片機)

SPI總線:STM32本身支持SPI硬件時序,本文示例代碼里同時采用模擬時序和硬件時序兩種方式讀寫W25Q64。

模擬時序更加方便移植到其他單片機,更加方便學習理解SPI時序,通用性更高,不分MCU;

硬件時序效率更高,每個MCU配置方法不同,依賴MCU硬件本身支持。

存儲器件: 采用華邦W25Q64 flash存儲芯片。

W25Q64這類似的Flash存儲芯片在單片機里、嵌入式系統里還是比較常見,可以用來存儲圖片數據、字庫數據、音頻數據、保存設備運行日志文件等。

二、華邦W25Q64介紹(FLASH存儲類型)

2.1 W25Q64芯片功能介紹

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

W25Q64是為系統提供一個最小空間、最少引腳,最低功耗的串行Flash存儲器,25Q系列比普通的串行Flash存儲器更靈活,性能更優越。

W25Q64支持雙倍/四倍的SPI,可以儲存包括聲音、文本、圖片和其他數據;芯片支持的工作電壓 2.7V 到 3.6V,正常工作時電流小于5mA,掉電時低于1uA,所有芯片提供標準的封裝。

W25Q64的內存空間結構: 一頁256字節,4K(4096 字節)為一個扇區,16個扇區為1塊,容量為8M字節,共有128個塊,2048 個扇區。

W25Q64每頁大小由256字節組成,每頁的256字節用一次頁編程指令即可完成。

擦除指令分別支持: 16頁(1個扇區)、128頁、256頁、全片擦除。


SPI 最高支持 80MHz,當用快讀雙倍/四倍指令時,相當于雙倍輸出時最高速率160MHz,四倍輸出時最高速率 320MHz。這個傳輸速率比得上8位和16位的并行Flash存儲器。

W25Q64支持 JEDEC 標準,具有唯一的 64 位識別序列號,方便區別芯片型號。

2.2 W25Q64芯片特性詳細介紹

●SPI串行存儲器系列
-W25Q64:64M 位/8M 字節
-W25Q16:16M 位/2M 字節
-W25Q32:32M 位/4M 字節
-每 256 字節可編程頁


●靈活的4KB扇區結構
-統一的扇區擦除(4K 字節)
-塊擦除(32K 和 64K 字節)
-一次編程 256 字節
-至少 100,000 寫/擦除周期
-數據保存 20 年

●標準、雙倍和四倍SPI
-標準 SPI:CLK、CS、DI、DO、WP、HOLD
-雙倍 SPI:CLK、CS、IO0、IO1、WP、HOLD
-四倍 SPI:CLK、CS、IO0、IO1、IO2、IO3

●高級的安全特點
-軟件和硬件寫保護
-選擇扇區和塊保護
-一次性編程保護(1)
-每個設備具有唯一的64位ID(1)

●高性能串行Flash存儲器
-比普通串行Flash性能高6倍
-80MHz時鐘頻率
-雙倍SPI相當于160MHz
-四倍SPI相當于320MHz
-40MB/S連續傳輸數據
-30MB/S隨機存?。?2字節)
-比得上16位并行存儲器

●低功耗、寬溫度范圍
-單電源 2.7V-3.6V
-工作電流 4mA,掉電<1μA(典型值)
-40℃~+85℃工作

2.3 引腳介紹

下面只介紹W25Q64標準SPI接口,因為目前開發板上的封裝使用的就是標準SPI接口。

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

引腳編號

引腳名稱

I/O

功能

1

/CS

I

片選端輸入

2

DO(IO1)

I/O

數據輸出(數據輸入輸出 1)*1

3

/WP(IO2)

I/O

寫保護輸入(數據輸入輸出 2)*2

4

GND

5

DI(IO0)

I/O

數據輸入(數據輸入輸出 0)*1

6

CLK

I

串行時鐘輸入

7

/HOLD(IO3)

I/O

保持端輸入(數據輸入輸出 3)*2

8

VCC

電源

2.2.1 SPI片選(/CS)引腳用于使能和禁止芯片操作

CS引腳是W25Q64的片選引腳,用于選中芯片;當CS為高電平時,芯片未被選擇,串行數據輸出(DO、IO0、IO1、IO2 和 IO3)引腳為高阻態。未被選擇時,芯片處于待機狀態下的低功耗,除非芯片內部在擦除、編程。當/CS 變成低電平,芯片功耗將增長到正常工作,能夠從芯片讀寫數據。上電后, 在接收新的指令前,/CS 必須由高變為低電平。上電后,/CS 必須上升到 VCC,在/CS 接上拉電阻可以完成這個操作。

2.2.2 串行數據輸入、輸出和 IOs(DI、DO 和 IO0、IO1、IO2、IO3)

W25Q64、W25Q16 和 W25Q32 支持標準 SPI、雙倍 SPI 和四倍 SPI。

標準的 SPI 傳輸用單向的 DI(輸入)引腳連續的寫命令、地址或者數據在串行時鐘(CLK)的上升沿時寫入到芯片內。

標準的SPI 用單向的 DO(輸出)在 CLK 的下降沿從芯片內讀出數據或狀態。

2.2.3 寫保護(/WP)

寫保護引腳(/WP)用來保護狀態寄存器。和狀態寄存器的塊保護位(SEC、TB、BP2、BP1 和BP0)和狀態寄存器保護位(SRP)對存儲器進行一部分或者全部的硬件保護。/WP 引腳低電平有效。當狀態寄存器 2 的 QE 位被置位了,/WP 引腳(硬件寫保護)的功能不可用。

2.2.4 保持端(/HOLD)

當/HOLD 引腳是有效時,允許芯片暫停工作。在/CS 為低電平時,當/HOLD 變為低電平,DO 引腳將變為高阻態,在 DI 和 CLK 引腳上的信號將無效。當/HOLD 變為高電平,芯片恢復工作。/HOLD 功能用在當有多個設備共享同一 SPI 總線時。/HOLD 引腳低電平有效。當狀態寄存器 2 的 QE 位被置位了,/ HOLD 引腳的功能不可用。

2.2.5 串行時鐘(CLK)

串行時鐘輸入引腳為串行輸入和輸出操作提供時序。(見 SPI 操作)。

設備數據傳輸是從高位開始,數據傳輸的格式為 8bit,數據采樣從第二個時間邊沿開始,空閑狀態時,時鐘線 clk 為高電平。

2.3 內部結構框架圖

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

2.4 W25Q64的標準SPI操作流程

W25Q64標準SPI總線接口包含四個信號: 串行時鐘(CLK)、片選端(/CS)、串行數據輸入(DI)和串行數據輸出(DO)。

DI輸入引腳在CLK的上升沿連續寫命令、地址或數據到芯片內。

DO輸出引腳在CLK的下降沿從芯片內讀出數據或狀態。

W25Q64分別支持SPI總線工作模式0和工作模式3。模式0和模式3的主要區別在于常態時的CLK信號不同;對于模式0來說,當SPI主機已準備好數據還沒傳輸到串行Flash中時,CLK信號常態為低;

設備數據傳輸是從高位開始,數據傳輸的格式為8bit,數據采樣從第二個時間邊沿開始,空閑狀態時,時鐘線clk為高電平。

2.5 部分控制和狀態寄存器介紹

2.5.1 W25Q64的指令表

指令名稱

字節 1

(代碼)

字節 2

字節 3

字節 4

字節 5

字節 6

寫使能

06h

write_enabled

禁止寫

04h

讀狀態寄存器 1

05h

(S7-S0)(2)

讀狀態寄存器 2

35h

(S15-S8)(2)

寫狀態寄存器

01h

(S7-S0)

(S15-S8)

頁編程

02h

A23-A16

A15-A8

A7-A0

(D7-D0)

四倍頁編程

32h

A23-A16

A15-A8

A7-A0

(D7-D0,…)(3)

塊擦除(64KB)

D8h

A23-A16

A15-A8

A7-A0

塊擦除(32KB)

52h

A23-A16

A15-A8

A7-A0

扇區擦除(4KB)

20h

A23-A16

A15-A8

A7-A0

全片擦除

C7h/60h

暫停擦除

75h

恢復擦除

7Ah

掉電模式

B9h

高性能模式

A3h

2.5.2 讀狀態寄存器1

狀態寄存器1的內部結構如下:

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

狀態寄存器1的S0位是當前W25Q64的忙狀態;為1的時候表示設備正在執行程序(可能是在擦除芯片)或寫狀態寄存器指令,這個時候設備將忽略傳來的指令, 除了讀狀態寄存器和擦除暫停指令外,其他寫指令或寫狀態指令都無效, 當 S0 為 0 狀態時指示設備已經執行完畢,可以進行下一步操作。

讀狀態寄存器1的時序如下:

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

讀取狀態寄存器的指令是 8 位的指令。發送指令之前,先將/CS 拉低,再發送指令碼“05 h” 或者“35h”。設備收到讀取狀態寄存器的指令后,將狀態信息(高位)依次移位發送出去,讀出的狀態信息,最低位為 1 代表忙,最低位為 0 代表可以操作,狀態信息讀取完畢,將片選線拉高。

讀狀態寄存器指令可以使用在任何時候,即使程序在擦除的過程中或者寫狀態寄存器周期正在進行中。這可以檢測忙碌狀態來確定周期是否完成,以確定設備是否可以接受另一個指令。

2.5.3 讀制造商ID和芯片ID

時序圖如下:

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

讀取制造商/設備 ID 指令可以讀取制造商 ID 和特定的設備 ID。讀取之前,拉低 CS 片選信號,接著發送指令代碼“90h” ,緊隨其后的是一個 24 位地址(A23-A0)000000h。 設備收到指令之后,會發出華邦電子制造商 ID(EFh) 和設備ID(w25q64 為 16h)。如果 24 位地址設置為 000001h ,設備 ID 會先發出,然后跟著制造商 ID。制造商和設備ID可以連續讀取。完成指令后,片選信號/ CS 拉高。

2.5.4 全片擦除(C7h/60h)

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

全芯片擦除指令,可以將整個芯片的所有內存數據擦除,恢復到 0XFF 狀態。寫入全芯片擦除指令之前必須執行設備寫使能(發送設備寫使能指令 0x06),并判斷狀態寄存器(狀態寄存器位最低位必須等于 0 才能操作)。發送全芯片擦除指令前,先拉低/ CS,接著發送擦除指令碼”C7h”或者是”60h”, 指令碼發送完畢后,拉高片選線 CS/,,并判斷狀態位,等待擦除結束。全片擦除指令盡量少用,擦除會縮短設備的壽命。

2.5.5 讀數據(03h)

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

讀取數據指令允許按順序讀取一個字節的內存數據。當片選 CS/拉低之后,緊隨其后是一個 24 位的地址(A23-A0)(需要發送 3 次,每次 8 個字節,先發高位)。芯片收到地址后,將要讀的數據按字節大小轉移出去,數據是先轉移高位,對于單片機,時鐘下降沿發送數據,上升沿接收數據。讀數據時,地址會自動增加,允許連續的讀取數據。這意味著讀取整個內存的數據,只要用一個指令就可以讀完。數據讀取完成之后,片選信號/ CS 拉高。

讀取數據的指令序列,如上圖所示。如果一個讀數據指令而發出的時候,設備正在擦除扇區,或者(忙= 1),該讀指令將被忽略,也不會對當前周期有什么影響。

三、SPI時序介紹

SPI是串行外設接口(Serial Peripheral Interface)的縮寫,是一種高速的,全雙工,同步的通信總線,并且在芯片的管腳上只占用四根線,節約了芯片的管腳,同時為PCB的布局上節省空間。

SPI是一種高速、高效率的串行接口技術,一共有4根線。通常由一個主模塊和一個或多個從模塊組成,主模塊選擇一個從模塊進行同步通信,從而完成數據的交換。SPI是一個環形結構,通信時需要至少4根線(在單向傳輸時3根線也可以)。分別是MISO(主設備數據輸入)、MOSI(主設備數據輸出)、SCLK(時鐘)、CS(片選)。
(1)MISO– Master Input Slave Output,主設備數據輸入,從設備數據輸出;
(2)MOSI– Master Output Slave Input,主設備數據輸出,從設備數據輸入;
(3)SCLK – Serial Clock,時鐘信號,由主設備產生;
(4)CS – Chip Select,從設備使能信號,由主設備控制。

其中,CS是從芯片是否被主芯片選中的控制信號,也就是說只有片選信號為預先規定的使能信號時(高電位或低電位),主芯片對此從芯片的操作才有效。這就使在同一條總線上連接多個SPI設備成為可能。接下來就負責通訊的3根線了。通訊是通過數據交換完成的,這里先要知道SPI是串行通訊協議,也就是說數據是一位一位的傳輸的。這就是SCLK時鐘線存在的原因,由SCLK提供時鐘脈沖,SDI,SDO則基于此脈沖完成數據傳輸。數據輸出通過 SDO線,數據在時鐘上升沿或下降沿時改變,在緊接著的下降沿或上升沿被讀取。完成一位數據傳輸,輸入也使用同樣原理。因此,至少需要8次時鐘信號的改變(上沿和下沿為一次),才能完成8位數據的傳輸。
時鐘信號線SCLK只能由主設備控制,從設備不能控制。這樣的傳輸方式有一個優點,在數據位的傳輸過程中可以暫停,也就是時鐘的周期可以為不等寬,因為時鐘線由主設備控制,當沒有時鐘跳變時,從設備不采集或傳送數據。SPI還是一個數據交換協議:因為SPI的數據輸入和輸出線獨立,所以允許同時完成數據的輸入和輸出。芯片集成的SPI串行同步時鐘極性和相位可以通過寄存器配置,IO模擬的SPI串行同步時鐘需要根據從設備支持的時鐘極性和相位來通訊。SPI通信原理比I2C要簡單,IIC有應答機制,可以確保數據都全部發送成。SPI接口沒有指定的流控制,沒有應答機制確認是否接收到數據,速度上更加快。

SPI總線通過時鐘極性和相位可以配置成4種時序:

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

STM32F103參考手冊,SPI章節介紹的時序圖:

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

SPI時序比較簡單,CPU如果沒有硬件支持,可以直接寫代碼采用IO口模擬,下面是模擬時序的示例的代碼:

完整工程代碼下載:https://download.csdn.net/download/xiaolong1126626497/19425042

SPI的模式1:
u8 SPI_ReadWriteOneByte(u8 tx_data)
{
	u8 i,rx_data=0;
	SCK=0; //空閑電平(默認初始化情況)
	for(i=0;i<8;i++)
	{
		/*1. 主機發送一位數據*/
		SCK=0;//告訴從機,主機將要發送數據
		if(tx_data&0x80)MOSI=1; //發送數據
		else MOSI=0;
		SCK=1; //告訴從機,主機數據發送完畢
		tx_data<<=1; //繼續發送下一位
		
		/*2. 主機接收一位數據*/
		rx_data<<=1; //默認認為接收到0
		if(MISO)rx_data|=0x01;
	}
	SCK=0; //恢復空閑電平
	return rx_data;
}

SPI的模式2:
u8 SPI_ReadWriteOneByte(u8 tx_data)
{
	u8 i,rx_data=0;
	SCK=0; //空閑電平(默認初始化情況)
	for(i=0;i<8;i++)
	{
		/*1. 主機發送一位數據*/
		SCK=1;//告訴從機,主機將要發送數據
		if(tx_data&0x80)MOSI=1; //發送數據
		else MOSI=0;
		SCK=0; //告訴從機,主機數據發送完畢
		tx_data<<=1; //繼續發送下一位
		
		/*2. 主機接收一位數據*/
		rx_data<<=1; //默認認為接收到0
		if(MISO)rx_data|=0x01;
	}
	SCK=0; //恢復空閑電平
	return rx_data;
}


SPI的模式3:
u8 SPI_ReadWriteOneByte(u8 tx_data)
{
	u8 i,rx_data=0;
	SCK=1; //空閑電平(默認初始化情況)
	for(i=0;i<8;i++)
	{
		/*1. 主機發送一位數據*/
		SCK=1;//告訴從機,主機將要發送數據
		if(tx_data&0x80)MOSI=1; //發送數據
		else MOSI=0;
		SCK=0; //告訴從機,主機數據發送完畢
		tx_data<<=1; //繼續發送下一位
		
		/*2. 主機接收一位數據*/
		rx_data<<=1; //默認認為接收到0
		if(MISO)rx_data|=0x01;
	}
	SCK=1; //恢復空閑電平
	return rx_data;
}

SPI的模式4:
u8 SPI_ReadWriteOneByte(u8 tx_data)
{
	u8 i,rx_data=0;
	SCK=1; //空閑電平(默認初始化情況)
	for(i=0;i<8;i++)
	{
		/*1. 主機發送一位數據*/
		SCK=0;//告訴從機,主機將要發送數據
		if(tx_data&0x80)MOSI=1; //發送數據
		else MOSI=0;
		SCK=1; //告訴從機,主機數據發送完畢
		tx_data<<=1; //繼續發送下一位
		
		/*2. 主機接收一位數據*/
		rx_data<<=1; //默認認為接收到0
		if(MISO)rx_data|=0x01;
	}
	SCK=1; //恢復空閑電平
	return rx_data;
}
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

四、W25Q64的示例代碼

4.1 STM32采用硬件SPI讀寫W25Q64示例代碼

/*
函數功能:SPI初始化(模擬SPI)
硬件連接:
MISO--->PB14
MOSI--->PB15
SCLK--->PB13
*/
void SPI_Init(void)
{
	/*開啟時鐘*/
	RCC->APB1ENR|=1<<14;   //開啟SPI2時鐘
	RCC->APB2ENR|=1<<3;    //PB
	GPIOB->CRH&=0X000FFFFF; //清除寄存器
	GPIOB->CRH|=0XB8B00000;
	GPIOB->ODR|=0X7<<13;    	//PB13/14/15上拉--輸出高電平
	/*SPI2基本配置*/
	SPI2->CR1=0X0; 		//清空寄存器
	SPI2->CR1|=0<<15; //選擇“雙線雙向”模式
	SPI2->CR1|=0<<11; //使用8位數據幀格式進行發送/接收;
	SPI2->CR1|=0<<10; //全雙工(發送和接收);
	SPI2->CR1|=1<<9;  //啟用軟件從設備管理
	SPI2->CR1|=1<<8;  //NSS
	SPI2->CR1|=0<<7;  //幀格式,先發送高位
	SPI2->CR1|=0x0<<3;//當總線頻率為36MHZ時,SPI速度為18MHZ,高速。
	SPI2->CR1|=1<<2;  //配置為主設備
	SPI2->CR1|=1<<1;  //空閑狀態時, SCK保持高電平。
	SPI2->CR1|=1<<0;  //數據采樣從第二個時鐘邊沿開始。
	SPI2->CR1|=1<<6;  //開啟SPI設備。
}


/*
函數功能:SPI讀寫一個字節
*/
u8 SPI_ReadWriteOneByte(u8 data_tx)
{
    u16 cnt=0;				 
    while((SPI2->SR&1<<1)==0)		 //等待發送區空--等待發送緩沖為空	
    {
      cnt++;
      if(cnt>=65530)return 0; 	  //超時退出  u16=2個字節
    }	
    SPI2->DR=data_tx;	 	  		      //發送一個byte 
    cnt=0;
    while((SPI2->SR&1<<0)==0) 		//等待接收完一個byte   
    {
      cnt++;
      if(cnt>=65530)return 0;	   //超時退出
    }	  						    
    return SPI2->DR;          		//返回收到的數據	
}


/*
函數功能:W25Q64初始化
硬件連接:
MOSI--->PB15
MISO--->PB14
SCLK--->PB13
CS----->PB12
*/
void W25Q64_Init(void)
{
	/*1. 開時鐘*/
	RCC->APB2ENR|=1<<3; //PB
	
	/*2. 配置GPIO口模式*/
	GPIOB->CRH&=0xFFF0FFFF;
	GPIOB->CRH|=0x00030000;
	
	W25Q64_CS=1; //未選中芯片
	SPI_Init();   //SPI初始化
}


/*
函數功能:讀取芯片的ID號
*/
u16 W25Q64_ReadID(void)
{
	u16 id;
	/*1. 拉低片選*/
	W25Q64_CS=0;
	
	/*2. 發送讀取ID的指令*/
	SPI_ReadWriteOneByte(0x90);
	
	/*3. 發送24位的地址-0*/
	SPI_ReadWriteOneByte(0);
	SPI_ReadWriteOneByte(0);
	SPI_ReadWriteOneByte(0);
	
	/*4. 讀取芯片的ID*/
	id=SPI_ReadWriteOneByte(0xFF)<<8;
	id|=SPI_ReadWriteOneByte(0xFF);

	/*5. 拉高片選*/
	W25Q64_CS=1;
	return id;
}

/*
函數功能:檢測W25Q64狀態
*/
void W25Q64_CheckStat(void)
{
	u8 stat=1;
	while(stat&1<<0)
	{
		W25Q64_CS=0; //選中芯片
		SPI_ReadWriteOneByte(0x05);      //發送讀狀態寄存器1指令
		stat=SPI_ReadWriteOneByte(0xFF); //讀取狀態
		W25Q64_CS=1; //取消選中芯片
	}
}


/*
函數功能:頁編程
說    明:一頁最多寫256個字節。 寫數據之前,必須保證空間是0xFF
函數參數:
u32 addr:頁編程起始地址
u8 *buff:寫入的數據緩沖區
u16 len :寫入的字節長度
*/
void W25Q64_PageWrite(u32 addr,u8 *buff,u16 len)
{
	u16 i;
	W25Q64_Enabled();  						//寫使能
	W25Q64_CS=0; //選中芯片
	SPI_ReadWriteOneByte(0x02); //頁編程指令
	SPI_ReadWriteOneByte(addr>>16); //24~16地址
	SPI_ReadWriteOneByte(addr>>8);  //16~8地址
	SPI_ReadWriteOneByte(addr);     //8~0地址

	for(i=0;i>16); //24~16地址
	SPI_ReadWriteOneByte(addr>>8);  //16~8地址
	SPI_ReadWriteOneByte(addr);     //8~0地址
	for(i=0;i>16); //24~16地址
	SPI_ReadWriteOneByte(addr>>8);  //16~8地址
	SPI_ReadWriteOneByte(addr);     //8~0地址
	W25Q64_CS=1; 				//取消選中芯片
	W25Q64_CheckStat();  //檢測芯片忙狀態
}

/*
函數功能:寫使能
*/
void W25Q64_Enabled(void)
{
	W25Q64_CS=0; //選中芯片
	SPI_ReadWriteOneByte(0x06);     //寫使能
	W25Q64_CS=1; //取消選中芯片
}


/*
函數功能:指定位置寫入指定個數的數據,不考慮擦除問題
注意事項:W25Q64只能將1寫為,不能將0寫為1。
函數參數:
u32 addr---寫入數據的起始地址
u8 *buff---寫入的數據
u32 len---長度
*/
void W25Q64_WriteByteDataNoCheck(u32 addr,u8 *buff,u32 len)
{
	u32 page_remain=256-addr%256; //計算當前頁還可以寫下多少數據
	if(len<=page_remain) //如果當前寫入的字節長度小于剩余的長度
	{
		page_remain=len;
	}
	while(1)
	{
		W25Q64_PageWrite(addr,buff,page_remain);
		if(page_remain==len)break; //表明數據已經寫入完畢
		buff+=page_remain; //buff向后偏移地址
		addr+=page_remain; //起始地址向后偏移
		len-=page_remain;  //減去已經寫入的字節數
		if(len>256)page_remain=256;  //如果大于一頁,每次就直接寫256字節
		else page_remain=len;
	}
}


/*
函數功能:指定位置寫入指定個數的數據,考慮擦除問題,完善代碼
函數參數:
u32 addr---寫入數據的起始地址
u8 *buff---寫入的數據
u32 len---長度
說明:擦除的最小單位扇區,4096字節
*/
static u8 W25Q64_READ_WRITE_CHECK_BUFF[4096];
void W25Q64_WriteByteData(u32 addr,u8 *buff,u32 len)
{
    u32 i;
    u32 len_w;
    u32 sector_addr; //存放扇區的地址
    u32 sector_move; //扇區向后偏移的地址
    u32 sector_size; //扇區大小。(剩余的空間大?。?    u8 *p=W25Q64_READ_WRITE_CHECK_BUFF;//存放指針
    sector_addr=addr/4096; //傳入的地址是處于第幾個扇區
    sector_move=addr%4096; //計算傳入的地址存于當前的扇區的偏移量位置
    sector_size=4096-sector_move; //得到當前扇區剩余的空間

    if(len<=sector_size)
    {
            sector_size=len; //判斷第一種可能性、一次可以寫完
    }
    
    while(1)
    {
        W25Q64_ReadByteData(addr,p,sector_size);	 //讀取剩余扇區里的數據
        for(i=0;i4096)       //表明還可以寫一個扇區
        {
                sector_size=4096;//繼續寫一個扇區
        }
        else
        {
                sector_size=len; //剩余的空間可以寫完
        }
    }
}
;i++)>;i++)buff[i]=spi_readwriteonebyte(0xff);>;i++)>
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

4.2STM32采用硬件SPI讀寫W25Q64示例代碼

#include "spi.h"


/*
函數功能:SPI初始化(模擬SPI)
硬件連接:
MISO--->PB14
MOSI--->PB15
SCLK--->PB13
*/
void SPI_Init(void)
{
	/*1. 開時鐘*/
	RCC->APB2ENR|=1<<3; //PB

	/*2. 配置GPIO口模式*/
	GPIOB->CRH&=0x000FFFFF;
	GPIOB->CRH|=0x38300000;

	/*3. 上拉*/
	SPI_MOSI=1;
	SPI_MISO=1;
	SPI_SCLK=1;
}

/*
函數功能:SPI讀寫一個字節
*/
u8 SPI_ReadWriteOneByte(u8 data_tx)
{
	u8 data_rx=0; //存放讀取的數據
	u8 i;
	for(i=0;i<8;i++)
	{
		SPI_SCLK=0; //準備發送數據
		if(data_tx&0x80)SPI_MOSI=1;
		else SPI_MOSI=0;
		data_tx<<=1; //依次發送最高位
		SPI_SCLK=1;  //表示主機數據發送完成,表示從機發送完畢
		
		data_rx<<=1; //表示默認接收的是0
		if(SPI_MISO)data_rx|=0x01;
	}
	return data_rx;
}

#include "W25Q64.h"

/*
函數功能:W25Q64初始化
硬件連接:
MOSI--->PB15
MISO--->PB14
SCLK--->PB13
CS----->PB12
*/
void W25Q64_Init(void)
{
	/*1. 開時鐘*/
	RCC->APB2ENR|=1<<3; //PB
	
	/*2. 配置GPIO口模式*/
	GPIOB->CRH&=0xFFF0FFFF;
	GPIOB->CRH|=0x00030000;
	
	W25Q64_CS=1; //未選中芯片
	SPI_Init();   //SPI初始化
}


/*
函數功能:讀取芯片的ID號
*/
u16 W25Q64_ReadID(void)
{
	u16 id;
	/*1. 拉低片選*/
	W25Q64_CS=0;

	/*2. 發送讀取ID的指令*/
	SPI_ReadWriteOneByte(0x90);

	/*3. 發送24位的地址-0*/
	SPI_ReadWriteOneByte(0);
	SPI_ReadWriteOneByte(0);
	SPI_ReadWriteOneByte(0);

	/*4. 讀取芯片的ID*/
	id=SPI_ReadWriteOneByte(0xFF)<<8;
	id|=SPI_ReadWriteOneByte(0xFF);

	/*5. 拉高片選*/
	W25Q64_CS=1;
	return id;
}

/*
函數功能:檢測W25Q64狀態
*/
void W25Q64_CheckStat(void)
{
	u8 stat=1;
	while(stat&1<<0)
	{
		W25Q64_CS=0; //選中芯片
		SPI_ReadWriteOneByte(0x05);      //發送讀狀態寄存器1指令
		stat=SPI_ReadWriteOneByte(0xFF); //讀取狀態
		W25Q64_CS=1; //取消選中芯片
	}
}


/*
函數功能:頁編程
說    明:一頁最多寫256個字節。 寫數據之前,必須保證空間是0xFF
函數參數:
u32 addr:頁編程起始地址
u8 *buff:寫入的數據緩沖區
u16 len :寫入的字節長度
*/
void W25Q64_PageWrite(u32 addr,u8 *buff,u16 len)
{
	u16 i;
	W25Q64_Enabled();  						//寫使能
	W25Q64_CS=0; //選中芯片
	SPI_ReadWriteOneByte(0x02); //頁編程指令
	SPI_ReadWriteOneByte(addr>>16); //24~16地址
	SPI_ReadWriteOneByte(addr>>8);  //16~8地址
	SPI_ReadWriteOneByte(addr);     //8~0地址

	for(i=0;i>16); //24~16地址
	SPI_ReadWriteOneByte(addr>>8);  //16~8地址
	SPI_ReadWriteOneByte(addr);     //8~0地址
	for(i=0;i>16); //24~16地址
	SPI_ReadWriteOneByte(addr>>8);  //16~8地址
	SPI_ReadWriteOneByte(addr);     //8~0地址
	W25Q64_CS=1; 				//取消選中芯片
	W25Q64_CheckStat();  //檢測芯片忙狀態
}

/*
函數功能:寫使能
*/
void W25Q64_Enabled(void)
{
	W25Q64_CS=0; //選中芯片
	SPI_ReadWriteOneByte(0x06);     //寫使能
	W25Q64_CS=1; //取消選中芯片
}


/*
函數功能:指定位置寫入指定個數的數據,不考慮擦除問題
注意事項:W25Q64只能將1寫為,不能將0寫為1。
函數參數:
u32 addr---寫入數據的起始地址
u8 *buff---寫入的數據
u32 len---長度
*/
void W25Q64_WriteByteDataNoCheck(u32 addr,u8 *buff,u32 len)
{
	u32 page_remain=256-addr%256; //計算當前頁還可以寫下多少數據
	if(len<=page_remain) //如果當前寫入的字節長度小于剩余的長度
	{
		page_remain=len;
	}
	while(1)
	{
		W25Q64_PageWrite(addr,buff,page_remain);
		if(page_remain==len)break; //表明數據已經寫入完畢
		buff+=page_remain; //buff向后偏移地址
		addr+=page_remain; //起始地址向后偏移
		len-=page_remain;  //減去已經寫入的字節數
		if(len>256)page_remain=256;  //如果大于一頁,每次就直接寫256字節
		else page_remain=len;
	}
}


/*
函數功能:指定位置寫入指定個數的數據,考慮擦除問題,完善代碼
函數參數:
u32 addr---寫入數據的起始地址
u8 *buff---寫入的數據
u32 len---長度
說明:擦除的最小單位扇區,4096字節
*/
static u8 W25Q64_READ_WRITE_CHECK_BUFF[4096];
void W25Q64_WriteByteData(u32 addr,u8 *buff,u32 len)
{
	u32 i;
	u32 sector_addr; //存放扇區的地址
	u32 sector_move; //扇區向后偏移的地址
	u32 sector_size; //扇區大小。(剩余的空間大?。?	u8 *p=W25Q64_READ_WRITE_CHECK_BUFF;//存放指針
	sector_addr=addr/4096; //傳入的地址是處于第幾個扇區
	sector_move=addr%4096; //計算傳入的地址存于當前的扇區的偏移量位置
	sector_size=4096-sector_move; //得到當前扇區剩余的空間

	if(len<=sector_size)
	{
		sector_size=len; //判斷第一種可能性、一次可以寫完
	}

	while(1)
	{
		W25Q64_ReadByteData(addr,p,sector_size);	 //讀取剩余扇區里的數據
		for(i=0;i4096)       //表明還可以寫一個扇區
		{
			sector_size=4096;//繼續寫一個扇區
		}
		else
		{
			sector_size=len; //剩余的空間可以寫完
		}
	}
}
;i++)>;i++)buff[i]=spi_readwriteonebyte(0xff);>;i++)>
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png審核編輯:符乾江
收藏 人收藏

    評論

    相關推薦

    什么是使用 stm32單片機的拍手傳感器?

    安全系統通過測量不同的物理參數來工作。其中一個參數就是合理性。每一個移動的物體都會發出聲音和振動。這些聲音和振動可以被...
    發表于 04-03 11:11 ? 813次 閱讀
    什么是使用 stm32單片機的拍手傳感器?

    淺談STM32硬件I2C的使用

    STM32的硬件I2C很多人都對它望而卻步。因為很多電工都說,STM32 硬件 I2C有BUG、不穩定、死機等等……最后都使...
    發表于 04-03 10:55 ? 988次 閱讀
    淺談STM32硬件I2C的使用

    STM32芯片系統結構

    STM32芯片基于ARM公司的Cortex-M3內核,由ST公司設計生產,內核與總線矩陣之間有I(指....
    的頭像 STM32嵌入式開發 發表于 04-02 15:59 ? 577次 閱讀

    STM32的Flash寫了保護怎么辦?

    STM32還提供了一個特別的保護,即對Flash存儲區施加讀保護后,即使沒有啟用寫保護,Flash的....
    的頭像 STM32嵌入式開發 發表于 04-02 15:55 ? 149次 閱讀

    串口丟數據的幾個常見原因

    這幾個標志位在編程中經常使用,直接用函數庫的同學可能沒有關心過這幾個標志位,數據丟失有可能就是對它們....
    的頭像 凡億PCB 發表于 04-02 15:50 ? 919次 閱讀

    stm32把IMU測量數據通過nrf24l01無線通信 源程序

    [table] [tr][td]stm32把IMU測量數據通過nrf24l01無線通信,同時通過串口助手觀察通信是否成功。需要兩塊32的單片機進行通信...
    發表于 04-02 14:15 ? 624次 閱讀

    單片機項目: stm32低功耗模式分析

    在為應用選擇微控制器時,電源約束是設計者的一個關鍵考慮因素,尤其是在電源起著重要作用的物聯網應用中。物聯網節點只有在使...
    發表于 04-02 10:46 ? 655次 閱讀
    單片機項目: stm32低功耗模式分析

    RT-Thread組件RealTime Target Insight有何功能

    RealTime Target Insight是一個面向系統調試、優化的組件 它能夠獲得RT-Thread的運行信息,能夠找出相應段之間運行的時...
    發表于 04-02 10:28 ? 1384次 閱讀

    我想對STM32H743IIT用JLINK的secure chip進行加密,但是發現這個菜單是灰色的

    我想對STM32H743IIT用JLINK的secure chip進行加密,但是發現這個菜單是灰色的不能使用,請教下怎么解決? 1.我嘗試...
    發表于 04-02 10:23 ? 588次 閱讀

    制版沒有留PA9和PA10,不知道怎么寫程序

    我制版沒有留PA9和PA10,請問有什么辦法能夠寫程序嗎。我以為USB的D+和D-可以寫程序,后來發現不行。留了PA4,PA5,P...
    發表于 04-01 14:48 ? 914次 閱讀
    制版沒有留PA9和PA10,不知道怎么寫程序

    不能連接上STM32H7芯片的原因

    通過日??蛻舻募夹g支持整理,有兩種可能的根本原因可以導致這個問題。第一種可能性更大,與電源配置錯誤有....
    的頭像 STM32單片機 發表于 04-01 14:41 ? 206次 閱讀

    意法半導體STM32 ODE生態系統介紹

    快速、經濟的原型設計和開發STM32開放開發環境(ODE)在一個開放、靈活、簡單、經濟的開發環境下,....
    的頭像 意法半導體PDSA 發表于 04-01 14:04 ? 136次 閱讀

    PY32F030 中文數據手冊 V1.1

    PY32F030 系列微控制器采用高性能的 32 位 ARM? Cortex?-M0+內核,寬電壓工作范圍的 MCU。嵌入高達64Kbytes fla...
    發表于 04-01 10:44 ? 726次 閱讀

    STM32F407以太網在驅動層發送函數中死循環問題

    問題描述:芯片STM32F407ZGT6,RTT版本4.0.4。用tcp方式跟上位機建立長連接,心跳包10s一次,每次上電時通信正常,過1...
    發表于 04-01 10:36 ? 975次 閱讀
    STM32F407以太網在驅動層發送函數中死循環問題

    迅為STM32MP157開發板完全再現開發流程,從而降低學習門檻

    一款真正屬于自己的開發板作為迅為2022年的開年新品,STM32MP157開發板在發布之初所制定的方向就是:通過對開發流程進行完全...
    發表于 03-31 10:53 ? 1137次 閱讀
    迅為STM32MP157開發板完全再現開發流程,從而降低學習門檻

    稚暉君:配置CLion用于STM32開發

    Keil操作簡單,容易上手,而且可以很方便地進行調試。但是對于以前不是做嵌入式開發的軟件開發人員來說....
    的頭像 li5236 發表于 03-30 14:28 ? 211次 閱讀
    稚暉君:配置CLion用于STM32開發

    STM32微控制器產品技術參考手冊

      本手冊是STM32微控制器產品的技術參考手冊參照2009年12月 RM0008 Referenc....
    發表于 03-30 14:17 ? 49次 閱讀

    內存是怎么讀取數據的

    你知道內存是怎么讀取數據的嗎?知道數據是怎么一個一個字節發送的嗎?
    的頭像 電子工程世界 發表于 03-30 13:52 ? 179次 閱讀

    同步通信和異步通信有什么區別

    個人認為即便再過幾十年,目前市面上還能看到很多51內核的單片機,作為最基礎的型號,它是沒有那么快被淘....
    發表于 03-29 17:11 ? 59次 閱讀
    同步通信和異步通信有什么區別

    STM32CubeProgrammer和STM32CubeMonitor的新功能

    ST 近期推出新版本的 STM32CubeProgrammer、STM32CubeMonitor、S....
    的頭像 MCU開發加油站 發表于 03-25 11:29 ? 466次 閱讀

    STM32+BH1750光敏傳感器獲取光照強度

    使用IIC模擬時序驅動,方便移植到其他平臺,采集的光照度比較靈敏. 合成的光照度返回值范圍是 0~....
    的頭像 DS小龍哥-嵌入式技術 發表于 03-25 09:26 ? 309次 閱讀
    STM32+BH1750光敏傳感器獲取光照強度

    emwin開發教程免費下載

    emwin開發教程免費下載.用于窗口開發,st-emwin
    發表于 03-24 15:09 ? 20次 閱讀

    基于ARM內核的32位高級MCU的stm32f407中文手冊

      本參考手冊面向應用開發人員,提供有關使用 STM32F405xx/07xx、STM32F415x....
    發表于 03-24 15:07 ? 32次 閱讀

    C語言和STM32學習的一些學習筆記

    自己總結的一些C語言和STM32F1學習的一些筆記,適合想快速了解學習C語言和STM32單片機的同學
    發表于 03-24 14:53 ? 134次 閱讀

    如何使用STM32G031開發板實現雙通道示波器

    開啟Single后,無觸發時,正常顯示波形;觸發一次后,波形與頻譜均固定,并不會更新,但可以調整負時....
    的頭像 電子森林 發表于 03-22 09:57 ? 292次 閱讀

    STM32 HAL庫與標準庫的區別

    ??相比較早幾年使用標準庫開發來講,最近幾年HAL庫的使用是越來越多,那么我們開發應當使用哪一種呢,....
    的頭像 STM32嵌入式開發 發表于 03-22 09:13 ? 661次 閱讀

    利爾達與ST聯合發布STM32MP1開發板新品 利爾達硬核實力托底

    近日,致力于提供物聯網產品研發、技術應用、服務落地一站式解決方案的國家高新技術企業利爾達與ST意法半....
    的頭像 利爾達科技集團 發表于 03-21 19:04 ? 1122次 閱讀
    利爾達與ST聯合發布STM32MP1開發板新品 利爾達硬核實力托底

    單片機自學筆記 51單片機自學好找工作嗎

    自學不是說不可以,速成的話還是找一對一的比較好,建議學完51學STM32,51單片機也并不是很難,利....
    發表于 03-21 17:54 ? 78次 閱讀
    單片機自學筆記 51單片機自學好找工作嗎

    STM32F103rct6標準版的電路原理圖

    本文檔的主要內容詳細介紹的是STM32F103rct6標準版的電路原理圖免費下載。
    發表于 03-21 14:56 ? 146次 閱讀

    GD的抗干擾能力為何不如STM32

    GD32是國內開發的一款單片機,據說開發的人員是來自ST公司的,GD32也是以STM32作為模板做出....
    的頭像 電子工程世界 發表于 03-21 13:42 ? 711次 閱讀

    STM32+ULN2003驅動28BYJ4步進電機(正反轉)

    STM32驅動UL2003控制步進電機正反轉,根據角度轉動。
    的頭像 DS小龍哥-嵌入式技術 發表于 03-21 09:26 ? 1509次 閱讀
    STM32+ULN2003驅動28BYJ4步進電機(正反轉)

    STM32+ESP8266連接騰訊IOT微信小程序一鍵配網

    次我以智能鎖為產品模型,在騰訊物聯網平臺創建一個設備,使用STM32F103系統板+ESP8266+....
    的頭像 DS小龍哥-嵌入式技術 發表于 03-18 09:20 ? 3615次 閱讀
    STM32+ESP8266連接騰訊IOT微信小程序一鍵配網

    32位基于ARM微控制器STM32F101xx與STM32F103xx的固件函數庫

     本手冊介紹了32位基于ARM微控制器STM32F101xx與STM32F103xx的固件函數庫。
    發表于 03-17 14:42 ? 45次 閱讀

    STM32中CAN總線接口發送和接收數據

    CAN物理層的形式主要分為閉環總線及開環總線網絡兩種,一個適合于高速通訊,一個適合于遠距離通訊。CA....
    的頭像 MCU開發加油站 發表于 03-17 11:00 ? 610次 閱讀

    STM32G0復位后死機

    有客戶反映,STM32G071RBT6 在使用 STM32CubeProgrammer 燒錄完程序后....
    的頭像 STM32單片機 發表于 03-17 10:56 ? 330次 閱讀

    STM32: 介紹IIC總線、讀寫AT24C02(模擬時序)

    AT24C02系列支持I2C,總線數據傳送協議I2C,總線協議規定任何將數據傳送到總線的器件作為發送....
    的頭像 DS小龍哥-嵌入式技術 發表于 03-17 09:23 ? 2759次 閱讀
    STM32: 介紹IIC總線、讀寫AT24C02(模擬時序)

    stm32中常用關鍵字的使用方法

    extern,可以在一個文件中引用另一個文件中定義的變量或者函數,下面就結合具體的實例。
    的頭像 嵌入式應用開發 發表于 03-16 16:35 ? 448次 閱讀

    STM32: 采用IIC硬件時序讀寫AT24C08

    AT24C08 是串行CMOS類型的EEPROM存儲芯片,AT24C0x這個系列包含了AT24C01....
    的頭像 DS小龍哥-嵌入式技術 發表于 03-16 09:31 ? 1943次 閱讀
    STM32: 采用IIC硬件時序讀寫AT24C08

    STM32:編寫XPT2046電阻觸摸屏驅動(模擬SPI)

    XPT2046是一顆12位的ADC芯片,可以當做普通的ADC芯片使用,但是一般都是用在電阻觸摸屏上,....
    的頭像 DS小龍哥-嵌入式技術 發表于 03-15 09:13 ? 2574次 閱讀
    STM32:編寫XPT2046電阻觸摸屏驅動(模擬SPI)

    如何解決STM32芯片Flash寫保護的問題

    本文介紹了如何解決STM32芯片Flash寫保護導致無法下載程序,無法在線調試的問題;如果您遇到相同....
    的頭像 FPGA之家 發表于 03-14 17:24 ? 1111次 閱讀

    STM32: NEC紅外線協議解碼(超低成本無線傳輸方案)

    這是NEC協議的紅外線遙控器: 如果自己手機沒有紅外線遙控器的功能,可以淘寶上買一個小遙控器來學習....
    的頭像 DS小龍哥-嵌入式技術 發表于 03-14 09:48 ? 329次 閱讀
    STM32: NEC紅外線協議解碼(超低成本無線傳輸方案)

    STM32最小系統硬件組成部分

    最小系統為單片機工作的最低要求,不含外設控制,原理簡單,分析最小系統是STM32入門的基礎。
    的頭像 STM32嵌入式開發 發表于 03-12 14:17 ? 2715次 閱讀

    STM32設計智能居家-萬能紅外遙控器

    NEC協議在上篇文章里已經詳細介紹過了。這篇文章和上篇文章內容是連貫的,上篇文章完成NEC紅外線協議....
    的頭像 DS小龍哥-嵌入式技術 發表于 03-12 13:30 ? 806次 閱讀
    STM32設計智能居家-萬能紅外遙控器

    使用STM32、SFPGA和I.MX6ULL IO點亮LED燈

    摘要:你點亮過多少板子的LED燈呢?有很多小伙伴要求講一下STM32、FPGA、Liunx他們之間有....
    的頭像 嵌入式ARM 發表于 03-12 09:24 ? 644次 閱讀

    詳解STM32堆棧

    程序編譯之后,全局變量,靜態變量已經分配好內存空間,在函數運行時,程序需要為局部變量分配??臻g,當中....
    的頭像 硬件攻城獅 發表于 03-11 09:51 ? 419次 閱讀

    STM32+LWIP網絡協議棧移植(網卡采用DM9000)

    本篇文章主要講解如何在STM32F103工程里添加移植LWIP協議,最終完成TCP服務器、TCP客戶....
    的頭像 DS小龍哥-嵌入式技術 發表于 03-11 09:49 ? 1544次 閱讀
    STM32+LWIP網絡協議棧移植(網卡采用DM9000)

    如何實現軟硬件分層

    以STM32為例,打開網絡上下載的例程或者是購買開發板自帶的例程,都會發現應用層中會有stm32f1....
    的頭像 strongerHuang 發表于 03-10 17:32 ? 642次 閱讀

    第六屆STM32峰會將于2022年4月22日在深圳舉行

    ????????在智能化技術日臻成熟的今天,我們的生活被各類智能化應用悄然改變。在物聯網的基礎上加上....
    的頭像 意法半導體中國 發表于 03-10 11:21 ? 664次 閱讀

    STM32F103實現IAP在線升級應用程序

    實現IAP技術的核心是一段預先燒寫在單片機內部的IAP程序。這段程序主要負責與外部的上位機軟件進行握....
    的頭像 DS小龍哥-嵌入式技術 發表于 03-10 09:04 ? 1605次 閱讀
    STM32F103實現IAP在線升級應用程序

    ST-li<x>nk_V2驅動與在線升級工具

    ST-li<x>nk_V2驅動與在線升級工具免費下載。
    發表于 03-09 15:01 ? 50次 閱讀

    基于keil5新建STM32F10x寄存器版本工程

    前面文章分享了很多關于STM32F103系列知識點、物聯網相關的小項目,工程都采用的是寄存器方式編寫....
    的頭像 DS小龍哥-嵌入式技術 發表于 03-09 08:49 ? 1884次 閱讀
    基于keil5新建STM32F10x寄存器版本工程

    嵌入FPGA的國產通用MCU,如何使用其2K邏輯

    國產MCU中唯一內置FPGA邏輯的產品
    的頭像 MCU/FPGA by AGM 發表于 03-08 10:47 ? 543次 閱讀
    嵌入FPGA的國產通用MCU,如何使用其2K邏輯

    基于STM32完成FATFS文件系統移植與運用

    這篇文章主要演示FATFS文件系統如何移植到自己的工程,并完成文件的讀寫。 因為SD卡采用的是....
    的頭像 DS小龍哥-嵌入式技術 發表于 03-08 09:17 ? 1630次 閱讀
    基于STM32完成FATFS文件系統移植與運用

    AGM32 MCU Products List選型對標表

    詳細選型對標表
    的頭像 MCU/FPGA by AGM 發表于 03-07 14:06 ? 359次 閱讀

    基于STM32的DS18B20溫度傳感器設計

    DS18B20內置了64位產品序列號,方便識別身份,在一根線上可以掛接多個DS18B20傳感器,通過....
    的頭像 DS小龍哥-嵌入式技術 發表于 03-07 11:44 ? 745次 閱讀
    基于STM32的DS18B20溫度傳感器設計

    AGM Micro發布兼容STM32的MCU產品系列

    AGM Micro發布了兼容STM32的MCU產品系列,推出具有低延遲高靈活性的功能模塊MCU產品系....
    的頭像 MCU/FPGA by AGM 發表于 03-07 09:48 ? 343次 閱讀
    AGM Micro發布兼容STM32的MCU產品系列

    STM32 啟動流程的詳細講解

    開發環境: 處理器:STM32F103 MDK:5.30 STM32CubeMX:6.0.1 ? 對....
    的頭像 嵌入式大雜燴 發表于 03-06 15:26 ? 424次 閱讀
    STM32 啟動流程的詳細講解

    關于STM32的基礎知識

    1、AHB系統總線分為APB1(36MHz)和APB2(72MHz),其中2>1,意思是APB2接高....
    發表于 03-04 13:45 ? 81次 閱讀
    關于STM32的基礎知識

    stm32資料pdf資料免費下載

    、stm32f103系列和、stm32f4xx系列的參考文檔
    發表于 03-04 09:45 ? 67次 閱讀

    stm32--ADC操作源碼免費下載

    stm32--ADC操作源碼免費下載。
    發表于 03-04 09:42 ? 40次 閱讀
    俄罗斯一级婬片A片AAA毛片_国产一级婬片A片AAA毛片A级