🚀write in front🚀
🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
💬本系列哔哩哔哩江科大STM32的视频为主以及自己的总结梳理📚
🚀Projeet source code🚀
💾工程代码放在了本人的Gitee仓库:iPickCan (iPickCan) - Gitee.com
引用:
STM32入门教程-2023版 细致讲解 中文字幕_哔哩哔哩_bilibili
Keil5 MDK版 下载与安装教程(STM32单片机编程软件)_mdk528-CSDN博客
STM32之Keil5 MDK的安装与下载_keil5下载程序到单片机stm32-CSDN博客
0. 江协科技/江科大-STM32入门教程-各章节详细笔记-查阅传送门-STM32标准库开发_江协科技stm32笔记-CSDN博客
【STM32】江科大STM32学习笔记汇总(已完结)_stm32江科大笔记-CSDN博客
江科大STM32学习笔记(上)_stm32博客-CSDN博客
STM32学习笔记一(基于标准库学习)_电平输出推免-CSDN博客
术语:
|--------------------------------------|---------------------------------------------|
| 英文缩写 | 描述 |
| GPIO:General Purpose Input Onuput | 通用输入输出 |
| AFIO:Alternate Function Input Output | 复用输入输出 |
| AO:Analog Output | 模拟输出 |
| DO:Digital Output | 数字输出 |
| 内部时钟源 CK_INT:Clock Internal | 内部时钟源 |
| 外部时钟源 ETR:External Trigger | 时钟源 External 触发 |
| 外部时钟源 ETR:External Trigger mode 1 | 外部时钟源 External 触发 时钟模式1 |
| 外部时钟源 ETR:External Trigger mode 2 | 外部时钟源 External 触发 时钟模式2 |
| 外部时钟源 ITRx:Internal Trigger inputs | 外部时钟源,ITRx (Internal trigger inputs)内部触发输入 |
| 外部时钟源 TIx:exTernal Input pin | 外部时钟源 TIx (external input pin)外部输入引脚 |
| CCR:Capture/Comapre Register | 捕获/比较寄存器 |
| OC:Output Compare | 输出比较 |
| IC:Input Capture | 输入捕获 |
| TI1FP1:TI1 Filter Polarity 1 | Extern Input 1 Filter Polarity 1,外部输入1滤波极性1 |
| TI1FP2:TI1 Filter Polarity 2 | Extern Input 1 Filter Polarity 2,外部输入1滤波极性2 |
| DMA:Direct Memory Access | 直接存储器存取 |
正文:
0. 概述
从 2024/06/12 定下计划开始学习下江协科技STM32课程,接下来将会按照哔站上江协科技STM32的教学视频来学习入门STM32 开发,本文是视频教程 P2 STM32简介一讲的笔记。
1.🚚 硬件SPI读写W25Q64
接线图(和软件SPI一样)
使用SPI1,SCK,接PA5;MISO,接PA6;MOSI,接PA7;NSS,可接PA4。
接线图对应:PA5接CLK引脚,PA6接DO引脚,PA7接DI引脚,PA4接CS引脚,
硬件引脚定义
如果SPI1的复用引脚被占用了,可以引脚重定义
注意:PA15、PB3、PB4这里没有加粗,因为默认情况下,作为JTAG的调试端口使用的,如果要使用原本的GPIO功能或使用重定义外设引脚功能,都需要解除调试端口的复用,否则GPIO或外设引脚都不会正常工作,解除调试端口的方法,在6-4小节。
SPI初始化流程:
- 第一步,开启时钟,开始SPI和GPIO时钟。
- 第二步,初始化GPIO口。其中,SCK,MOSI由硬件外设配置的输出信号,配置为复用推挽输出,MISO是硬件输入信号,配置为上拉输入。SS引脚,是软件控制的输出信号,配置为通用推挽输出
- 第三步,配置SPI外设,调用SPI_Init里面的参数。
- 第四步,开关控制,调用SPI_Cmd,给SPI使能
初始化后,参考非连续传输的时序来执行运行控制的代码,能产生交换字节的时序了。
SPI常用库函数:
cpp
void SPI_I2S_DeInit(SPI_TypeDef* SPIx);//恢复缺省配置
void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);//初始化
void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct);
void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct);//结构体变量初始化
void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct);
void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);// 外设使能
void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);
void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState
NewState);//中断使能
void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq,
FunctionalState NewState);//DMA使能
void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data); //写DR数据寄存器
uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx); //读DR数据寄存器
//状态标志
FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);//获取TXE和RXNE标志位的状态
void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
生成时序
- 第一步,等待TXE为1,发送寄存器空;如发送寄存器不为空,不要着急写。
- 第二步,执行软件写入0xF1至SPI_DR,写入数据,调用SPI_I2S_SendData。
- 第三步,等待RXNE为1,发送完成即接收完成,RXNE置1
- 第四步,读取DR,从RDR里,把交换接收的数据读出来,调用 SPI_I2S_SendData(SPI1, ByteSend);。注(TDR是只写的,RDR是只读的,进行写操作时,数据写入TDR,进行读操作时,数据从RDR读出)
注意事项:这里的硬件SPI,必须是发送,同时接收。
TXE和RXNE,会自动清除标志位。