X
首页
技术
模拟电子
单片机
半导体
电源管理
嵌入式
传感器
最能打国产芯
应用
汽车电子
工业控制
家用电子
手机便携
安防电子
医疗电子
网络通信
测试测量
物联网
最能打国产芯
大学堂
首页
直播
专题
TI 培训
论坛
汽车电子
国产芯片
电机驱动控制
电源技术
单片机
模拟电子
PCB设计
电子竞赛
DIY/开源
嵌入式系统
医疗电子
颁奖专区
【厂商专区】
【电子技术】
【创意与实践】
【行业应用】
【休息一下】
最能打国产芯
活动中心
直播
发现活动
颁奖区
电子头条
参考设计
下载中心
分类资源
文集
排行榜
电路图
Datasheet
最能打国产芯
国产芯片交流
[MCU] 【CW32L052测评】学习笔记04(SPI_Flashd读写)
qzc0927
2023-8-6 10:28
楼主
## SPI-FLASH读写 ### 8.1:硬件设计 外部flash也是用户存储数据来用,使用的是SPI接口,首先先看评估板的用户手册上关于SPI接口的说明: ![image-20230806084940015](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20230806084940015.png) 再看主芯片的用户手册里面关于通讯时序的说明: ![image-20230806085254693](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20230806085254693.png) 以及寄存器相关描述: ![image-20230806085527595](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20230806085527595.png) 最后看下原理图的接口: ![image-20230806085631732](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20230806085631732.png) 从原理图可以看出,使用PC00,PC01,PC02,PC03作为SPI接口,后续软件设计需要,同时需要查看引脚对应的SPI接口序号,回到评估板的数据手册查看。 ![image-20230806091517518](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20230806091517518.png) 使用的是SPI1接口。 ### 8.2:软件设计 首先宏定义引脚配置: ```ABAP //SPIx GPIO #define FLASH_SPI_SCK_GPIO_CLK RCC_AHB_PERIPH_GPIOE #define FLASH_SPI_SCK_GPIO_PORT CW_GPIOC #define FLASH_SPI_SCK_GPIO_PIN GPIO_PIN_1 #define FLASH_SPI_MISO_GPIO_CLK RCC_AHB_PERIPH_GPIOE #define FLASH_SPI_MISO_GPIO_PORT CW_GPIOC #define FLASH_SPI_MISO_GPIO_PIN GPIO_PIN_2 #define FLASH_SPI_MOSI_GPIO_CLK RCC_AHB_PERIPH_GPIOE #define FLASH_SPI_MOSI_GPIO_PORT CW_GPIOC #define FLASH_SPI_MOSI_GPIO_PIN GPIO_PIN_3 #define FLASH_SPI_CS_GPIO_CLK RCC_AHB_PERIPH_GPIOE #define FLASH_SPI_CS_GPIO_PORT CW_GPIOC #define FLASH_SPI_CS_GPIO_PIN GPIO_PIN_0 //SPIx #define FLASH_SPIx CW_SPI1 #define FLASH_SPI_CLK RCC_APB2_PERIPH_SPI1 #define FLASH_SPI_APBClkENx RCC_APBPeriphClk_Enable2 ``` 其次进行SPI初始化配置: ```c void SPI_FLASH_Init(void) { SPI_InitTypeDefSPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /************************GPIO Configuration***********************/ RCC_AHBPeriphClk_Enable(FLASH_SPI_SCK_GPIO_CLK | FLASH_SPI_MISO_GPIO_CLK | FLASH_SPI_MOSI_GPIO_CLK | FLASH_SPI_CS_GPIO_CLK, ENABLE); FLASH_SPI_APBClkENx(FLASH_SPI_CLK, ENABLE); //SPI SCK MOSI MISO 复用 FLASH_SPI_AF_SCK; FLASH_SPI_AF_MISO; FLASH_SPI_AF_MOSI; //CS GPIO_InitStructure.Pins = FLASH_SPI_CS_GPIO_PIN; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_Init(FLASH_SPI_CS_GPIO_PORT, &GPIO_InitStructure); //SCK GPIO_InitStructure.Pins = FLASH_SPI_SCK_GPIO_PIN; GPIO_Init(FLASH_SPI_SCK_GPIO_PORT, &GPIO_InitStructure); //MOSI GPIO_InitStructure.Pins = FLASH_SPI_MOSI_GPIO_PIN; GPIO_Init(FLASH_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure); //MISO GPIO_InitStructure.Pins = FLASH_SPI_MISO_GPIO_PIN; GPIO_InitStructure.Mode = GPIO_MODE_INPUT; GPIO_Init(FLASH_SPI_MISO_GPIO_PORT, &GPIO_InitStructure); //拉高CS FLASH_SPI_CS_HIGH(); /************************SPI Configuration***********************/ SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // 双线全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // 主机模式 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // 帧数据长度为8bit SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; // 时钟空闲电平为高 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // 第二个边沿采样 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // 片选信号由SSI寄存器控制 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; // 波特率为PCLK的8分频 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 最高有效位 MSB 收发在前 SPI_InitStructure.SPI_Speed = SPI_Speed_Low; // 低速SPI SPI_Init(FLASH_SPIx, &SPI_InitStructure); SPI_Cmd(FLASH_SPIx, ENABLE); } ``` ### 结果验证 编写测试函数代码: ```c #include"bsp_flash.h" #include"stdio.h" #include"main.h" extern TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength); //SPI TEST uint8_t TxBuffer[] = "This is SPI_FLASH Test"; uint8_t RxBuffer[BufferSize]; uint8_t DeviceID = 0; uint16_t ManufactDeviceID = 0; int32_t JedecID = 0; uint8_t UniqueID[8]; uint8_t status1; uint8_t status2; void SPI_FLASH_Test(void) { printf("\r\n2.SPI_FLASH Test Start\r\n"); TestStatus TransferStatus = FAILED; DeviceID = SPI_FLASH_DeviceID(); ManufactDeviceID = SPI_FLASH_ManufactDeviceID(); JedecID = SPI_FLASH_JedecID(); SPI_FLASH_UniqueID(UniqueID); //printf("\r\nDeviceID = 0x%X\r\nManufactDeviceID = 0x%X\r\nJedecID = 0x%X", DeviceID, ManufactDeviceID, JedecID); //printf("\r\nUniqueID = 0x "); //for(uint8_t i = 0;i<8;i++) //{ // printf("%X ", UniqueID[i]); //} /* 读状态寄存器 */ status1 = SPI_FLASH_ReadStatusReg1(); status2 = SPI_FLASH_ReadStatusReg2(); //printf("\r\nstatus1 = 0x%X\r\nstatus2 = 0x%X\r\n", status1, status2); // /* 写状态寄存器 */ // SPI_FLASH_WriteStatusReg1(0x00); // SPI_FLASH_WriteStatusReg2(0x00); // status1 = SPI_FLASH_ReadStatusReg1(); // status2 = SPI_FLASH_ReadStatusReg2(); // printf("\r\nstatus1 = 0x%X\r\nstatus2 = 0x%X\r\n", status1, status2); /* Check JEDEC ID */ if(JedecID == sJedecID) { //擦除扇区 4KB SPI_FLASH_SectorErase(FLASH_SectorToEraseAddress); //写数据 SPI_FLASH_BufferWrite(TxBuffer, FLASH_WriteAddress, BufferSize); printf("写入的数据为:%s\r\n", TxBuffer); //读数据 SPI_FLASH_BufferRead(RxBuffer, FLASH_ReadAddress, BufferSize); printf("读出的数据为:%s\r\n", RxBuffer); //检查写入的数据与读出的数据是否一致 TransferStatus = Buffercmp(TxBuffer, RxBuffer, BufferSize); if(TransferStatus == PASSED) { printf("SPI_FLASH Test OK\r\n"); } else { printf("\r\nSPI_FLASH Test Error:Read and Write Data is not same\r\n"); while(1); } //擦除扇区 4KB SPI_FLASH_SectorErase(FLASH_SectorToEraseAddress); //读数据 SPI_FLASH_BufferRead(RxBuffer, FLASH_ReadAddress, BufferSize); for(uint8_t j = 0; j < BufferSize; j++) { if(RxBuffer[j] != 0xFF) { printf("\r\nSPI_FLASH Test Error:FLASH Erase fail\r\n"); while(1); } } } else// (FlashID != sFLASH_ID) { printf("\r\nSPI_FLASH Test Error:Read JEDEC ID Error\r\n"); while(1); } } ``` 函数功能你主要是将“This is SPI_FLASH Test”字符串通过SPI_FLASH_BufferWrite写入到SPI_FLASH里面,然后通过SPI_FLASH_BufferRead将数据读取出来,读取成功之后通过串口打印出来。打开串口调试助手,查看信息是否成功读写。 ![image-20230806102110466](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20230806102110466.png)
点赞
回复评论 (1)
沙发
lugl4313820
恭喜flash烧写测试成功!
点赞
2023-8-6 11:26
最新活动
是德科技有奖直播 | 应对未来高速算力芯片的设计与测试挑战
免费申请 | 上百份MPS MIE模块,免费试用还有礼!
TI 有奖直播 | 使用基于 Arm 的 AM6xA 处理器设计智能化楼宇
Follow me第二季第3期来啦!与得捷一起解锁高性能开发板【EK-RA6M5】超能力!
报名直播赢【双肩包、京东卡、水杯】| 高可靠性IGBT的新选择——安世半导体650V IGBT
30套RV1106 Linux开发板(带摄像头),邀您动手挑战边缘AI~
随便看看
【有人答对啦~】论坛刚刚新调整好了个入口,大家快来找找看
wince UI程序窗口覆盖问题 Z order
SEED-DEC643用户指南——FLASH测试程序
远离静电,你有哪些好办法?教你建立一个 ESD 安全工作区
使用ST7 PWM(脉冲宽度调制)产生模拟输出(正弦波)
msp430仿真困惑
BlueNRG-x文档-下主要的官方资料查找
四层板和33欧电阻
Silicon Labs BG22-EK4108A 开发套件 用科技连接未来 申请进行时!
<OP放大电路设计>,[日] 冈村迪夫 著
【是德征文】+示波器的FFT功能在滤波器效果验证分析中运用
ZigBee基础程序之——LED
C2000三相无刷永磁同步电机控制器 电路图
电容电阻电感电路分压计算
有没有想过launchpad在电视上显示图像
绘制一个功能比较全的板子 听听大家建议
micropython入门教程资料汇总,
世界著名汽车品牌标识演化历史------福特
I2C复位期间,scl sda是高,复位后,scl sda产生一个周期的信号后,一直拉低
WinCE 4.2增加一个分区的问题
电子工程世界版权所有
京B2-20211791
京ICP备10001474号-1
京公网安备 11010802033920号
回复
写回复
收藏
回复