瑞萨e2studio----串口获取数据通过SPI存储于W25Q128外部flash

1.概述      
     本篇文章主要介绍如何使用e2studio对瑞萨进行spi配置,同时移植stm32上的w25q128到瑞萨上,同时通过对该flash进行读写操作,验证是否正确。 
2.硬件准备   
     首先需要准备一个开发板,这里我准备的是芯片型号 r7fa2l1ab2dfl 的开发板。 
3.新建工程
4.工程模板
5.保存工程路径
6.芯片配置     
    本文中使用r7fa2l1ab2dfl来进行演示。 
7
   7.工程模板选择
8.spi配置     
    点击stacks->new stack->driver->connectivity->spi driver on r_spi。
9.spi属性配置
10.片选cs管脚设置     
        设置p103管脚为输出管脚,作为cs片选。
11.设置e2studio堆栈
12.e2studio的重定向printf设置     
    c++ 构建->设置->gnu arm cross c linker->miscellaneous去掉other linker flags中的 “--specs=rdimon.specs”
13.printf输出重定向到串口     
    打印最常用的方法是printf,所以要解决的问题是将printf的输出重定向到串口,然后通过串口将数据发送出去。    注意一定要加上头文件#include #ifdef __gnuc__ //串口重定向 #define putchar_prototype int __io_putchar(int ch)#else #define putchar_prototype int fputc(int ch, file *f)#endifputchar_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中,有个片选定义,代码如下。#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中,有对数据进行发送和接受,代码如下。 /* 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个块(block),每个块大小为64k字节,每个块又分为16个扇区(sector),每个扇区4k个字节。w25q128的最小擦除单位为一个扇区,也就是每次必须擦除4k个字节。芯片id如下所示。0xef13,表示芯片型号为w25q80 0xef14,表示芯片型号为w25q16 0xef15,表示芯片型号为w25q32 0xef16,表示芯片型号为w25q64 0xef17,表示芯片型号为w25q128
16.演示效果       
    开机会打印w25q128的id,id为0xef17,实际如下所示。    并且之前保存的数据也正确读取出来了。    定义数组databuff,其中databuff[0]表示写入扇区, databuff[1]表示写入位置,剩下的为写入数据,同时以0xff结尾。    分别输入数据 01 02 01 02 03 04 ff与02 20 aa bb cc dd ff
17.主程序代码    #include hal_data.h#include #include w25qx.hfsp_cpp_headervoid r_bsp_warmstart(bsp_warm_start_event_t event);fsp_cpp_footervoid uart1_data(void);#define buffersize 255 //可以接收的最大字符个数uint8_t receivebuff[buffersize]; //接收缓冲区uint8_t recv_end_flag = 0,rx_len=0;//接收完成中断标志,接收到字符长度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]; //进入中断接收数据的数组uint8_t databuff[5000]; //保存接收到的数据的数组int rxline=0; //接收到的数据长度int rx_flag=0; //接受到数据标志int rx_flag_finish=0; //接受完成或者时间溢出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++; //每接收到一个数据,进入回调数据长度加1 databuff[rxline-1]=rxbuff[0]; //把每次接收到的数据保存到缓存数组 rx_flag=1; rx_len++; if(rxbuff[0]==0xff) //接收结束标志位,这个数据可以自定义,根据实际需求,这里只做示例使用,不一定是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)#endifputchar_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扇区数据**************************************************************/ /*##-3- read the flash ########################*/ /*读取数据,rdata读取数据的指针,起始地址0x00,读取数据长度0x200*/ if(bsp_w25qx_read(rdata1,0x0,0x200)== w25qx_ok) printf(the first sector success\n); else printf(the first sector error\n); /*打印数据*/ 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扇区数据**************************************************************/ /*##-3- read the flash ########################*/ /*读取数据,rdata读取数据的指针,起始地址0x1000,读取数据长度0x200*/ if(bsp_w25qx_read(rdata2,0x1000,0x200)== w25qx_ok) printf(the second sector success\n); else printf(the second sector error\n); /*打印数据*/ 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扇区数据**************************************************************/ /*##-3- read the flash ########################*/ /*读取数据,rdata读取数据的指针,起始地址0x2000,读取数据长度0x200*/ if(bsp_w25qx_read(rdata3,0x2000,0x200)== w25qx_ok) printf(the third sector success\n); else printf(the third sector error\n); /*打印数据*/ 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扇区数据为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; } /*写入数据,wdata写入数据的指针,起始地址0x00,写入数据长度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 ########################*/ /*读取数据,rdata读取数据的指针,起始地址0x00,读取数据长度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); /*打印数据*/ 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扇区数据为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; } /*写入数据,wdata写入数据的指针,起始地址0x1000,写入数据长度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 ########################*/ /*读取数据,rdata读取数据的指针,起始地址0x00,读取数据长度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); /*打印数据*/ 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扇区数据为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;i++)>

三星第二代NPU已完成开发,将应用于Galaxy S10和Note 10
传统眼图参数测量的局限
普惠将成为与涡轮控制公司的售后市场供应商
3D打印2D打印机,惠普为国际空间站增添助力
服务器数据恢复-ESXi误删虚拟机的数据恢复案例
瑞萨e2studio----串口获取数据通过SPI存储于W25Q128外部flash
物联网在交通控制系统中的作用
LN2401 CMOS降压恒流驱动器概述及特点
荧光微量氧变送器LOX-TRACE-1000-BLX 的特性及应用分析
2018年功率半导体可能如IC业一样迎来发展热潮
小米6最新消息:小米6新机变二手,价格瞬间降千元,还想全款预售吗?
技嘉AorusRTX2080TiXtreme11G显卡高清拆解图赏
智能照明迎来了怎样的机会
访问控制中PIP的典型流程和关键点思考
DS26528收发器的初始化和配置
2022年可穿戴设备总出货量将达1.904亿
无线网络连接上但上不了网
我国的自动驾驶技术研发接连取得重大突破
找方案 | 基于 ams OSRAM AS7056 心率血氧检测 Sensor Board 方案
大疆招聘最青睐的几个岗位,毕业就能拿高薪,未来大有可为