1.概述
本篇文章主要介紹如何使用e2studio對(duì)瑞薩進(jìn)行spi配置,同時(shí)移植stm32上的W25Q128到瑞薩上,同時(shí)通過對(duì)該FLASH進(jìn)行讀寫操作,驗(yàn)證是否正確。
2.硬件準(zhǔn)備
首先需要準(zhǔn)備一個(gè)開發(fā)板,這里我準(zhǔn)備的是芯片型號(hào) R7FA2L1AB2DFL 的開發(fā)板。
3.新建工程
4.工程模板
5.保存工程路徑
6.芯片配置
本文中使用R7FA2L1AB2DFL來進(jìn)行演示。
7
7.工程模板選擇
8.SPI配置
點(diǎn)擊Stacks->New Stack->Driver->Connectivity->SPI Driver on r_spi。
9.SPI屬性配置
10.片選CS管腳設(shè)置
設(shè)置P103管腳為輸出管腳,作為CS片選。
11.設(shè)置E2STUDIO堆棧
12.e2studio的重定向printf設(shè)置
C++ 構(gòu)建->設(shè)置->GNU ARM Cross C Linker->Miscellaneous去掉Other linker flags中的 “--specs=rdimon.specs”
13.printf輸出重定向到串口
打印最常用的方法是printf,所以要解決的問題是將printf的輸出重定向到串口,然后通過串口將數(shù)據(jù)發(fā)送出去。
注意一定要加上頭文件#include
#ifdef __GNUC__ //串口重定向
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
err = R_SCI_UART_Write(&g_uart0_ctrl, (uint8_t *)&ch, 1);
if(FSP_SUCCESS != err) __BKPT();
while(uart_send_complete_flag == false){}
uart_send_complete_flag = false;
return ch;
}
int _write(int fd,char *pBuffer,int size)
{
for(int i=0;i;i++)>
14.stm32移植瑞薩說明
在STM32的W25Qx.h中,有個(gè)片選定義,代碼如下。
#define W25Qx_Enable() HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET)
#define W25Qx_Disable() HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET)
修改后如下所示。
#define W25Qx_Enable() R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_03, BSP_IO_LEVEL_LOW);
#define W25Qx_Disable() R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_03, BSP_IO_LEVEL_HIGH);
在STM32的W25Qx.c中,有對(duì)數(shù)據(jù)進(jìn)行發(fā)送和接受,代碼如下。
/* Send the read status command */
HAL_SPI_Transmit(&hspi1, cmd, 1, W25Qx_TIMEOUT_VALUE);
/* Reception of the data */
HAL_SPI_Receive(&hspi1,&status, 1, W25Qx_TIMEOUT_VALUE);
修改后如下所示。
/* Send the read status command */
g_transfer_complete = false;
err = R_SPI_Write(&g_spi0_ctrl, cmd, 1, SPI_BIT_WIDTH_8_BITS);
assert(FSP_SUCCESS == err);
/* Wait for SPI_EVENT_TRANSFER_COMPLETE callback event. */
while ( g_transfer_complete==false)
{
;
}
/* Reception of the data */
g_transfer_complete = false;
err = R_SPI_Read(&g_spi0_ctrl, &status, 1, SPI_BIT_WIDTH_8_BITS);
assert(FSP_SUCCESS == err);
/* Wait for SPI_EVENT_TRANSFER_COMPLETE callback event. */
while ( g_transfer_complete==false)
{
;
}
15.W25Q128說明
W25Q128將16M的容量分為256個(gè)塊(Block),每個(gè)塊大小為64K字節(jié),每個(gè)塊又分為16個(gè)扇區(qū)(Sector),每個(gè)扇區(qū)4K個(gè)字節(jié)。W25Q128的最小擦除單位為一個(gè)扇區(qū),也就是每次必須擦除4K個(gè)字節(jié)。芯片ID如下所示。
0XEF13,表示芯片型號(hào)為W25Q80
0XEF14,表示芯片型號(hào)為W25Q16
0XEF15,表示芯片型號(hào)為W25Q32
0XEF16,表示芯片型號(hào)為W25Q64
0XEF17,表示芯片型號(hào)為W25Q128
16.演示效果
開機(jī)會(huì)打印W25Q128的ID,ID為0XEF17,實(shí)際如下所示。
并且之前保存的數(shù)據(jù)也正確讀取出來了。
定義數(shù)組DataBuff,其中DataBuff[0]表示寫入扇區(qū), DataBuff[1]表示寫入位置,剩下的為寫入數(shù)據(jù),同時(shí)以0xff結(jié)尾。
分別輸入數(shù)據(jù) 01 02 01 02 03 04 ff與02 20 aa bb cc dd ff
17.主程序代碼
#include "hal_data.h"
#include
#include "W25Qx.h"
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER
void uart1_data(void);
#define BUFFERSIZE 255 //可以接收的最大字符個(gè)數(shù)
uint8_t ReceiveBuff[BUFFERSIZE]; //接收緩沖區(qū)
uint8_t recv_end_flag = 0,Rx_len=0;//接收完成中斷標(biāo)志,接收到字符長度
uint8_t wData1[0x200];
uint8_t wData2[0x200];
uint8_t wData3[0x200];
uint8_t rData1[0x200];
uint8_t rData2[0x200];
uint8_t rData3[0x200];
uint8_t ID[4];
uint32_t i;
uint8_t flag[1] ;
int i_flag = 0;
fsp_err_t err = FSP_SUCCESS;
volatile bool uart_send_complete_flag = false;
uint8_t RxBuff[1]; //進(jìn)入中斷接收數(shù)據(jù)的數(shù)組
uint8_t DataBuff[5000]; //保存接收到的數(shù)據(jù)的數(shù)組
int RxLine=0; //接收到的數(shù)據(jù)長度
int Rx_flag=0; //接受到數(shù)據(jù)標(biāo)志
int Rx_flag_finish=0; //接受完成或者時(shí)間溢出
void user_uart_callback (uart_callback_args_t * p_args)
{
if(p_args->event == UART_EVENT_TX_COMPLETE)
{
uart_send_complete_flag = true;
}
if(p_args->event == UART_EVENT_RX_CHAR)
{
RxBuff[0] = p_args->data;
RxLine++; //每接收到一個(gè)數(shù)據(jù),進(jìn)入回調(diào)數(shù)據(jù)長度加1
DataBuff[RxLine-1]=RxBuff[0]; //把每次接收到的數(shù)據(jù)保存到緩存數(shù)組
Rx_flag=1;
Rx_len++;
if(RxBuff[0]==0xff) //接收結(jié)束標(biāo)志位,這個(gè)數(shù)據(jù)可以自定義,根據(jù)實(shí)際需求,這里只做示例使用,不一定是0xff
{
Rx_flag_finish=1;
Rx_len--;
}
RxBuff[0]=0;
}
}
#ifdef __GNUC__ //串口重定向
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
err = R_SCI_UART_Write(&g_uart1_ctrl, (uint8_t *)&ch, 1);
if(FSP_SUCCESS != err) __BKPT();
while(uart_send_complete_flag == false){}
uart_send_complete_flag = false;
return ch;
}
int _write(int fd,char *pBuffer,int size)
{
for(int i=0;ievent)
{
g_transfer_complete = true;
}
}
/*******************************************************************************************************************//**
* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
* is called by main() when no RTOS is used.
**********************************************************************************************************************/
void hal_entry(void)
{
/* TODO: add your own code here */
err = R_SCI_UART_Open(&g_uart1_ctrl, &g_uart1_cfg);
assert(FSP_SUCCESS == err);
err = R_SPI_Open(&g_spi0_ctrl, &g_spi0_cfg);
assert(FSP_SUCCESS == err);
printf("\r\n SPI-W25Q128 open\n");
/*##-1- Read the device ID ########################*/
BSP_W25Qx_Init();//初始化W25Q128
BSP_W25Qx_Read_ID(ID);//讀取ID
if((ID[0] != 0xEF) | (ID[1] != 0x17))
{
printf("SPI-W25Q128 error");
}
else//ID正確,打印ID
{
printf("W25Q128 ID : ");
for(i=0;i<2;i++)
{
printf("0x%02X ",ID[i]);
}
printf("\r\n\r\n");
}
/**************************讀取第1扇區(qū)數(shù)據(jù)**************************************************************/
/*##-3- Read the flash ########################*/
/*讀取數(shù)據(jù),rData讀取數(shù)據(jù)的指針,起始地址0x00,讀取數(shù)據(jù)長度0x200*/
if(BSP_W25Qx_Read(rData1,0x0,0x200)== W25Qx_OK)
printf("The first sector success\n");
else
printf("The first sector error\n");
/*打印數(shù)據(jù)*/
printf("The first sector data: \r\n");
for(i =0;i<0x200;i++)
{
if(i%20==0)
printf("\nThe first sector data[%d]--data[%d]: \r\n",i,i+19);
printf("0x%02X ",rData1[i]);
}
printf("\n");
/**************************讀取第2扇區(qū)數(shù)據(jù)**************************************************************/
/*##-3- Read the flash ########################*/
/*讀取數(shù)據(jù),rData讀取數(shù)據(jù)的指針,起始地址0x1000,讀取數(shù)據(jù)長度0x200*/
if(BSP_W25Qx_Read(rData2,0x1000,0x200)== W25Qx_OK)
printf("The second sector success\n");
else
printf("The second sector error\n");
/*打印數(shù)據(jù)*/
printf("The second sector data: \r\n");
for(i =0;i<0x200;i++)
{
if(i%20==0)
printf("\nThe second sector data[%d]--data[%d]: \r\n",i,i+19);
printf("0x%02X ",rData2[i]);
}
printf("\n");
/**************************讀取第3扇區(qū)數(shù)據(jù)**************************************************************/
/*##-3- Read the flash ########################*/
/*讀取數(shù)據(jù),rData讀取數(shù)據(jù)的指針,起始地址0x2000,讀取數(shù)據(jù)長度0x200*/
if(BSP_W25Qx_Read(rData3,0x2000,0x200)== W25Qx_OK)
printf("The third sector success\n");
else
printf("The third sector error\n");
/*打印數(shù)據(jù)*/
printf("The third sector data: \r\n");
for(i =0;i<0x200;i++)
{
if(i%20==0)
printf("\nThe third sector data[%d]--data[%d]: \r\n",i,i+19);
printf("0x%02X ",rData3[i]);
}
printf("\n");
/**************************清除第1扇區(qū)數(shù)據(jù)為0**************************************************************/
/*##-1- Erase Block ##################################*/
if(BSP_W25Qx_Erase_Block(0) == W25Qx_OK)
printf(" QSPI Erase Block ok\r\n");
else
printf("error\r\n");
/*##-1- Written to the flash ########################*/
/* fill buffer */
printf(" Clear the first sector data[0]--data[0x200]\r\n");
for(i =0;i<0x200;i ++)
{
wData1[i] = 0;
rData1[i] = 0;
}
/*寫入數(shù)據(jù),wData寫入數(shù)據(jù)的指針,起始地址0x00,寫入數(shù)據(jù)長度0x200*/
if(BSP_W25Qx_Write(wData1,0x00,0x200)== W25Qx_OK)
printf("Clear success\r\n");
else
printf("Clear error\r\n");
/*##-1- Read the flash ########################*/
/*讀取數(shù)據(jù),rData讀取數(shù)據(jù)的指針,起始地址0x00,讀取數(shù)據(jù)長度0x200*/
if(BSP_W25Qx_Read(rData1,0x00,0x200)== W25Qx_OK)
printf("Read the first sector data[0]--data[0x200]\r\n\r\n");
else
printf("Read error\r\n\r\n");
/*打印數(shù)據(jù)*/
printf("the first sector data[0]--data[0x200]: \r\n");
for(i =0;i<0x200;i++)
{
if(i%20==0)
printf("\ndata[%d]--data[%d]:\r\n",i,i+19);
printf("0x%02X ",rData1[i]);
}
printf("\n");
/**************************清除第2扇區(qū)數(shù)據(jù)為0**************************************************************/
/*##-2- Erase Block ##################################*/
if(BSP_W25Qx_Erase_Block(0x1000) == W25Qx_OK)
printf(" QSPI Erase Block ok\r\n");
else
printf("error\r\n");
/*##-2- Written to the flash ########################*/
/* fill buffer */
printf(" Clear the second sector data[0]--data[0x200]\r\n");
for(i =0;i<0x200;i ++)
{
wData2[i] = 0;
rData2[i] = 0;
}
/*寫入數(shù)據(jù),wData寫入數(shù)據(jù)的指針,起始地址0x1000,寫入數(shù)據(jù)長度0x200*/
if(BSP_W25Qx_Write(wData2,0x1000,0x200)== W25Qx_OK)
printf("Clear success\r\n");
else
printf("Clear error\r\n");
/*##-2- Read the flash ########################*/
/*讀取數(shù)據(jù),rData讀取數(shù)據(jù)的指針,起始地址0x00,讀取數(shù)據(jù)長度0x200*/
if(BSP_W25Qx_Read(rData2,0x1000,0x200)== W25Qx_OK)
printf("Read the second sector data[0]--data[0x200]\r\n\r\n");
else
printf("Read error\r\n\r\n");
/*打印數(shù)據(jù)*/
printf("the first sector data[0]--data[0x200]: \r\n");
for(i =0;i<0x200;i++)
{
if(i%20==0)
printf("\ndata[%d]--data[%d]:\r\n",i,i+19);
printf("0x%02X ",rData2[i]);
}
printf("\n");
/**************************清除第3扇區(qū)數(shù)據(jù)為0**************************************************************/
/*##-3- Erase Block ##################################*/
if(BSP_W25Qx_Erase_Block(0x2000) == W25Qx_OK)
printf(" QSPI Erase Block ok\r\n");
else
printf("error\r\n");
/*##-3- Written to the flash ########################*/
/* fill buffer */
printf(" Clear the third sector data[0]--data[0x200]\r\n");
for(i =0;i<0x200;i ++)
{
wData3[i] = 0;
rData3[i] = 0;
}
/*寫入數(shù)據(jù),wData寫入數(shù)據(jù)的指針,起始地址0x2000,寫入數(shù)據(jù)長度0x200*/
if(BSP_W25Qx_Write(wData3,0x2000,0x200)== W25Qx_OK)
printf("Clear success\r\n");
else
printf("Clear error\r\n");
/*##-3- Read the flash ########################*/
/*讀取數(shù)據(jù),rData讀取數(shù)據(jù)的指針,起始地址0x00,讀取數(shù)據(jù)長度0x200*/
if(BSP_W25Qx_Read(rData3,0x2000,0x200)== W25Qx_OK)
printf("Read the third sector data[0]--data[0x200]\r\n\r\n");
else
printf("Read error\r\n\r\n");
/*打印數(shù)據(jù)*/
printf("the first third data[0]--data[0x200]: \r\n");
for(i =0;i<0x200;i++)
{
if(i%20==0)
printf("\ndata[%d]--data[%d]:\r\n",i,i+19);
printf("0x%02X ",rData3[i]);
}
printf("\n");
while(1)
{
uart1_data();
R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT100->160
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
void uart1_data(void)
{
if(Rx_flag_finish ==1)//接收完成標(biāo)志
{
if(DataBuff[0]==0x01)
{
printf("LENGTH:%d\n",Rx_len-2);
for(int i =0;i;i++)>;i++)>
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。
舉報(bào)投訴
-
mcu
+關(guān)注
關(guān)注
146文章
17316瀏覽量
352229 -
ARM
+關(guān)注
關(guān)注
134文章
9164瀏覽量
368585 -
嵌入式
+關(guān)注
關(guān)注
5090文章
19176瀏覽量
306885 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5121瀏覽量
97973
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
瑞薩e2studio(1)----瑞薩芯片之搭建FSP環(huán)境
視頻教學(xué)
樣品申請(qǐng)
請(qǐng)勿添加外鏈
e2studio軟件
e2studio是瑞薩的集成開發(fā)環(huán)境,F(xiàn)SP 提供了眾多可提高效率的工具,用于開發(fā)針對(duì)瑞
發(fā)表于 09-30 15:28
STM32CUBEMX(13)--SPI,W25Q128外部Flash移植
上節(jié)省空間,提供方便,正是出于這種簡單易用的特性,越來越多的芯片集成了這種通信協(xié)議,比如 EEPROM,FLASH,實(shí)時(shí)時(shí)鐘,AD轉(zhuǎn)換器。 W25Q128 是一款SPI接口的Flash
發(fā)表于 09-30 14:41
物聯(lián)網(wǎng)行業(yè)中Nor Flash的軟件設(shè)計(jì)分享_W25Q128的軟件設(shè)計(jì)方案
一 概述 W25Q128是一種NOR Flash芯片,掉電后數(shù)據(jù)不丟失的特點(diǎn)。 W25Q128FV陣列被組織成65,536個(gè)可編程頁面,每個(gè)頁面256字節(jié)。每次最多可編程256字節(jié)。可
W25Q128FV中文手冊(cè)
W25Q128FV(128Mbit)型串行 Flash 存儲(chǔ)器面向受限于空間、引腳和功耗的系統(tǒng),提供了一種存儲(chǔ)解決方案。
發(fā)表于 09-18 11:33
?11次下載
瑞薩e2studio----SPI速率解析
在嵌入式系統(tǒng)的設(shè)計(jì)中,串行外設(shè)接口(SPI)的通信速率是一個(gè)關(guān)鍵參數(shù),它直接影響到系統(tǒng)的性能和穩(wěn)定性。瑞薩電子的RA4M2微控制器為開發(fā)者提供了靈活而強(qiáng)大的
ESP32外部flash與spi外設(shè)沖突怎么解決?
硬件: ESP32 ,W25Q128 SPI顯示器
庫:IDF4.0.1
使用hspi掛載了外部16MB的W25Q128,并同時(shí)掛載了SPI
發(fā)表于 06-25 06:19
【GD32H757Z海棠派開發(fā)板使用手冊(cè)】第十一講 SPI-SPI NOR FLASH讀寫實(shí)驗(yàn)
通過本實(shí)驗(yàn)主要學(xué)習(xí)以下內(nèi)容:
?SPI簡介
?GD32H7 SPI簡介
?SPI NOR FLASH——GD
具有雙/四SPI和QPI的串行閃存W25Q128FV數(shù)據(jù)手冊(cè)
電子發(fā)燒友網(wǎng)站提供《具有雙/四SPI和QPI的串行閃存W25Q128FV數(shù)據(jù)手冊(cè).pdf》資料免費(fèi)下載
發(fā)表于 04-25 17:11
?0次下載
如何使用SPI的DMA模式讀寫FLASH?
環(huán)境:HAL庫 + USB + W25Q64 + Fatfs
硬件:stm32f103c8t6 + MX25L64
我使用普通模式,完成在W25Q64中寫入文件,通過USB可以再PC中
發(fā)表于 04-16 07:59
STM32F103ZET6將SPI+W25QXX的程序移植后,步進(jìn)電機(jī)均轉(zhuǎn)速轉(zhuǎn)慢的原因?
SPI2+W25Q16
多個(gè)步進(jìn)電機(jī)脈沖均由多個(gè)不同定時(shí)器PWM(TIM1TIM2TIM4TIM8)或定時(shí)器中斷(TIM1)生成;
現(xiàn)象:
1、原程序運(yùn)行正常,步進(jìn)電機(jī)均正常,通過示波器測(cè)量,步進(jìn)脈沖信號(hào)正常
發(fā)表于 04-02 08:30
瑞薩電子推出采用自研RISC-V CPU內(nèi)核的通用32位MCU
5.5V
封裝:16 WLCSP、24/32/48 QFN封裝(QFP可選)
R9A02G021 RISC-V MCU得到瑞薩e2 studio集成開發(fā)環(huán)境(IDE)的全方位支持,客戶
發(fā)表于 03-30 22:08
NUCLEO-H7A3ZIQ使用keil外部下載算法后提示Flash Timeout的原因?
我用ospi驅(qū)動(dòng)w25q128,可以讀出id,可以寫入和讀取數(shù)據(jù)。然后自己寫了個(gè)KEIL的外部下載算法,修改了鏈接器腳本讓圖片資源存儲(chǔ)在w25q12
發(fā)表于 03-19 06:18
用S25FS128S無法從SPI Flash啟動(dòng)FX3是什么原因?怎么查?
您好,
我們根據(jù)官方推薦使用了S25FS128S作為FX3的SPI Flash,將固件下載到Flash內(nèi)以后,重新上電,設(shè)備仍然顯示為bootloader,不能正常啟動(dòng)設(shè)備。
我們嘗試
發(fā)表于 02-28 08:02
STM32F407ZGT6 spi flash片選引腳無法被拉低的原因?怎么解決?
\");
return -RT_ERROR;
}
if (RT_NULL == rt_sfud_flash_probe(\"W25Q128\", \"spi
發(fā)表于 02-20 07:13
評(píng)論