STM32

STM32是STMicroelectronics(意法半导体)推出的一系列基于ARM Cortex-M内核的32位微控制器(MCU)产品。这些微控制器提供了广泛的产品系列,覆盖了多种不同的性能和功能需求,适用于各种应用领域,包括工业控制、汽车电子、消费类电子、医疗设备等。

STM32系列微控制器以其高性能、低功耗、丰富的外设接口和灵活的开发工具而闻名。它们通常具有丰富的存储器、多种通信接口(如UART、SPI、I2C、CAN等)、模拟数字转换器(ADC)、定时器、PWM输出等功能,以满足不同应用场景下的需求。

STM32微控制器通常使用标准的ARM Cortex-M内核,包括Cortex-M0、M0+、M3、M4和M7等,这些内核具有不同的性能和功耗特性,可根据具体应用的需求进行选择。此外,STM32系列还提供了多种封装和引脚配置,以满足不同尺寸和集成度的要求。

STMicroelectronics为STM32系列提供了丰富的开发工具和支持资源,包括基于ARM开发环境的集成开发环境(IDE)、调试器、评估板和参考设计等。这些工具和资源有助于开发人员快速开发和部署他们的应用,并提供了全面的技术支持和文档资料,帮助用户充分发挥STM32微控制器的性能和功能优势。

一、stm32的pwm输出引脚是使用的IO口的复用功能。

二、T2~T5这4个通用定时器均可输出4路PWM——CH1~CH4。

三、我们以tim3的CH1路pwm输出为例来进行图文讲解(其它类似),并在最后给出tim3的ch1和ch2两路pwm输出的c代码(已在STM32F103RBT6上测试成功,大家放心使用!)。

四、给出了PWM频率和占空比的计算公式。

步骤如下:

1、使能TIM3时钟

详解STM32的PWM输出及频率和脉宽(占空比)的计算

RCC->APB1ENR |= 1 << 1;
2、配置对应引脚(PA6)的复用输出功能

详解STM32的PWM输出及频率和脉宽(占空比)的计算

GPIOA->CRL &= 0XF0FFFFFF;//PA6清0
GPIOA->CRL |= 0X0B000000;//复用功能输出(推挽50MHz输出)
GPIOA->ODR |= 1 << 6;//PA6上拉

3、设定计数器自动重装值及是否分频

TIM3->ARR = arr;//设定计数器自动重装值(决定PWM的频率)
TIM3->PSC = psc;//预分频器,0为不分频

4、设置PWM的模式(有1和2两种模式,区别在于输出电平极性相反),根据需求选一种即可

详解STM32的PWM输出及频率和脉宽(占空比)的计算

注:TIMX_CCMR1决定CH1~CH2路,TIMX_CCMR2决定CH3~CH4路。

详解STM32的PWM输出及频率和脉宽(占空比)的计算

//TIM3->CCMR1 |= 6 << 4;//CH1 PWM1模式
TIM3->CCMR1 |= 7 << 4;//CH1 PWM2模式
TIM3->CCMR1 |= 1 << 3;//CH1预装载使能

5、输出使能设置

详解STM32的PWM输出及频率和脉宽(占空比)的计算

TIM3->CCER |= 1 << 0;//输入/捕获1输出使能

6、自动重装载预装载允许位(ARPE) 及定时器使能

详解STM32的PWM输出及频率和脉宽(占空比)的计算

TIM3->CR1 = 0X0080;//ARPE使能(此句不配置也行)
TIM3->CR1 |= 0X01;//使能定时器3

下面给出TIM3_CH1及TIM3_CH2的PWM输出代码:
void PWM_Init_TIM3_CH1(u16 arr, u16 psc)
{
//1、使能TIM3时钟
RCC->APB1ENR |= 1 << 1;//使能TIM3时钟
//2、配置对应引脚(PA6)的复用输出功能
GPIOA->CRL &= 0XF0FFFFFF;//PA6清0
GPIOA->CRL |= 0X0B000000;//复用功能输出(推挽50MHz输出)
GPIOA->ODR |= 1 << 6;//PA6上拉
//3、设定计数器自动重装值及是否分频
TIM3->ARR = arr;//设定计数器自动重装值(决定PWM的频率)
TIM3->PSC = psc;//预分频器 0为不分频
//4、设置PWM的模式
TIM3->CCMR1 |= 7 << 4;//CH1 PWM2模式
TIM3->CCMR1 |= 1 << 3;//CH1预装载使能
//5、输出使能设置
TIM3->CCER |= 1 << 0;//输入/捕获1输出使能
//6、自动重装载预装载允许位(ARPE) 及 定时器 使能
TIM3->CR1 = 0X0080;//ARPE使能
TIM3->CR1 |= 0X01;//使能定时器3
}
void PWM_Init_TIM3_CH2(u16 arr, u16 psc)
{
RCC->APB1ENR |= 1 << 1;//使能TIM3时钟

GPIOA->CRL &= 0X0FFFFFFF;//PA7清0
GPIOA->CRL |= 0XB0000000;//复用功能输出(推挽50MHz输出)
GPIOA->ODR |= 1 << 7;//PA7上拉
TIM3->ARR = arr;//设定计数器自动重装值(决定PWM的频率)
TIM3->PSC = psc;//预分频器 不分频
TIM3->CCMR1 |= 7 << 12;//CH2 PWM2模式
TIM3->CCMR1 |= 1 << 11;//CH2预装载使能
TIM3->CCER |= 1 << 4;//输入/捕获2输出使能
TIM3->CR1 = 0X0080;//ARPE使能
TIM3->CR1 |= 0X01;//使能定时器3
}
频率:
//Fpwm = 72M / ((arr+1)*(psc+1))(单位:Hz)
占空比:
//duty circle = TIM3->CCR1 / arr(单位:%)
注:本文方法的一个定时器4个通道的pwm输出的频率是相同的,但占空比可以不同!

转自: akunainiannian的专栏

围观 665

前言

一般芯片开发过程中,存在 Bin 文件的拼接过程,比如在做 IAP 程序+用户程序过程中,最终烧写 bin 文件或 hex 文件需要将两个或者三个单独编译通过的程序拼接在一起作为最终烧录文件,本文就如何操作做详细说明。

示例案例

使用芯片为 STM32F030R8T6,IAP_Boot.bin 是程序 IAP 程序编译后生成的 bin 文件,地址在 0x0800 0000 ~ 0x0800 1FFF;APP.bin 是客户运行程序,地址在 0x0800 2000 ~ 0x0800 FFFF;而整个 Flash 空间将会是 0x0800 0000 ~ 0x0800 FFFF;

具体操作

下载任意一款支持 STM32F030 芯片烧录的烧写器 PC 软件,比如 raisonance,segger,hilosystems 等等,可根据自身所使用的量产烧写器型号进行选择,这边举例如果客户使用了 Xeltek 烧写器,其他厂商的操作大体相同。

在 xeltek 官网下载下载器的 PC 软件,www.xeltek.com

安装后打开,选择芯片型号。

用于量产烧录的拼接 Bin 文件操作

打开 IAP_Boot.bin 文件

用于量产烧录的拼接 Bin 文件操作

然后再打开 APP.bin 文件,操作注意选择地址以及不可覆盖选项

用于量产烧录的拼接 Bin 文件操作

察看拼接是否成功

会在 Buffer 中看到地址 0x0000 0000 存入的是 IAP_Boot.bin 的内容,在地址 0x0000 2000 地址上存入的是 APP.bin 文件中内容,此时即拼接成功。

用于量产烧录的拼接 Bin 文件操作用于量产烧录的拼接 Bin 文件操作

保存拼接后的文件
注意选择数据大小,生成最终量产烧写文件 Com.bin

用于量产烧录的拼接 Bin 文件操作

总结

通过上面的操作,即可生成对应的拼接文件,同样如果是几个文件的拼接也可以相同进行操作,拼接后的 bin 文件可以通过量产烧写器进行自动下载操作。

来源: ST

围观 946

1 总体描述:

DM9000A的PHY 能够以10BASE-T 的标准在UTP3\4\5或者以100BASE-T的标准在UTP5上接口通信。它的自动协商功能是够自动配置DM9000A最大地发挥出自身性能。它同时支持IEEE 802.3X全双工数据流通信。

2、结构图:

STM32网络通信之DM9000A电路设计

3、硬件电路的设计

(1)电源连接:

STM32网络通信之DM9000A电路设计

(2)数据接口连接:
STM32网络通信之DM9000A电路设计

(3)控制接口连接
STM32网络通信之DM9000A电路设计

基本知识点1——何为PHY?

网卡工作在OSI(开放式系统互连)的最后两层,物理层PHY 和数据链路层(MAC)
PHY物理层定义了数据传送与接收所需要的电与光信号、线路状态、时钟基准、数据编码和电路等,并向数据链路层设备提供标准接口,物理层的芯片称之为PHY。

基本知识点2——何为10BASE-T 与100BASE-T

(1)10BASE-T 表示一种以 10Mbps的数据传输速率工作的双绞线以太网标准, T表示采用双绞线,最大传输距离是500米;
(2)100BASE-T 表示一种以100Mbps的数据传输速率工作的局域网标准,通常被称为快速以太网标准,与10BASE-T相比,速度快了十倍,距离小了一半,最远210米。

基本知识点3——何为UTP3\4\5?

说的通俗一些,UTP就是我们平常用的网线,由一定长度的双绞线和RJ45水晶头组成;最大传输距离是100米,有两种标准:

标准568A: 绿白-绿-橙白-蓝-蓝白-橙-棕白-棕
标准568B: 橙白-橙-绿白-蓝-蓝白-绿-棕白-棕

当你要自己制作网线时,如何判断你所买到的网线是哪种标准呢? 直接看你买到的线身上印制的字符。

将双绞线按电气特性分为:3类,4类和5类线,也就是UTP3,UTP4,UTP5,目前已有6类线,但是我们常用的是UTP3和UTP5 。

这里顺便为自己普及一下双绞线的知识:

>>U/UTP双绞线:即通常所说的UTP双绞线,非屏蔽双绞线;
>>F/UTP双绞线:总屏蔽层为铝箔屏蔽,没有线对屏蔽层的屏蔽双绞线;
>>U/FTP双绞线:没有总屏蔽层,线对屏蔽为铝箔屏蔽的屏蔽双绞线;
>>SF/UTP双绞线:总屏蔽层为丝网+铝箔的双重屏蔽,线对没有屏蔽的双重屏蔽双绞线;
>>S/FTP双绞线:总屏蔽层为丝网,线对屏蔽为铝箔屏蔽的双重屏蔽双绞线。

转自: dxmcu的专栏

围观 453

STM32 提供了丰富的接口资源,其中包括 USB FS、USB HS、OTG FS 和 OTG HS。对于高速 USB,由于信号速率相对较高。在开发过程中,会对高速 USB 信号质量进行测试,例如运用广泛的眼图测试。STM32 的高速 USB/OTG IP 遵循USB 2.0 规范,能够配合实现眼图等信号质量测试项。本文中,首先介绍眼图等信号质量测试的实现框架,然后以 Cube 软件包中 USB 设备类的 HID 例程为基础,提供软件层面的修改。最后通过 USB 官方提供的 HSETT 工具,一步一步呈现如何使STM32 实现的 USB 设备进入测试模式,以便使其输出用以获取眼图等测试项的信号。

一 信号质量测试背景介绍

高速 USB 信号质量测试,实现框架如下图。

STM32 的高速 USB 信号质量测试实现

根据测试需要,利用电脑端测试软件工具 HSETT,使 STM32 实现的 USB 设备进入相应的测试模式。然后利用示波器抓取测试信号,进行信号质量分析。本文中不包含示波器抓取信号的实现描述,读者可以通过文末的参考文档进行了解。

其中,HSETT 全称 High-speed Electrical Test Tool,是 USB 官方组织发布的一个发包工具(官网 www.usb.org 下载)。

STM32 的高速 USB IP 遵循 USB2.0 规范,支持多种测试模式,包括 Test_J 模式、Test_K 模式、Test_SE0_NAK 模式、Test_Packet 模式和 Test_Force_Enable 模式。更多测试模式内容的介绍请参考 USB2.0 规范。 更多内容请参考对应型号的参考手册。其中,如果是进行眼图测试,需要进入 Test_Packet 测试模式。

二 软件层面支持

本文中实现环境如下:

硬件平台: STM32F469I-EVAL
Cube 软件包版本: v1.16.0
HID 例程文件路径 :
STM32Cube_FW_F4_V1.16.0\Projects\STM32469I_EVAL\Applications\USB_Device\HID_Standalone.HS Electrical Test Tool (HSETT)

通过上述介绍可以了解到高速 USB 的信号质量测试,需要 USB 器件进入测试模式,提供符合测试的信号输出。基于此,下面列出例程中添加及修改处,以实现 HID 设备对测试模式的支持。

STM32 的高速 USB 信号质量测试实现

STM32 的高速 USB 信号质量测试实现

STM32 的高速 USB 信号质量测试实现

完成上述修改,编译生成执行文件,并加载到 STM32F469I-EVAL 板。注: 工程中包含三个子工程,分别是STM32469I-EVAL_USBD-FS、STM32469I-EVAL_USBD-HS-IN-FS 和 STM32469I-EVAL_USBD-HS,选择 STM32469IEVAL_USBD-HS实现高速 USB 的 HID 设备功能。

三 测试模式进入

利用 USB 数据线将 STM32F469I-EVAL 板上的高速 USB 口与电脑连接。如果 HID 例程运行正常,电脑会对将其识别为HID 设备,可在电脑的设备管理器中查看,如下图。

STM32 的高速 USB 信号质量测试实现

打开 HS Electrical Test Tool,出现主控制器选择界面,如下图。界面中内容及出现情况与电脑有关,如果电脑仅包含一个主控制器,不会出现选择界面。注意 HSETT 工具用于 USB2.0,如果电脑只有 USB3.0 主控制器,会出现无法找到USB2.0 主控制器的提示,并且不能使用。

STM32 的高速 USB 信号质量测试实现

从设备管理器进入,查看主控制器属性中的位置路径。查找与 HID 设备的位置路径关联的主控制器,如下图(主控制器的总线、设备和功能号信息,在下图界面的“常规”标签中)。

STM32 的高速 USB 信号质量测试实现

根据图中信息确定选择 “PCI 总线 0、设备 29、功能 7”,出现选择测试类型的界面,如下图。

STM32 的高速 USB 信号质量测试实现

本文中介绍 USB 设备的测试实现。选择 “Device”,单击“TEST”,进入测试模式的界面,如下图

STM32 的高速 USB 信号质量测试实现

界面中列出了挂载在主控制器上的 USB 设备硬件 ID,选择对应的设备。(实验时,对应 USB 主控制器上只挂载了STM32 实现的 HID 设备。)

点击 “Enumerate Bus”重新与设备建立枚举。枚举成功出现如下提示。

STM32 的高速 USB 信号质量测试实现

HSETT 提供了多种设备命令,如下图。为了实现眼图测试,选择“TEST_PACKET ”,单击“EXECUTE”,向 USB 设备发送设置 Test_Packet 模式的命令。

STM32 的高速 USB 信号质量测试实现

发送成功,并被 USB 设备正确响应后,出现如下提示。然后可以单击“Return To Main”  “Exit”退出 HSETT,释放主控制器的控制。

STM32 的高速 USB 信号质量测试实现

STM32 高速 USB 进入测试模式,通过 USB 接口连续循环地向外输出测试需要的信号。在进入测试模式后,信号的发送不受 USB 数据线连接的影响,断开 USB 数据线,依然会发送信号,以便获取眼图等测试信号。

四 小结

本文简略的从 STM32 角度,描述了高速 USB 信号质量测试中,涉及到的修改及实现。对于具体的测试及分析,不在本文介绍范围内,读者可以通过提供的参考文档 Universal Serial Bus Implementers Forum Device Hi-Speed Electrical TestProcedure,更加全面的了解信号质量测试的步骤及实现。另外,文件中以 HID 设备为例,但需知测试实现与哪种类型 USB设备无关。

来源: http://www.stmcu.com.cn

围观 1598

前言

在参考Cube软件包中I2C例程后, 根据应用需要新增了一路I2C接口,结果新增I2C无法收发数据。本文主要对问题进行描述,分析产生原因,提供解决方法。

一、问题描述

如前言所述,现象表现为I2C无法收发数据。得无法理解之处,在于之前已经完成了I2C的移植工作,并且运行正常。现在遵照正确的方式,新添一路I2C接口,只是更改了对应的I2C接口及引脚,为什么无法收发数据。简化测试程序如下。

GPIO_InitTypeDef GPIO_InitStruct;
 /* Enable GPIO TX/RX clock */
 I2Cx_SCL_GPIO_CLK_ENABLE();
 I2Cx_SDA_GPIO_CLK_ENABLE();
 /* Enable I2Cx clock */
 I2Cx_CLK_ENABLE();
 /*##-2- Configure peripheral GPIO ##########################################*/
 /* I2C TX GPIO pin configuration */
 GPIO_InitStruct.Pin = I2Cx_SDA_PIN;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
 GPIO_InitStruct.Pull = GPIO_PULLUP;
 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
 GPIO_InitStruct.Alternate = I2Cx_SCL_SDA_AF;
 HAL_GPIO_Init(I2Cx_SDA_GPIO_PORT, &GPIO_InitStruct);
 GPIO_InitStruct.Pin = I2Cx_SCL_PIN;
 HAL_GPIO_Init(I2Cx_SCL_GPIO_PORT, &GPIO_InitStruct);

 I2cHandle.Instance = I2Cx;
 I2cHandle.Init.ClockSpeed = 100000;
 I2cHandle.Init.DutyCycle = I2C_DUTYCYCLE;
 I2cHandle.Init.OwnAddress1 = 0;
 I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
 I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
 I2cHandle.Init.OwnAddress2 = 0;
 I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
 I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

 if(HAL_I2C_Init(&I2cHandle) != HAL_OK)
 {
 /* Initialization Error */
 Error_Handler();
 }
 while(1)
 {
 HAL_I2C_Master_Transmit(&I2cHandle, (uint16_t)I2C_ADDRESS, (uint8_t*)aTxBuffer,TXBUFFERSIZE, 10000);
 }

二 现象分析

将上述程序在STM32F469i-Disco板上实现,复现现象并寻找规律。发现规律如下:

I2C配置顺序引发的异常案例

分析上表可以发现问题的产生与硬件设计有一定关系。观察发现,如果I2C没有外部上拉时,会导致问题产生。

通过单步调试,定位于HAL_I2C_Master_Transmit(),在这个函数中调用的I2C_WaitOnFlagUntilTimeout()无法执行异常,返回HAL_BUSY,导致了I2C写功能失败。在I2C_WaitOnFlagUntilTimeout函数内部,是对忙标志位BUSY@I2Cx_SR2的检测。通过对参考手册的阅读(如下截图所述),如果在未占用I2C总线时,SDA或SCL引脚存在低电平,则意味着总线处于忙状态。这种检测机制在I2C接口失能时依然工作。

I2C配置顺序引发的异常案例

结合程序中调用顺序,在I2C3时钟使能时,虽然I2C3没有使能,但是忙状态检测已经开始。由于对应的SCL引脚上无上拉电阻,并且由于还未对I2C3的SCL引脚进行配置。此时SCL引脚为浮空输入状态,实际测量发现为低电平,BUSY标志被置位。

三 解决方法

通过现象及分析,可了解到问题可通过硬件或者软件解决。

硬件方面,为SDA、SCL引脚提供外部的I2C上拉电阻,问题不在出现。

软件方面,发现在对SCL、SDA引脚配置时会启用内部上拉。通过将I2C时钟使能代码放于I2C引脚配置语句后面,问题也不再出现。

需要注意, I2C的SDA、SCL引脚内部上拉电阻,为弱上拉。使用者可以通过对应型号STM32的数据手册,查看对应引脚的上拉电阻,以便判断是否能够满足应用需要。如下为STM32F469上拉电阻信息截图。

I2C配置顺序引发的异常案例

来源: STM32单片机

围观 859

STM32中,每一个GPIO都可以触发一个外部中断,但是,GPIO的中断是以组位一个单位的,同组间的外部中断同一时间只能使用一个。比如说,PA0,PB0,PC0,PD0,PE0,PF0,PG0这些为1组,如果我们使用PA0作为外部中断源,那么别的就不能够再使用了,在此情况下,我们智能使用类似于PB1,PC2这种末端序号不同的外部中断源。每一组使用一个中断标志EXTIx。EXTI0 – EXTI4这5个外部中断有着自己的单独的中断响应函数,EXTI5-9共用一个中断响应函数,EXTI10-15共用一个中断响应函数。

程序开发

其实上面那些基本概念和知识只是对STM32的中断系统有一个大概的认识,用程序说话将会更能够加深如何使用中断。使用外部中断的基本步骤如下:

1.设置好相应的时钟;
2.设置相应的中断;
3.IO口初始化;
4.把相应的IO口设置为中断线路(要在设置外部中断之前)并初始化;
5.在选择的中断通道的响应函数中中断函数。

根据原理图,K1/K2/K3连接的是PC5/PC2/PC3,因此我将用EXTI5/EXTI2/EXTI3三个外部中断。PB5/PD6/PD3分别连接了三个LED灯。中断的效果是按下按键,相应的LED灯将会被点亮。

1.设置相应的时钟

首先需要打开GPIOB、GPIOC和GPIOE(因为按键另外一端连接的是PE口)。然后由于是要用于触发中断,所以还需要打开GPIO复用的时钟。相应的函数在GPIO的学习笔记中有了详细了解释。详细代码如下:

void RCC_cfg()
{
//打开PE PD PC PB端口时钟,并且打开复用时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
}

设置相应的时钟所需要的RCC函数在stm32f10x_rcc.c中,所以要在工程中添加此文件。

2.设置好相应的中断

设置相应的中断实际上就是设置NVIC,在STM32的固件库中有一个结构体NVIC_InitTypeDef,里面有相应的标志位设置,然后再用NVIC_Init()函数进行初始化。详细代码如下:

void NVIC_cfg()
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //选择中断分组2

NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQChannel; //选择中断通道2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占式中断优先级设置为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应式中断优先级设置为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断
NVIC_Init(&NVIC_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQChannel; //选择中断通道3
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占式中断优先级设置为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //响应式中断优先级设置为1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断
NVIC_Init(&NVIC_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel; //选择中断通道5
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占式中断优先级设置为2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //响应式中断优先级设置为2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断
NVIC_Init(&NVIC_InitStructure);
}

由于有3个中断,因此根据前文所述,需要有3个bit来指定抢占优先级,所以选择第2组。又由于EXTI5-9共用一个中断响应函数,所以EXTI5选择的中断通道是EXTI9_5_IRQChannel,详细信息可以在头文件中查询得到。用到的NVIC相关的库函数在stm32f10x_nivc.c中,需要将此文件复制并添加到工程中。具体位置可以查看关于GPIO的笔记。这段代码编译起来没有任何问题,但是在链接的时候就会报错,需要把STM32F10xR.LIB加入工程中,具体位置在…KeilARMRV31LIBSTSTM32F10xR.LIB。

3.IO口初始化

void IO_cfg()
{
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //选择引脚2
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出频率最大50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //带上拉电阻输出
GPIO_Init(GPIOE,&GPIO_InitStructure);
GPIO_ResetBits(GPIOE,GPIO_Pin_2); //将PE.2引脚设置为低电平输出

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5; //选择引脚2 3 5
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //选择输入模式为浮空输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出频率最大50MHz
GPIO_Init(GPIOC,&GPIO_InitStructure); //设置PC.2/PC.3/PC.5

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_6; //选择引脚3 6
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出频率最大50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //带上拉电阻输出
GPIO_Init(GPIOD,&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //选择引脚5
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出频率最大50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //带上拉电阻输出
GPIO_Init(GPIOB,&GPIO_InitStructure);
}

其中连接外部中断的引脚需要设置为输入状态,而连接LED的引脚需要设置为输出状态,初始化PE.2是为了使得按键的另外一端输出低电平。GPIO中的函数在stm32f10x_gpio.c中。

4.把相应的IO口设置为中断线路

由于GPIO并不是专用的中断引脚,因此在用GPIO来触发外部中断的时候需要设置将GPIO相应的引脚和中断线连接起来,具体代码如下:
void EXTI_cfg()
{
EXTI_InitTypeDef EXTI_InitStructure;
//清空中断标志
EXTI_ClearITPendingBit(EXTI_Line2);
EXTI_ClearITPendingBit(EXTI_Line3);
EXTI_ClearITPendingBit(EXTI_Line5);
//选择中断管脚PC.2 PC.3 PC.5
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource3);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource5);
EXTI_InitStructure.EXTI_Line = EXTI_Line2 | EXTI_Line3 | EXTI_Line5; //选择中断线路2 3 5
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //设置为中断请求,非事件请求
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //设置中断触发方式为上下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //外部中断使能
EXTI_Init(&EXTI_InitStructure);
}

EXTI_cfg中需要调用到的函数都在stm32f10x_exti.c。

5.写中断响应函数

STM32不像C51单片机那样,可以用过interrupt关键字来定义中断响应函数,STM32的中断响应函数接口存在中断向量表中,是由启动代码给出的。默认的中断响应函数在stm32f10x_it.c中。因此我们需要把这个文件加入到工程中来。

在这个文件中,我们发现,很多函数都是只有一个函数名,并没有函数体。我们找到EXTI2_IRQHandler()这个函数,这就是EXTI2中断响应的函数。我的目标是将LED灯点亮,所以函数体其实很简单:

void EXTI2_IRQHandler(void)
{
//点亮LED灯
GPIO_SetBits(GPIOD,GPIO_Pin_6);
//清空中断标志位,防止持续进入中断
EXTI_ClearITPendingBit(EXTI_Line2);
}
void EXTI3_IRQHandler(void)
{
GPIO_SetBits(GPIOD,GPIO_Pin_3);
EXTI_ClearITPendingBit(EXTI_Line3);
}
void EXTI9_5_IRQHandler(void)
{
GPIO_SetBits(GPIOB,GPIO_Pin_5);
EXTI_ClearITPendingBit(EXTI_Line5);
}

由于EXTI5-9是共用一个中断响应函数,因此所有的EXTI5 – EXTI9的响应函数都写在这个里面。

6.写主函数

#include "stm32f10x_lib.h"
void RCC_cfg();
void IO_cfg();
void EXTI_cfg();
void NVIC_cfg();
int main()
{
RCC_cfg();
IO_cfg();
NVIC_cfg();
EXTI_cfg();
while(1);
}

main函数前是函数声明,main函数函数体中都是调用初始化配置函数,然后进入死循环,等待中断响应。

以上就是STM32外部中断的介绍,功能可以不用管,知道该配置哪些东西就够了。ok,基础知识学习完了吧!那么就可以买个具体模块来试试了。这里用的是四路数字触摸感应传感器模块。

下面是该模块的简要描述:

一、模块描述

该传感器模块是四路触摸感应模块,基于TTP224芯片。通过触摸数字(1、2、3、4),可以起到控制外围硬件电路的作用。手按数字开关,对应的灯(D1、D2、D3、D4)会亮,对应的四个输出口(OUT1、OUT2、OUT3、OUT4)中的一个会输出高电平。

模块参数:
1、板载TTP224电容式4键触摸感应IC
2、板载4路电平状态指示灯
3、工作电压:2.4V-5.5V
4、模块可以设置输出模式、键输出模式、最长输出时间和快速/低功耗选择
5、PCB板子尺寸:35(mm)x29(mm)

二、硬件调试

(1) 硬件实物图展示如下图:

利用STM32外部中断驱动四路数字触摸感应传感器模块

(2) 模块原理图接口展示如图:
利用STM32外部中断驱动四路数字触摸感应传感器模块

(3) 管脚实际连接表
利用STM32外部中断驱动四路数字触摸感应传感器模块

三、软件调试

本工程实现的功能是通过触摸传感器模块中的数字触发引脚的外部中断,从而控制核心板上LED灯闪烁以及K11开发板上的继电器。本案例基于光轮电子公司TreeOS软件开发架构运行,具体软件工程还请关注光轮电子公司TreeOS驱动库文件。

以下是工程图:

利用STM32外部中断驱动四路数字触摸感应传感器模块

来源: eeworld.com

围观 442

STM32 提供了丰富的接口资源,其中包括 USB FS、USB HS、OTG FS 和 OTG HS。对于高速 USB,由于信号速率相对较高。在开发过程中,会对高速 USB 信号质量进行测试,例如运用广泛的眼图测试。STM32 的高速 USB/OTG IP 遵循USB 2.0 规范,能够配合实现眼图等信号质量测试项。本文中,首先介绍眼图等信号质量测试的实现框架,然后以 Cube 软件包中 USB 设备类的 HID 例程为基础,提供软件层面的修改。最后通过 USB 官方提供的 HSETT 工具,一步一步呈现如何使STM32 实现的 USB 设备进入测试模式,以便使其输出用以获取眼图等测试项的信号。

一 信号质量测试背景介绍

高速 USB 信号质量测试,实现框架如下图。

STM32 的高速 USB 信号质量测试实现

根据测试需要,利用电脑端测试软件工具 HSETT,使 STM32 实现的 USB 设备进入相应的测试模式。然后利用示波器抓取测试信号,进行信号质量分析。本文中不包含示波器抓取信号的实现描述,读者可以通过文末的参考文档进行了解。

其中,HSETT 全称 High-speed Electrical Test Tool,是 USB 官方组织发布的一个发包工具(官网 www.usb.org 下载)。

STM32 的高速 USB IP 遵循 USB2.0 规范,支持多种测试模式,包括 Test_J 模式、Test_K 模式、Test_SE0_NAK 模式、Test_Packet 模式和 Test_Force_Enable 模式。更多测试模式内容的介绍请参考 USB2.0 规范。 更多内容请参考对应型号的参考手册。其中,如果是进行眼图测试,需要进入 Test_Packet 测试模式。

二 软件层面支持

本文中实现环境如下:

硬件平台: STM32F469I-EVAL
Cube 软件包版本: v1.16.0
HID 例程文件路径 :
STM32Cube_FW_F4_V1.16.0\Projects\STM32469I_EVAL\Applications\USB_Device\HID_Standalone.
HS Electrical Test Tool (HSETT)
通过上述介绍可以了解到高速 USB 的信号质量测试,需要 USB 器件进入测试模式,提供符合测试的信号输出。基于此,下面列出例程中添加及修改处,以实现 HID 设备对测试模式的支持。

STM32 的高速 USB 信号质量测试实现

完成上述修改,编译生成执行文件,并加载到 STM32F469I-EVAL 板。注: 工程中包含三个子工程,分别是
STM32469I-EVAL_USBD-FS、STM32469I-EVAL_USBD-HS-IN-FS 和 STM32469I-EVAL_USBD-HS,选择 STM32469I-EVAL_USBD-HS实现高速 USB 的 HID 设备功能。

三 测试模式进入

利用 USB 数据线将 STM32F469I-EVAL 板上的高速 USB 口与电脑连接。如果 HID 例程运行正常,电脑会对将其识别为HID 设备,可在电脑的设备管理器中查看,如下图。

STM32 的高速 USB 信号质量测试实现

打开 HS Electrical Test Tool,出现主控制器选择界面,如下图。界面中内容及出现情况与电脑有关,如果电脑仅包含一个主控制器,不会出现选择界面。注意 HSETT 工具用于 USB2.0,如果电脑只有 USB3.0 主控制器,会出现无法找到USB2.0 主控制器的提示,并且不能使用。

STM32 的高速 USB 信号质量测试实现

从设备管理器进入,查看主控制器属性中的位置路径。查找与 HID 设备的位置路径关联的主控制器,如下图(主控制器的总线、设备和功能号信息,在下图界面的“常规”标签中)。

STM32 的高速 USB 信号质量测试实现

STM32 的高速 USB 信号质量测试实现

本文中介绍 USB 设备的测试实现。选择 “Device”,单击“TEST”,进入测试模式的界面,如下图。

STM32 的高速 USB 信号质量测试实现

界面中列出了挂载在主控制器上的 USB 设备硬件 ID,选择对应的设备。(实验时,对应 USB 主控制器上只挂载了STM32 实现的 HID 设备。)
点击 “Enumerate Bus”重新与设备建立枚举。枚举成功出现如下提示。

STM32 的高速 USB 信号质量测试实现

HSETT 提供了多种设备命令,如下图。为了实现眼图测试,选择“TEST_PACKET ”,单击“EXECUTE”,向 USB 设备发送设置 Test_Packet 模式的命令。

STM32 的高速 USB 信号质量测试实现

发送成功,并被 USB 设备正确响应后,出现如下提示。然后可以单击“Return To Main”  “Exit”退出 HSETT,释放主控制器的控制。

STM32 的高速 USB 信号质量测试实现

STM32 高速 USB 进入测试模式,通过 USB 接口连续循环地向外输出测试需要的信号。在进入测试模式后,信号的发送不受 USB 数据线连接的影响,断开 USB 数据线,依然会发送信号,以便获取眼图等测试信号。

四 小结

本文简略的从 STM32 角度,描述了高速 USB 信号质量测试中,涉及到的修改及实现。对于具体的测试及分析,不在本文介绍范围内,读者可以通过提供的参考文档 Universal Serial Bus Implementers Forum Device Hi-Speed Electrical TestProcedure,更加全面的了解信号质量测试的步骤及实现。另外,文件中以 HID 设备为例,但需知测试实现与哪种类型 USB设备无关。

来源:ST

围观 855

在 Cube 软件包中,为不同系列 MCU、不同外设提供了对应的例程方便开发参考。其中,针对STM324xG-EVAL 平台提供了 UART 中断发送接收的例程。开发者参考了这个例程进行 UART 功能开发,并且为了实现不间断的接收功能,在接收回调函数中,再次调用中断接收函数。在这种情况下,出现了例程执行异常。本文分析了这种情况出现原因及解决方法。

问题描述

测试验证板: STM3240G-EVAL
参考例程路径:
STM32Cube_FW_F4_V1.15.0\Projects\STM324xG_EVAL\Examples\UART\UART_Hyperterminal_IT

基于上述例程,出于前言中交代的应用目的,在接收回调函数 HAL_UART_RxCpltCallback 中,再次调用 HAL_UART_Receive_IT。
随后出现例程执行卡死在下面红色标识的语句处,导致了 UART 中断发送无法正确被执行。

 if(HAL_UART_Receive_IT(&UartHandle, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
 {
 /* Turn LED3 on: Transfer error in reception process */
 BSP_LED_On(LED3);
 while(1)
 {
 }
 }
 /*##-4- Wait for the end of the transfer ###################################*/
 /* Before starting a new communication transfer, you need to check the current
 state of the peripheral; if it 抯 busy you need to wait for the end of current
 transfer before starting a new one.
 For simplicity reasons, this example is just waiting till the end of the
 transfer, but application may perform other tasks while transfer operation
 is ongoing. */
 while (HAL_UART_GetState(&UartHandle) != HAL_UART_STATE_READY)
 {
 }
 /*##-5- Send the received Buffer ###########################################*/
 if(HAL_UART_Transmit_IT(&UartHandle, (uint8_t*)aRxBuffer, RXBUFFERSIZE)!= HAL_OK)

问题分析及解决

根据描述,首先考虑到是否由于 UART 始终处于接收忙状态,导致中断发送收到影响。但是 UART 外设具有发送数据寄存器和接收数据寄存器,以及互不影响的接收、发送中断。

继续对问题进行定位,发现在 HAL_UART_GetState 函数中,会同时获取发送和接收状态。这意味着,只有在发送和接收同时处于就绪状态时,中断发送函数才会被执行。而开发者的应用实现中,使得UART 始终处于接收状态,从而判断无法通过。

清楚了产生原因后,问题解决就一目了然了。只需将对发送和接收状态的判断,改写成仅对发送的状
态的判断,如下所示。其中 gState 对应着发送状态。

//while (HAL_UART_GetState(&UartHandle) != HAL_UART_STATE_READY)
 while( UartHandle.gState != HAL_UART_STATE_READY)

总结

在使用 Cube 软件包例程时,最好能够对各驱动接口函数有一定认识。例如上述问题,对于例程来说,没有问题。但是转移到应用时,就需要考虑到例程中调用的判断函数是否符合应用目的了。

而对于各驱动接口函数,在函数定义处,都给出了介绍,包括各参数说明。同时,在 Cube 软件包的Drivers 目录下,提供了对驱动接口函数介绍的文档。

来源:ST

围观 589

前言

STM32 提供了灵活多样的外扩存储器访问实现。本文中,介绍如何利用 QSPI (QuadSPI) 外扩串行
NOR Flash 存储器。首先对 QSPI 接口功能特性进行介绍,然后分别介绍硬件设计和软件开发。并基于 STM32CubeMX,提供访问 MICRON N25Q128A13EF840F 的实现参考。

一 实现环境

开发板:STM32F469G-DISCO
开发库:STM32CubeF4 v1.16.0
STM32CubeMX: v4.22.0
集成开发环境:IAR v7.70.1.11486

实现过程在 STM32F469I-DISCO 板上展开,利用板上已有的串行 NOR Flash 存储器(MICRON
N25Q128A13EF840F)。呈现整个开发涉及环节。在本文中,首先根据 QSPI 接口,介绍 QSPI 与外扩串行存储器硬件连接。

另外,Cube 软件包中包含 QSPI 实现例,在本文对库中实现的 QSPI 例不做讨论,读者也可参考这些 QSPI 例进行设计。本文围绕由 STM32CubeMX 生成的工程,介绍如何实现对外扩串行 NOR Flash 存储器的访问。

二 QSPI 介绍

在呈现 QSPI 访问外扩 Flash 的实现例前, 需要对 QSPI 有一定的了解,在此对 QSPI 进行简短的介绍。更多内容请参考AN4760。

QSPI(Quad-SPI)支持四线串行访问形式。同时,QSPI 支持传统 SPI 和 Dual-SPI 模式,Dual-SPI 模式支持两线串行访问。与 FMC/FSMC 比较,QSPI 支持更低成本、更小封装外部串行 Flash 存储器,更少的 IO 引脚占用,有效减少 PCB 面积,降低 PCB 设计复杂度。

QSPI 在不同系列 STM32 产品线的支持情况(仅部分罗列,未涵盖所有支持型号)。

利用 QuadSPI 外扩串行 NOR Flash 的实现

QSPI 接口提供了灵活可配置的 5 个阶段,如下图所示(仅用于理解阶段构成,时序图根据配置不同存在差异)。分别是命令阶段、地址阶段、复用字节阶段、Dummy 阶段和数据阶段。可以根据外扩 Flash 中命令时序对不同阶段进行配置。后续会以实例进行呈现。更多内容请参考 AN4760。
利用 QuadSPI 外扩串行 NOR Flash 的实现

QSPI 支持三种模式,分别是:

间接模式 - 所有操作通过 QSPI 寄存器实现,类似于传统 SPI,可以使用阻塞模式、中断模式或者 DMA 模式进行读写等访问。本文中提供的实现例为间接模式下的实现。

状态轮询模式 - 接口自动轮询指定寄存器,直到回读寄存器内容与指定条件匹配。可应用于状态检测,从而实现忙等待等效果。本文不对此模式进行实现介绍,应用实现可参考 Cube 软件包中 QSPI 例程。

存储器映射模式 - 外扩 Flash 被视为内部存储器,支持 AHB 主器件直接访问,CPU 能够直接运行位于 QSPI 存储器的执行代码。内部系统架构如下图所示(以 STM32F469/F479 为例)。本文不对此模式进行实现介绍,应用实现可参考 Cube软件包中 QSPI 例程 QSPI_ExecuteInPlace。

利用 QuadSPI 外扩串行 NOR Flash 的实现

三 QSPI 外扩串行 Flash 实现例

3.1 串行 Flash 介绍

以 MICRON N25Q128A13EF840F 为例,更多细节请参考存储器手册。N25Q128A13EF840F 引脚图、时序图和电气参数来源于 N25Q128A13 手册文档。

支持协议: SPI, Dual I/O(对应 Dual-SPI), Quad I/O(对应 Quad-SPI)
支持访问模式: 单线访问、双线访问、四线访问,得益于 QSPI 接口的灵活可配性,三种访问模式全部支持。
供电电压范围: 2.7 ~ 3.6V
最大时钟频率: 108MHz
存储空间: 128Mb (16MB)

器件引脚示意图如下所示。由两根电源引脚和六根 QSPI 信号线构成。

利用 QuadSPI 外扩串行 NOR Flash 的实现

下表为存储器 N25Q128A13xxx 命令(未列出全部命令)。通过下表可知,存储器提供了灵活的访问实现形式,而结合同样灵活可配的 QSPI 接口,能够实现存储器命令全支持。而本文仅为提供设计思路,呈现了部分命令在 QSPI 上的实现。

利用 QuadSPI 外扩串行 NOR Flash 的实现

3.2 硬件设计

涉及到的信号线少,硬件设计简单,只需直接将 QSPI 的六根信号线与存储器连接即可。考虑到可测性,可以增加串行电阻或者测试点。硬件电路图如下所示。

利用 QuadSPI 外扩串行 NOR Flash 的实现

QSPI 接口 PCB 设计遵循如下几点,更多硬件设计内容请参考 AN4488。

a. 线阻 50Ω ±10%
b. 最大线长 < 120mm
c. 避免在不同信号层走信号线
d. 时钟线至少离其他信号线 3 倍线宽距离
e. 数据信号线长差 ≤ 10mm
f. 避免时钟线采用蛇形走线,同时尽量减少数据线上过孔。

3.3 软件开发流程

利用 QuadSPI 外扩串行 NOR Flash 的实现

3.4 软件实现例

在环境搭建完成后,就可以利用 STM32CubeMX 根据硬件连接情况,进行 QSPI 配置,获取 IAR 工程。具体软件实现流程如下。

利用 QuadSPI 外扩串行 NOR Flash 的实现

a. 利用 STM32CubeMX 生成 IAR 工程
打开 STM32CubeMX  点击”New project”  在”Part Number Search’中输入 STM32F469NI  点击”MCUs Liast”中出现的 STM32F469NIHx  点击“Start Project”  此时,基于 STM32F469NIHx 的 STM32CubeMX 工程被打开。

如下,根据 STM32F469I-DISCO 板硬件连接情况(QSPI NCS, CLK, Q0, Q1, Q2, Q3 对应 PB6, PF10, PF8, PF9,PF7, PF6;外部高速晶振为 8MHz 无源晶振;调试接口采用 SWD 接口,其中 SWCLK, SWDIO 对应 PA14, PA13):选择” QuadSPI”为”Bank1 with Quad SPI Lines”(注:也可在开发过程中,先用 STM32CubeMX 查看 QSPI 接口对应的 IO 引脚,进行硬件开发) 。

注: 在如上选择后,右侧引脚图中 QSPI 对应的引脚会呈现绿色显示。需要根据电路图中所连接的 QSPI 引脚,进行复用引脚确认。例如,在默认情况下,QSPI IO0 对应到 PC9 引脚,而 STM32F469I-DISCO 板上的 QSPI IO0 与PF8 连接,并非 PC9。所以,需要在右侧引脚图中,按住 Ctrl 键,左键在 PC9 引脚按下,拖动至 PF8 处,松开左键和 Ctrl 键,实现 IO0 引脚的关联。

选择“High Speed Clock(HSE)”为“Crystal/Ceramic Resonator”。

选择”Debug”为”Serial Wire”

利用 QuadSPI 外扩串行 NOR Flash 的实现

时钟配置如下图所示。设置输入时钟频率为 8MHz  选择”HSE”做为 PLL 倍频时钟源  选择”PLLCLK”做为主频时钟源  设置 “HCLK”为 180MHz (FAHB 为 180MHz) 点击 Enter 键,自动生成对应主频的时钟参数(仅提供时钟配置参考,并不限制一定要设置 180MHz 主频)。

利用 QuadSPI 外扩串行 NOR Flash 的实现

QSPI 配置如下图。参数的配置需要与存储器参数匹配。

• FIFO Threshold(FIFO 阈值) 配置为 4,并不严格要求。
• Smaple shift 选择“Sample shifting half cycle”。延后半个时钟,获取数据线上数据。可以使用在由于线路设计,数据信号存在较大延迟的场景。

利用 QuadSPI 外扩串行 NOR Flash 的实现

使能 QSPI 中断。

利用 QuadSPI 外扩串行 NOR Flash 的实现

点击菜单栏”Project”  “Settings”  设置”Project Name” , “Project Location” 和 “Toolchain / IDE” 。其中“Toolchain/ IDE”设置为 EWARM 以便生成对应 IDE 的工程。其他选项保持默认。

点击菜单栏”Project”  “Generate Code”  等待 IAR 工程生成,出现”Code Generation”界面  点击”Open Project” 打开工程。

b. 完善工程。
由上述步骤获得的 IAR 工程中,包含了时钟配置及 QSPI 接口的初始化。对于外扩 Flash 的操作,还需要 添加外扩 Flash 支持的命令进行操作。N25Q128A13EF840F 支持的部分命令可参见本文 3.1 小结。

在这里出于简化考虑,仅提供了阻塞式读取 ID,擦除 Flash,块写和快读操作的实现。更多实现模式,可以参考Cube 软件包中提供的 QSPI 例程。

在 N25Q128A13EF840F 手册中提供了读 ID 命令时序,如下图所示。

利用 QuadSPI 外扩串行 NOR Flash 的实现

由时序图可知,读 ID 时序构成: 命令阶段 + 数据阶段。命令阶段和数据阶段线宽都为 1,读 ID 命令码为 0x9E 或者0x9F,ID 数据长度为 17 字节。

在 N25Q128A13EF840F 手册中提供了写使能命令时序,如下图所示。

利用 QuadSPI 外扩串行 NOR Flash 的实现

由时序图可知,块擦除时序仅有命令阶段。命令阶段线宽为 1,写使能命令码为 0x06。(注:这里仅呈现了单线命令模式的实现。除此之外,STM32 QSPI 接口和外扩存储器支持双线、四线模式)。

在 N25Q128A13EF840F 手册中提供了扇区擦除命令时序,如下图所示。

利用 QuadSPI 外扩串行 NOR Flash 的实现

由时序图可知,扇区擦除时序构成:命令阶段+地址阶段。命令阶段和地址阶段线宽为 1,扇区擦除命令码为 0xD8。

其中地址为 24-bit,任一位于需要进行擦除操作的扇区范围内地址都有效。在此简单选择扇区 0 进行擦除,选择地址为 0。(注:这里仅呈现了单线命令模式的实现。除此之外,STM32 QSPI 接口和外扩存储器支持双线、四线模式)。

在 N25Q128A13EF840F 手册中提供了四线快速写命令时序,如下图所示。

利用 QuadSPI 外扩串行 NOR Flash 的实现

由时序图可知,四线快速写命令时序构成:命令阶段+地址阶段+数据阶段。命令阶段和地址阶段线宽为 1,数据阶段线宽为 4,四线快速写命令码为 0x32。其中地址为 24-bit,对应写入起始地址。(注:这里仅呈现了单线命令模式的实现。除此之外,STM32 QSPI 接口和外扩存储器支持双线、四线模式)。

在 N25Q128A13EF840F 手册中提供了四线快速读命令时序,如下图所示。

利用 QuadSPI 外扩串行 NOR Flash 的实现

由时序图可知,四线快速读命令时序构成:命令阶段+地址阶段+数据阶段。命令阶段和地址阶段线宽为 1,数据阶段线宽为 4,四线快速读命令码为 0x6B。其中地址为 24-bit,对应写入起始地址。四线快速读命令默认 Dummy cycles 为 8。(注:这里仅呈现了单线命令模式的实现。除此之外,STM32 QSPI 接口和外扩存储器支持双线、四线模式)。

在 main.c \ main 函数中,增加代码如下。

 … //系统、时钟、IO 和 QSPI 初始化
 /* USER CODE BEGIN 2 */
 QSPI_CommandTypeDef sCommand;
 static uint8_t Buf_ID[17] = {0};
 static uint8_t TxBuf[0x10] = "Ext Flash", RxBuf[0x10] = {0};

 sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; //DDR 模式失能
 sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; //DDR 模式下,数据延迟输出
 sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; //每次发送都包含命令阶段

 /***** 读 ID 操作 *****/
 sCommand.Instruction = 0x9F; //READ ID 命令码
 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; //命令线宽
 sCommand.AddressMode = QSPI_ADDRESS_NONE; //地址线宽。无地址阶段
 sCommand.DataMode = QSPI_DATA_1_LINE; //数据线宽
 sCommand.NbData = 17; //读取数据长度。ID 长度为 17 字节
 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无复用字节阶段
 sCommand.DummyCycles = 0; //无 Dummy 阶段
 //配置命令(在有数据阶段时,命令在后续发送/接收 API 调用时发送)
 if (HAL_QSPI_Command(&hqspi, &sCommand, 5000) != HAL_OK)
 {
 Error_Handler();
 }
 //执行 QSPI 接收
 if (HAL_QSPI_Receive(&hqspi, Buf_ID,5000) != HAL_OK)
 {
 Error_Handler();
 }
 HAL_Delay(1); //延时 1ms. 单位为 SysTick 定时中断周期

 /***** 写使能操作(需要在块擦除之前,使外扩存储器处于写使能状态) *****/
 sCommand.Instruction = 0x06; //写使能 命令码
 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; //命令线宽
 sCommand.AddressMode = QSPI_ADDRESS_NONE; //地址线宽。无地址阶段
 sCommand.DataMode = QSPI_DATA_NONE; //数据线宽。无数据阶段
 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无复用字节阶段
 sCommand.DummyCycles = 0; //无 Dummy 阶段
 //配置发送命令
 if (HAL_QSPI_Command(&hqspi, &sCommand, 5000) != HAL_OK)
 {
 Error_Handler();
 }

 /***** 块擦除操作 *****/
 sCommand.Instruction = 0xD8; //扇区擦除 命令码
 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; //命令线宽
 sCommand.AddressMode = QSPI_ADDRESS_1_LINE; //地址线宽。无地址阶段
 sCommand.AddressSize = QSPI_ADDRESS_24_BITS; //地址长度
 sCommand.Address = 0; //位于所需擦除扇区内的任一地址。
 sCommand.DataMode = QSPI_DATA_NONE; //数据线宽。无数据阶段
 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无复用字节阶段
 sCommand.DummyCycles = 0; //无 Dummy 阶段
 //配置发送命令
 if (HAL_QSPI_Command(&hqspi, &sCommand, 5000) != HAL_OK)
 {
 Error_Handler();
 }
 HAL_Delay(3000); //延时 3s. 单位为 SysTick 定时中断周期

 /***** 写使能操作(需要在块擦除之前,使外扩存储器处于写使能状态) *****/
 sCommand.Instruction = 0x06; //写使能 命令码
 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; //命令线宽
 sCommand.AddressMode = QSPI_ADDRESS_NONE; //地址线宽。无地址阶段
 sCommand.DataMode = QSPI_DATA_NONE; //数据线宽。无数据阶段
 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无复用字节阶段
 sCommand.DummyCycles = 0; //无 Dummy 阶段
 //配置发送命令
 if (HAL_QSPI_Command(&hqspi, &sCommand, 5000) != HAL_OK)
 {
 Error_Handler();
 }

 /***** 四线快速写操作 *****/
 sCommand.Instruction = 0x32; //四线快速写 命令码
 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; //命令线宽
 sCommand.AddressMode = QSPI_ADDRESS_1_LINE; //地址线宽
 sCommand.AddressSize = QSPI_ADDRESS_24_BITS; //地址长度
 sCommand.Address = 0; //写入起始地址
 sCommand.DataMode = QSPI_DATA_4_LINES; //数据线宽
 sCommand.NbData = 10; //写入数据长度
 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无复用字节阶段
 sCommand.DummyCycles = 0; //无 Dummy 阶段
 //配置命令(在有数据阶段时,命令在后续发送/接收 API 调用时发送)
 if (HAL_QSPI_Command(&hqspi, &sCommand, 5000) != HAL_OK)
 {
 Error_Handler();
 }
 //执行 QSPI 接收
 if (HAL_QSPI_Transmit(&hqspi, TxBuf ,5000) != HAL_OK)
 {
 Error_Handler();
 }
 HAL_Delay(5); //延时 5ms. 单位为 SysTick 定时中断周期

 /***** 四线快速读操作 *****/
 sCommand.Instruction = 0x6B; //四线快速读 命令码
 sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; //命令线宽
 sCommand.AddressMode = QSPI_ADDRESS_1_LINE; //地址线宽
 sCommand.AddressSize = QSPI_ADDRESS_24_BITS; //地址长度
 sCommand.Address = 0; //起始地址
 sCommand.DataMode = QSPI_DATA_4_LINES; //数据线宽
 sCommand.NbData = 10; //读取数据长度
 sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无复用字节阶段
 sCommand.DummyCycles = 8; //Dummy 阶段。N25Q128A13EF840F
Dummy cycles 默认为 15
 //配置命令(在有数据阶段时,命令在后续发送/接收 API 调用时发送)
 if (HAL_QSPI_Command(&hqspi, &sCommand, 5000) != HAL_OK)
 {
 Error_Handler();
 }
 //执行 QSPI 接收
 if (HAL_QSPI_Receive(&hqspi, RxBuf,5000) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE END 2 */

四 小结

STM32 的 QuadSPI 接口灵活可配,对于命令阶段、地址阶段、复用字节阶段、Dummy 阶段和数据阶段都可以进行配置。基于这种灵活性,能够实现市面上 SPI、Dual IO、Quad IO 的串行 Flash 支持。但出于简化考虑,QSPI 支持的中断访问及DMA 访问等更多功能没有在本文进行介绍,更多实现可以参考 ST 提供的 Cube 软件包中的 QSPI 例程。另外,不同厂家的串行 Flash 命令及操作实现略有差异,具体以采用的 Flash 文档描述为准。

相关文档
AN4760 Quad-SPI (QSPI) interface on STM32 microcontrollers
AN4488 Getting started with STM32F4xxxx MCU hardware development
RM0386 STM32F469xx and STM32F479xx advanced ARM®-based 32-bit MCUs

相关工具&链接
STM32CubeMX http://www.st.com/content/st_com/en/products/development-tools/software-...
STM32CubeF4 http://www.st.com/content/st_com/en/products/embedded-software/mcus-embe...

来源: ST

围观 4403

页面

订阅 RSS - STM32