Stm32通过SPI读写W25QXX

  1. Printf的重定向

因为printf是c++中的库函数,要使用printf输出到串口,需要重定向,将printf定向到HAL_UART_Transmit。

新建一个retarget.c文件。

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| #include "stdio.h" #include "stm32f1xx_hal.h" #include "usart.h" #pragma import(__use_no_semihosting_swi) #pragma import(__use_no_semihosting) void _sys_exit(int x) { x = x; } struct __FILE { int handle; /* Whatever you require here. If the only file you are using is */ /* standard output using printf() for debugging, no file handling */ /* is required. */ }; /* FILE is typedef' d in stdio.h. */ FILE __stdout; void _ttywrch(int ch){}; int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff); return ch; } |

网上找的代码或多或少运行不起来,搞了好久才调通,以上是调通后的代码,几乎只要是调试keil的工程都需要用到。可以保存下来重复使用。

  1. delay微秒

delay是一个延时函数。Stm32的HAL库提供了一个HAL_Delay的函数,但是只能延时毫秒。延时微秒,需要根据stm32的系统时钟计算,网上一大堆,但貌似或多或少有点问题,不能拿来即用。

新建一个delay.c和delay.h的文件。

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| #include "delay.h" //仿原子延时,不进入systic中断 void delay_us(uint32_t nus) { uint32_t temp; SysTick->LOAD = 9*nus; SysTick->VAL=0X00;//清空计数器 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 do { temp=SysTick->CTRL;//读取当前倒计数值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } void delay_ms(uint16_t nms) { uint32_t temp; SysTick->LOAD = 9000*nms; SysTick->VAL=0X00;//清空计数器 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 do { temp=SysTick->CTRL;//读取当前倒计数值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } |

|------------------------------------------------------------------------------------|
| #include "stm32f1xx_hal.h" 或者直接#include "main.h",规范一点 void delay_us(uint32_t nus); |

之后,在main.c中引用delay.h就可以调用delay_us函数。

  1. 遇到的问题

1.编译报错

w25qxx.c(69): error: #20: identifier "SPI_I2S_FLAG_TXE" is undefined

解:SPI_I2S_FLAG_TXE这个寄存器没有定义。网上使用的都是这个寄存器,但是在spi的库函数里找不到这个。看了半天,找到一个SPI_FLAG_TXE,改成这个就可以了。可能是时间长了,库函数里的变量名改了。

2. .\spi.axf: Error: L6218E: Undefined symbol SPI_I2S_GetFlagStatus (referred from w25qxx.o).

解:原理如上个问题,修改为

HAL_SPI_GetState(&hspi2) == HAL_SPI_STATE_BUSY_TX

3. STM32关于我遇到的HardFault_Handler的处理_warning:hardfault handler-CSDN博客

调了一个下午,发现是内存泄漏,数组访问越界的问题,也是醉了。

4. 软件SPI和硬件SPI的区别

软件SPI:用IO模拟SPI时序,这个模拟过程全部是CPU在负责执行,为了其稳定的存取数据,你可能会插入软件延时,这个时间在读取数据量不大的情况下并不明显,但是基本上你在读取过程中,其他非中断非异常程序是无法得到执行。

硬件SPI:首先这个数据存道储的过程是不需要CPU参与得,程序中配置好SPI的访问时序,开启中断,CPU就可以在中断函数中搬移数据,省下了软件模拟IO得存取时间。

仔细研究就会发现,CPU在进行SPI中断服务程序还版是需要耽误时间得,这个过程在大数据量传输中还是很耗时,ARM中Cortex-M3内核得处理器在硬件SPI上加入了DMA,这个DMA直接从SPI的数据寄存器,软件配置好DMA之后,基本上整个传输都不要权CPU参与,软件设计得好的话,整个数据传输都不要CPU参与。

W25Qxx------------(硬件SPI)_硬件spi和软件spi区别-CSDN博客

5.W25QXX上的端口容易接反。

D0--------MISO---------PA6--------PB15

D1--------MOSI---------PA7--------PB14

6.SPI1和SPI2的区别

SPI2需要复用引脚,重映射。Cubemx里面生成代码会配置好,如果用标准库去写,需要自己配置重映射。

7.硬SPI和软SPI的区别

硬SPI可以不用配置CS/NSS管脚,软SPI就是自己重新配置CS管脚,使其达到控制片选的功能,硬SPI利用终断或DMA传输数据,还没试过。

8.SPI中参数配置

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128; hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi1.Init.CRCPolynomial = 10; |

SPI_POLARITY_LOW--------对应上文的CLK极性0.

SPI_PHASE_1EDGE---------对应上文的CLK相位0

所以SPI工作在模式1(总共4个模式,上升沿采集数据,下降沿发送数据)

SPI_NSS_SOFT----------软SPI

SPI_BAUDRATEPRESCALER_128-----------128分频,在cubemx配置里面会显示对应多少赫兹

  1. 调试成功,纪念一下

完成

STM32CubeMX学习笔记(10)------SPI接口使用(读写SPI Flash W25Q64)_stm32cubemx配置spi-CSDN博客

  1. 继续封装SPI收发数据成W25Q64收发数据

网上代码一般比较标准,按照教程来操作即可,无需太多改动。已经标准化的东西,拿来用用,理解一下原理就好,加深印象。

7、单片机与W25Q128(FLASH)的通讯(SPI)实验(STM32F407)_f407 w25q-CSDN博客

6.GPIO的8种模式理解

开漏输出(open drain)与推挽输出(push pull)学习详解及某个踩到的坑分享-CSDN博客

STM32CUBEMX配置教程(三)通用GPIO配置_stm32cubemx怎么设置gpio精准输出-CSDN博客

STM32的GPIO端口配置八种模式的理解_stm32的gpio的配置模式有哪几种-CSDN博客

相关推荐
天蓝蓝235281 小时前
嵌入式硬件基础知识
嵌入式硬件
代码总长两年半1 小时前
STM32+FATFS+SD卡+RTC(生成.CSV格式文件)
stm32·嵌入式硬件·实时音视频
honey ball3 小时前
仪表放大器AD620
运维·单片机·嵌入式硬件·物联网·学习
luckyluckypolar3 小时前
STM32 -中断
stm32·单片机·嵌入式硬件·物联网
启明云端wireless-tag8 小时前
ESP32无线WiFi蓝牙SOC,设备物联网通信方案,启明云端乐鑫代理商
嵌入式硬件·物联网·wifi·esp32·乐鑫·wifi模组
小狗爱吃黄桃罐头8 小时前
江协科技STM32学习- P14 示例程序(定时器定时中断和定时器外部时钟)
stm32·江科大stm32
@@庆9 小时前
stm32 PWR电源控制(修改主频&睡眠模式&停机模式&待机模式)
stm32·单片机·嵌入式硬件
JT灬新一9 小时前
STM32巡回研讨会总结(2024)
stm32·单片机·嵌入式硬件
爱桥代码的程序媛9 小时前
鸿蒙OpenHarmony【轻量系统芯片移植案例】标准系统方案之瑞芯微RK3568移植案例
嵌入式硬件·harmonyos·鸿蒙·鸿蒙系统·移植·openharmony·鸿蒙开发
Whappy00110 小时前
51单片机-DA(数字转模拟)
单片机·嵌入式硬件·51单片机