国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【正點原子STM32連載】 第四十三章 SPI實驗 摘自【正點原子】APM32F407最小系統(tǒng)板使用指南

這篇具有很好參考價值的文章主要介紹了【正點原子STM32連載】 第四十三章 SPI實驗 摘自【正點原子】APM32F407最小系統(tǒng)板使用指南。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1)實驗平臺:正點原子stm32f103戰(zhàn)艦開發(fā)板V4
2)平臺購買地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套實驗源碼+手冊+視頻下載地址: http://www.openedv.com/thread-340252-1-1.html##

第四十三章 SPI實驗

本章將介紹使用APM32F407驅(qū)動板載的NOR Flash進(jìn)行讀寫操作。通過本章的學(xué)習(xí),讀者將學(xué)習(xí)到使用SPI驅(qū)動NOR Flash的使用。
本章分為如下幾個小節(jié):
43.1 硬件設(shè)計
43.2 程序設(shè)計
43.3 下載驗證

43.1 硬件設(shè)計
43.1.1 例程功能

  1. 按下KEY_UP和KEY0按鍵,分別對25Q128進(jìn)行數(shù)據(jù)的寫入和讀取操作,讀取到的數(shù)據(jù)會顯示至LCD
  2. 可通過USMART對25Q128進(jìn)行讀ID和芯片/扇區(qū)擦除的操作
  3. LED0閃爍,指示程序正在運(yùn)行
    43.1.2 硬件資源
  4. LED
    LED0 - PF9
  5. 按鍵
    KEY0 - PE4
    KEY_UP - PA0
  6. USART1(PA9、PA10連接至板載USB轉(zhuǎn)串口芯片上)
  7. 正點原子 2.8/3.5/4.3/7/10寸TFTLCD模塊(僅限MCU屏,16位8080并口驅(qū)動)
  8. SPI1
    SPI1_SCK - PB3
    SPI1_MISO - PB4
    SPI1_MOSI - PB5
  9. 25Q128
    F_CS - PB14
    43.1.3 原理圖
    本章實驗使用了板載的25Q128芯片,該芯片是一個NOR Flash,MCU是通過SPI與該NOR Flash進(jìn)行連接與通信的,該NOR Flash與MCU的連接原理圖,如下如圖所示:
    【正點原子STM32連載】 第四十三章 SPI實驗 摘自【正點原子】APM32F407最小系統(tǒng)板使用指南,stm32,嵌入式硬件,單片機(jī)

圖43.1.3.1 NOR Flash與MCU的連接原理圖
43.2 程序設(shè)計
43.2.1 Geehy標(biāo)準(zhǔn)庫的SPI驅(qū)動
本章實驗通過SPI1驅(qū)動NOR Flash,因此需要對SPI1進(jìn)行相應(yīng)的配置,并使用SPI1與NOR Flash進(jìn)行通信,其具體的步驟如下所示:
①:配置SPI1
②:使能SPI1
③:使用SPI1發(fā)送數(shù)據(jù)(接收數(shù)據(jù))前,等待SPI1發(fā)送緩沖區(qū)為空(接收緩沖區(qū)非空)
④:使用SPI1發(fā)送一字節(jié)數(shù)據(jù)
⑤:使用SPI1接收一字節(jié)數(shù)據(jù)
在Geehy標(biāo)準(zhǔn)庫中對應(yīng)的驅(qū)動函數(shù)如下:
①:配置SPI
該函數(shù)用于配置SPI,其函數(shù)原型如下所示:
void SPI_Config(SPI_T* spi, SPI_Config_T* spiConfig);
該函數(shù)的形參描述,如下表所示:
形參 描述
spi 指向SPI外設(shè)結(jié)構(gòu)體的指針
例如:SPI1、SPI2等(在apm32f4xx.h文件中有定義)
spiConfig 指向SPI配置結(jié)構(gòu)體的指針
需自行定義,并根據(jù)SPI的配置參數(shù)填充結(jié)構(gòu)體中的成員變量
表43.2.1.1 函數(shù)SPI_Config()形參描述
該函數(shù)的返回值描述,如下表所示:
返回值 描述
無 無
表43.2.1.2 函數(shù)SPI_Config()返回值描述
該函數(shù)使用SPI_Config_T類型的結(jié)構(gòu)體變量傳入SPI的配置參數(shù),該結(jié)構(gòu)體的定義如下所示:

typedef enum
{
    SPI_MODE_SLAVE,								/* 從機(jī)模式 */
    SPI_MODE_MASTER								/* 主機(jī)模式 */
} SPI_MODE_T;

typedef enum
{
    SPI_DATA_LENGTH_8B,							/* 8位數(shù)據(jù)格式 */
    SPI_DATA_LENGTH_16B							/*16位數(shù)據(jù)格式 */
} SPI_DATA_LENGTH_T;

typedef enum
{
    SPI_CLKPHA_1EDGE,							/* 在第一個時鐘邊沿進(jìn)行采樣 */
    SPI_CLKPHA_2EDGE								/* 在第二個時鐘邊沿進(jìn)行采樣 */
} SPI_CLKPHA_T;

typedef enum
{
    SPI_CLKPOL_LOW,								/* 時鐘信號空閑時為低電平 */
    SPI_CLKPOL_HIGH								/* 時鐘信號空閑時為高電平 */
} SPI_CLKPOL_T;

typedef enum
{
    SPI_NSS_HARD,								/* 硬件片選 */
    SPI_NSS_SOFT									/* 軟件片選 */
} SPI_NSS_T;

typedef enum
{
    SPI_FIRSTBIT_MSB,							/* MSB */
    SPI_FIRSTBIT_LSB								/* LSB */
} SPI_FIRSTBIT_T;

typedef enum
{
    SPI_DIRECTION_2LINES_FULLDUPLEX	= 0x0000,	/* 雙線全雙工 */
    SPI_DIRECTION_2LINES_RXONLY		= 0x0100,	/* 雙線僅接收 */
    SPI_DIRECTION_1LINE_RX			= 0x0001,	/* 單線僅接受 */
    SPI_DIRECTION_1LINE_TX			= 0x0011	/* 單線僅發(fā)送 */
} SPI_DIRECTION_T;

typedef enum
{
    SPI_BAUDRATE_DIV_2,							/*波特率2分頻 */
    SPI_BAUDRATE_DIV_4,							/*波特率4分頻 */
    SPI_BAUDRATE_DIV_8,							/*波特率8分頻 */
    SPI_BAUDRATE_DIV_16,						/*波特率16分頻 */
    SPI_BAUDRATE_DIV_32,						/*波特率32分頻 */
    SPI_BAUDRATE_DIV_64,						/*波特率64分頻 */
    SPI_BAUDRATE_DIV_128,						/*波特率128分頻 */
    SPI_BAUDRATE_DIV_256,						/*波特率256分頻 */
} SPI_BAUDRATE_DIV_T;

typedef struct
{
    SPI_MODE_T			mode;			/* 模式 */
    SPI_DATA_LENGTH_T	length;			/* 數(shù)據(jù)位長度 */
    SPI_CLKPHA_T			phase;			/* 采樣階段 */
    SPI_CLKPOL_T			polarity;		/* 時鐘線空閑極性 */
    SPI_NSS_T			nss;			/* 片選信號 */
    SPI_FIRSTBIT_T		firstBit;		/* 數(shù)據(jù)第一比特 */
    SPI_DIRECTION_T		direction;		/* 方向 */
    SPI_BAUDRATE_DIV_T	baudrateDiv;	/* 波特率分頻 */
    uint16_t				crcPolynomial;	/* CRC校驗值 */
} SPI_Config_T;
該函數(shù)的使用示例,如下所示:
#include "apm32f4xx.h"
#include "apm32f4xx_spi.h"

void example_fun(void)
{
    SPI_Config_T spi_init_struct;

    /* 配置SPI1 */
    spi_init_struct.mode			= SPI_MODE_MASTER;
    spi_init_struct.length			= SPI_DATA_LENGTH_8B;
    spi_init_struct.phase			= SPI_CLKPHA_2EDGE;
    spi_init_struct.polarity		= SPI_CLKPOL_HIGH;
    spi_init_struct.nss				= SPI_NSS_SOFT;
    spi_init_struct.firstBit		= SPI_FIRSTBIT_MSB;
    spi_init_struct.direction		= SPI_DIRECTION_2LINES_FULLDUPLEX;
    spi_init_struct.baudrateDiv		= SPI_BAUDRATE_DIV_256;
    spi_init_struct.crcPolynomial	= 7;
    SPI_Config(SPI1_SPI, &spi_init_struct);
}

②:使能SPI
該函數(shù)用于使能SPI,其函數(shù)原型如下所示:
void SPI_Enable(SPI_T* spi);
該函數(shù)的形參描述,如下表所示:
形參 描述
spi 指向SPI外設(shè)結(jié)構(gòu)體的指針
例如:SPI1、SPI2等(在apm32f4xx.h文件中有定義)
表43.2.1.3 函數(shù)SPI_Enable()形參描述
該函數(shù)的返回值描述,如下表所示:
返回值 描述
無 無
表43.2.1.4 函數(shù)SPI_Enable()返回值描述
該函數(shù)的使用示例,如下所示:

#include "apm32f4xx.h"
#include "apm32f4xx_spi.h"

void example_fun(void)
{
    /* 使能SPI1 */
    SPI_Enable(SPI1);
}

③:讀取SPI的狀態(tài)標(biāo)志
該函數(shù)用于讀取SPI的狀態(tài)標(biāo)志,其函數(shù)原型如下所示:
uint8_t SPI_I2S_ReadStatusFlag(SPI_T* spi, SPI_FLAG_T flag);
該函數(shù)的形參描述,如下表所示:
形參 描述
spi 指向SPI外設(shè)結(jié)構(gòu)體的指針
例如:SPI1、SPI2等(在apm32f4xx.h文件中有定義)
flag 指定的SPI狀態(tài)標(biāo)志
例如:SPI_FLAG_RXBNE、SPI_FLAG_TXBE等(在apm32f4xx_spi.h文件中有定義)
表43.2.1.5 函數(shù)SPI_I2S_ReadStatusFlag()形參描述
該函數(shù)的返回值描述,如下表所示:
返回值 描述
SET 事件標(biāo)志發(fā)生
RESET 事件標(biāo)志未發(fā)生
表43.2.1.6 函數(shù)SPI_I2S_ReadStatusFlag()返回值描述
該函數(shù)的使用示例,如下所示:

#include "apm32f4xx.h"
#include "apm32f4xx_spi.h"

void example_fun(void)
{
    uint8_t flag;

    /* 讀取SPI1的接收緩沖區(qū)非空標(biāo)志 */
    flag = SPI_I2S_ReadStatusFlag(SPI1, SPI_FLAG_RXBNE);
    if (flag == SET)
    {
        /* Do something. */
    }
    else
    {
        /* Do something. */
    }
}

④:SPI發(fā)送數(shù)據(jù)
該函數(shù)用于使用SPI發(fā)送數(shù)據(jù),其函數(shù)原型如下所示:
void SPI_I2S_TxData(SPI_T* spi, uint16_t data);
該函數(shù)的形參描述,如下表所示:
形參 描述
spi 指向SPI外設(shè)結(jié)構(gòu)體的指針
例如:SPI1、SPI2等(在apm32f4xx.h文件中有定義)
data 待發(fā)送的數(shù)據(jù)
表43.2.1.7 函數(shù)SPI_I2S_TxData()形參描述
該函數(shù)的返回值描述,如下表所示:
返回值 描述
無 無
表43.2.1.8 函數(shù)SPI_I2S_TxData()返回值描述
該函數(shù)的使用示例,如下所示:

#include "apm32f4xx.h"
#include "apm32f4xx_spi.h"

void example_fun(void)
{
    uint8_t data;
    
    data = 0x55;
    
    /* 使用SPI1發(fā)送1字節(jié)數(shù)據(jù) */
    SPI_I2S_TxData(SPI1, (uint16_t)data);
}

⑤:SPI接收數(shù)據(jù)
該函數(shù)用于接收SPI接收的數(shù)據(jù),其函數(shù)原型如下所示:
uint16_t SPI_I2S_RxData(SPI_T* spi);
該函數(shù)的形參描述,如下表所示:
形參 描述
spi 指向SPI外設(shè)結(jié)構(gòu)體的指針
例如:SPI1、SPI2等(在apm32f4xx.h文件中有定義)
表43.2.1.9 函數(shù)SPI_I2S_RxData()形參描述
該函數(shù)的返回值描述,如下表所示:
返回值 描述
uint16_t類型數(shù)據(jù) SPI接收的數(shù)據(jù)
表43.2.1.10 函數(shù)SPI_I2S_TxData()返回值描述
該函數(shù)的使用示例,如下所示:

#include "apm32f4xx.h"
#include "apm32f4xx_spi.h"

void example_fun(void)
{
    uint8_t data;
    
    /* 接收SPI1接收到的1字節(jié)數(shù)據(jù) */
    data = (uint8_t)SPI_I2S_RxData(SPI1);
    
    /* Do something. */
}

43.2.2 SPI驅(qū)動
本章實驗的SPI驅(qū)動主要負(fù)責(zé)向NOR Flash驅(qū)動提供SPI的各種操作函數(shù),例如:SPI初始化、SPI讀寫等。本章實驗中,SPI的驅(qū)動代碼包括spi.c和spi.h兩個文件。
SPI驅(qū)動中,對SPI、GPIO相關(guān)的宏定義,如下所示:

#define SPI1_SPI					SPI1
#define SPI1_SPI_CLK_ENABLE()								\
    do {														\
    		RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SPI1);	\
    } while (0)

#define SPI1_SCK_GPIO_PORT			GPIOB
#define SPI1_SCK_GPIO_PIN			GPIO_PIN_3
#define SPI1_SCK_GPIO_PIN_SOURCE	GPIO_PIN_SOURCE_3
#define SPI1_SCK_GPIO_AF			GPIO_AF_SPI1
#define SPI1_SCK_GPIO_CLK_ENABLE()							\
    do {														\
    		RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);	\
    } while (0)

#define SPI1_MISO_GPIO_PORT			GPIOB
#define SPI1_MISO_GPIO_PIN			GPIO_PIN_4
#define SPI1_MISO_GPIO_PIN_SOURCE	GPIO_PIN_SOURCE_4
#define SPI1_MISO_GPIO_AF			GPIO_AF_SPI1
#define SPI1_MISO_GPIO_CLK_ENABLE()						\
    do {														\
    		RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);	\
    } while (0)

#define SPI1_MOSI_GPIO_PORT			GPIOB
#define SPI1_MOSI_GPIO_PIN			GPIO_PIN_5
#define SPI1_MOSI_GPIO_PIN_SOURCE	GPIO_PIN_SOURCE_5
#define SPI1_MOSI_GPIO_AF			GPIO_AF_SPI1
#define SPI1_MOSI_GPIO_CLK_ENABLE()						\
    do {														\
    		RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);	\
    } while (0)
SPI驅(qū)動中,SPI的初始化函數(shù),如下所示:
/**
 * @brief	初始化SPI1
 * @param	無
 * @retval	無
 */
void spi1_init(void)
{
    GPIO_Config_T gpio_init_struct;
    SPI_Config_T spi_init_struct;
    
    /* 使能時鐘 */
    SPI1_SPI_CLK_ENABLE();			/* 使能SPI1時鐘 */
    SPI1_SCK_GPIO_CLK_ENABLE();		/* 使能SPI1 SCK引腳端口時鐘 */
    SPI1_MISO_GPIO_CLK_ENABLE();	/* 使能SPI1 MISO引腳端口時鐘 */
    SPI1_MOSI_GPIO_CLK_ENABLE();	/* 使能SPI1 MOSI引腳端口時鐘 */
    
    /* 配置SPI1 SCK引腳 */
    GPIO_ConfigPinAF(	SPI1_SCK_GPIO_PORT,			/* 配置SPI1 SCK引腳復(fù)用功能 */
    						SPI1_SCK_GPIO_PIN_SOURCE,
    						SPI1_SCK_GPIO_AF);
    gpio_init_struct.pin	= SPI1_SCK_GPIO_PIN;		/* SPI1 SCK引腳 */
    gpio_init_struct.mode	= GPIO_MODE_AF;				/* 復(fù)用功能模式 */
    gpio_init_struct.speed	= GPIO_SPEED_100MHz;		/* 高速 */
    gpio_init_struct.otype	= GPIO_OTYPE_PP;			/* 推挽輸出 */
    gpio_init_struct.pupd	= GPIO_PUPD_NOPULL;			/* 禁止上拉/下拉 */
    GPIO_Config(SPI1_SCK_GPIO_PORT, &gpio_init_struct);	/* 配置SPI1 SCK引腳 */
    
    /* 配置SPI1 MISO引腳 */
    GPIO_ConfigPinAF(	SPI1_MISO_GPIO_PORT,		/* 配置SPI1 MISO引腳復(fù)用功能 */
    						SPI1_MISO_GPIO_PIN_SOURCE,
    						SPI1_MISO_GPIO_AF);
    gpio_init_struct.pin	= SPI1_MISO_GPIO_PIN;			/* SPI1 MISO引腳 */
    gpio_init_struct.mode	= GPIO_MODE_AF;					/* 復(fù)用功能模式 */
    gpio_init_struct.speed	= GPIO_SPEED_100MHz;			/* 高速 */
    gpio_init_struct.otype	= GPIO_OTYPE_PP;				/* 推挽輸出 */
    gpio_init_struct.pupd	= GPIO_PUPD_NOPULL;				/* 禁止上拉/下拉 */
    GPIO_Config(SPI1_MISO_GPIO_PORT, &gpio_init_struct);	/* 配置SPI1 MISO引腳 */
    
    /* 配置SPI1 MOSI引腳 */
    GPIO_ConfigPinAF(	SPI1_MOSI_GPIO_PORT,		/* 配置SPI1 MOSI引腳復(fù)用功能 */
    						SPI1_MOSI_GPIO_PIN_SOURCE,
    						SPI1_MOSI_GPIO_AF);
    gpio_init_struct.pin	= SPI1_MOSI_GPIO_PIN;			/* SPI1 MOSI引腳 */
    gpio_init_struct.mode	= GPIO_MODE_AF;					/* 復(fù)用功能模式 */
    gpio_init_struct.speed	= GPIO_SPEED_100MHz;			/* 高速 */
    gpio_init_struct.otype	= GPIO_OTYPE_PP;				/* 推挽輸出 */
    gpio_init_struct.pupd	= GPIO_PUPD_NOPULL;				/* 禁止上拉/下拉 */
    GPIO_Config(SPI1_MOSI_GPIO_PORT, &gpio_init_struct);	/* 配置SPI1 MOSI引腳 */
    
    /* 配置SPI1 */
    spi_init_struct.mode			= SPI_MODE_MASTER;
    spi_init_struct.length			= SPI_DATA_LENGTH_8B;
    spi_init_struct.phase			= SPI_CLKPHA_2EDGE;
    spi_init_struct.polarity		= SPI_CLKPOL_HIGH;
    spi_init_struct.nss				= SPI_NSS_SOFT;
    spi_init_struct.firstBit		= SPI_FIRSTBIT_MSB;
    spi_init_struct.direction		= SPI_DIRECTION_2LINES_FULLDUPLEX;
    spi_init_struct.baudrateDiv		= SPI_BAUDRATE_DIV_256;
    spi_init_struct.crcPolynomial	= 7;
    SPI_Config(SPI1_SPI, &spi_init_struct);					/* 配置SPI1 */
    SPI_Enable(SPI1_SPI);									/* 使能SPI1 */
}

可以看到,該函數(shù)會配置并使能SPI1,同時也配置SPI使用的GPIO引腳的復(fù)用功能。
SPI驅(qū)動中,使用SPI傳輸1字節(jié)數(shù)據(jù)的函數(shù),如下所示:

/**
 * @brief	SPI1讀寫一個字節(jié)數(shù)據(jù)
 * @param	txdata: 待發(fā)送的一字節(jié)數(shù)據(jù)
 * @retval	接收到的一字節(jié)數(shù)據(jù)
 */
uint8_t spi1_read_write_byte(uint8_t txdata)
{
    uint8_t rxdata;
    
    /* 等待發(fā)送緩沖器為空 */
    while (SPI_I2S_ReadStatusFlag(SPI1_SPI, SPI_FLAG_TXBE) != SET);
    /* 發(fā)送一字節(jié)數(shù)據(jù) */
    SPI_I2S_TxData(SPI1_SPI, txdata);
    
    /* 等待接收緩沖非空 */
    while (SPI_I2S_ReadStatusFlag(SPI1_SPI, SPI_FLAG_RXBNE) != SET);
    /* 接收一字節(jié)數(shù)據(jù) */
    
    rxdata = SPI_I2S_RxData(SPI1_SPI);
    return rxdata;
}

使用SPI傳輸1字節(jié)數(shù)據(jù)就是先后發(fā)送并接收1字節(jié)數(shù)據(jù)。
43.2.3 NOR Flash驅(qū)動
本章實驗的NOR Flash驅(qū)動主要負(fù)責(zé)向應(yīng)用層提供NOR Flash的初始化和讀寫操作等函數(shù)。本章實驗中,NOR Flash的驅(qū)動代碼包括norflash.c和norflash.h兩個文件。
NOR Flash驅(qū)動中,對GPIO的相關(guān)宏定義,如下所示:

#define NORFLASH_CS_GPIO_PORT	GPIOB
#define NORFLASH_CS_GPIO_PIN	GPIO_PIN_14
#define NORFLASH_CS_GPIO_CLK_ENABLE()						\
    do {														\
    		RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);	\
    } while (0)

#define NORFLASH_CS(x) do { x ?											\
    		GPIO_SetBit(NORFLASH_CS_GPIO_PORT, NORFLASH_CS_GPIO_PIN) :		\
    		GPIO_ResetBit(NORFLASH_CS_GPIO_PORT, NORFLASH_CS_GPIO_PIN);	\
    } while (0)
NOR Flash驅(qū)動中,初始化NOR Flash的函數(shù),如下所示:
/**
 * @brief	初始化NOR Flash
 * @param	無
 * @retval	無
 */
void norflash_init(void)
{
    GPIO_Config_T gpio_init_struct;
    uint8_t temp;
    
    /* 使能時鐘 */
    NORFLASH_CS_GPIO_CLK_ENABLE();				/* 使能NOR Flash片選引腳端口時鐘 */
    
    /* 配置NOR Flash片選引腳 */
    gpio_init_struct.pin	= NORFLASH_CS_GPIO_PIN;	/* NOR Flash片選引腳 */
    gpio_init_struct.mode	= GPIO_MODE_OUT;		/* 通用輸出模式 */
    gpio_init_struct.speed	= GPIO_SPEED_100MHz;	/* 高速 */
    gpio_init_struct.otype	= GPIO_OTYPE_PP;		/* 推挽輸出 */
    gpio_init_struct.pupd	= GPIO_PUPD_UP;			/* 上拉 */
    GPIO_Config(NORFLASH_CS_GPIO_PORT, &gpio_init_struct);
    NORFLASH_CS(1);									/* 失能NOR Flash片選 */
    
    /* 配置SPI1接口 */
    spi1_init();							/* 初始化SPI1 */
    spi1_set_speed(SPI_SPEED_4);		/* 設(shè)置SPI1速度,84MHz/4=21MHz */
    
    g_norflash_type = norflash_read_id();/* 讀取NOR Flash芯片ID */
    if (g_norflash_type == W25Q256)		/* W25Q256需使能4字節(jié)地址模式 */
    {
    		temp = norflash_read_sr(3);		/* 讀狀態(tài)寄存器3,判斷地址模式 */
    		if ((temp & 0x01) == 0)			/* 如果不是4字節(jié)地址模式,則需進(jìn)行相應(yīng)配置 */
    		{
    			norflash_write_enable();	/* NOR Flash寫使能 */
    			temp |= (1 << 1);			/* ADP=1,配置上電4字節(jié)地址模式 */
    			norflash_write_sr(3, temp);	/* 寫狀態(tài)寄存器3 */
    			
    			NORFLASH_CS(0);				/* 使能NOR Flash片選 */
    			spi1_read_write_byte(NORFLASH_Enable4ByteAddr);/* 使能4字節(jié)地址模式 */
    			NORFLASH_CS(1);				/* 失能NOR Flash片選 */
    		}
    }
}

可以看到,在NOR Flash的初始化函數(shù)中,先初始化了控制NOR Flash片選的GPIO引腳,然后再是初始化與NOR Flash通訊的SPI并配置其通訊波特率,最后還會根據(jù)不同容量的NOR Flash做相應(yīng)的配置操作。
NOR Flash驅(qū)動中其他對NOR Flash的操作函數(shù),例如,NOR Flash的讀寫函數(shù)、擦除函數(shù)等,請讀者結(jié)合25Q128 NOR Flash芯片的數(shù)據(jù)手冊查看本實驗的配套實驗源碼。
43.2.4 實驗應(yīng)用代碼
本章實驗的應(yīng)用代碼,如下所示:

/* 待寫入NOR Flash的數(shù)據(jù) */
static const uint8_t g_text_buf[] = {"APM32 SPI TEST"};

/* 待寫入NOR Flash數(shù)據(jù)的長度 */
#define TEXT_SIZE sizeof(g_text_buf)

int main(void)
{
    uint16_t id;
    uint8_t t = 0;
    uint8_t key;
    uint8_t data[TEXT_SIZE];
    uint32_t flashsize;
    
    NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_3);	/* 設(shè)置中斷優(yōu)先級分組為組3 */
    sys_apm32_clock_init(336, 8, 2, 7);					/* 配置系統(tǒng)時鐘 */
    delay_init(168);										/* 初始化延時功能 */
    usart_init(115200);									/* 初始化串口 */
    usmart_dev.init(84);								/* 初始化USMART */
    led_init();											/* 初始化LED */
    lcd_init();											/* 初始化LCD */
    norflash_init();										/* 初始化NOR Flash */
    
    lcd_show_string(30, 50, 200, 16, 16, "APM32", RED);
    lcd_show_string(30, 70, 200, 16, 16, "SPI TEST", RED);
    lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
    lcd_show_string(30, 110, 200, 16, 16, "KEY_UP:Write  KEY0:Read", RED);
    
    id = norflash_read_id();							/* 讀NOR Flash芯片ID */
    while ((id == 0) || (id == 0xFFFF))					/* 檢測不到NOR Flash芯片 */
    {
    lcd_show_string(30, 130, 200, 16, 16, "NOR Flash Check Failed!", RED);
    delay_ms(500);
    lcd_show_string(30, 130, 200, 16, 16, "Please Check!          ", RED);
    delay_ms(500);
    LED0_TOGGLE();
    }
    /* NOR Flash檢測正常 */
    lcd_show_string(30, 130, 200, 16, 16, "NOR FLASH Ready!", BLUE);
    flashsize = 16 * 1024 * 1204;						/* NOR Flash容量為16MB */
    
    while (1)
    {
    		t++;
    		key = key_scan(0);
    		
    		if (key == WKUP_PRES)		/* 寫入數(shù)據(jù) */
    		{
    			lcd_fill(0, 150, 239, 319, WHITE);
    			lcd_show_string(30, 150, 200, 16, 16, "Start Write Flash....", BLUE);
    			sprintf((char *)data, "%s%d", (char *)g_text_buf, t);
    			/* 從倒數(shù)第100個地址處開始寫入TEXT_SIZE個字節(jié)的數(shù)據(jù) */
    			norflash_write((uint8_t *)data, flashsize - 100, TEXT_SIZE);
    			lcd_show_string(30, 150, 200, 16, 16, "Flash Write Finished!", BLUE);
    		}
    		else if (key == KEY0_PRES)	/* 讀取數(shù)據(jù) */
    		{
    			lcd_show_string(30, 150, 200, 16, 16, "Start Read FLASH... . ",BLUE);
    			/* 從倒數(shù)第100個地址處開始讀出TEXT_SIZE個字節(jié)的數(shù)據(jù) */
    			norflash_read(data, flashsize - 100, TEXT_SIZE);
    			lcd_show_string(30, 150, 200, 16, 16, "The Data Readed Is:   ",BLUE);
    			lcd_show_string(30, 170, 200, 16, 16, (char *)data, BLUE);
    		}
    		
    		if (t == 20)
    		{
    			LED0_TOGGLE();
    			t = 0;
    		}
    		
    		delay_ms(10);
    }
}

從本章實驗的應(yīng)用代碼中可以看到,在初始化完NOR Flash后,會檢測與NOR Flash的連接是否正常,若與NOR Flash的連接正常,則會不斷地等待按鍵輸入,若檢測到KEY_UP按鍵被按下,則會往NOR Flash的指定地址中寫入指定的數(shù)據(jù),若檢測KEY0按鍵被按下,則會從NOR Flash的指定地址中讀取數(shù)據(jù),并在LCD上進(jìn)行顯示。
43.3 下載驗證
在完成編譯和燒錄操作后,若MCU與NOR Flash的連接無誤,則可以在LCD上看到“NOR Flash Ready!”的提示信息,此時可以按下KEY_UP按鍵往NOR Flash的指定地址寫入指定的數(shù)據(jù),然后再按下KEY_0按鍵從NOR Flash的指定地址將寫入的數(shù)據(jù)讀回來在LCD上進(jìn)行顯示,此時便可以看到LCD上顯示“APM32 SPI TESTn”的提示信息,該提示信息就是從NOR Flash中讀回的數(shù)據(jù)。文章來源地址http://www.zghlxwxcb.cn/news/detail-719295.html

到了這里,關(guān)于【正點原子STM32連載】 第四十三章 SPI實驗 摘自【正點原子】APM32F407最小系統(tǒng)板使用指南的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包