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 - 使用 STM32 来控制 NeoPixels

目前,诸如 Arduino  Feather 等高级开发平台已经提供了出色的支持,可以通过易于使用的库和普遍使用的示例代码与NeoPixel LED 灯带矩阵 等相连接。然而,更高级的平台(例如 STM32 开发板 )通常缺乏相同水平的支持。因此,希望将NeoPixels整合到项目中的 开发人员需要全面了解NeoPixel通信协议以及如何克服它所带来的挑战。




1.gif

NeoPixels

Adafruit 推出的极受欢迎的可寻址全彩LED灯“NeoPixels”系列分为RGB和RGBW两个种类。尽管二者都将红、绿和蓝色LED与驱动器芯片相集成,但RGBW组件还集成了第四个纯白色的LED。可以使用类似的单线串行接口来控制这两种类型的NeoPixel,其时间值和数据结构仅存在微小的差异。

WS2812

RGB NeoPixels实际上是WS2812智能控制LED,包括数据信号输入引脚(DIN)和数据信号输出引脚(DOUT)。这允许多个LED级联并且只用一个数据线进行控制。链中的第一个LED负责处理从MCU接收到的前三个字节数据,然后将后续的数据简单地转发给DOUT引脚,该引脚可以连接到另一个LED的DIN引脚。LED将以此方式继续向下传递数据,直到它们接收到复位信号为止(即,DIN线在一段时间内持续保持低电平状态)。传输的字节按照图1所示的协议进行组织。第一个字节(G7-G0)表示绿色LED的8位PWM强度,其中0x00是完全关闭,0xFF是完全打开。类似地,第二个字节(R7-R0)用于控制红色LED的强度,第三个字节(B7-B0)用于控制蓝色LED的强度。

2.jpg

图 1 : WS2812 LED的3字节数据协议的结构

这些24位数据都是通过改变方波的脉冲宽度来进行编码的,如图2所示。请注意,无论发送代码0还是代码1,方波的周期仍保持在1.25μs。对于WS2812,使数据线保持低电平至少50μs即可生成复位信号。另请注意,图2中显示的计时值具有±0.15μs的公差。

3.jpg
图2:WS2812 LED的0和1位的计时图

一种截然不同的组件,NeoPixels的RGBW种类实际上是SK6812智能控制LED,采用与WS2812 LED相同的运作原理。然而,由于它们包含第四个LED,因此实施了图3所示的4字节数据协议。与图1相比,唯一的区别在于数据的串联字节(W7-W0),该字节指定了白色LED的8位PWM强度。

4.jpg

图 3 : SK6812 LED的4字节数据协议的结构。

图4展示了SK6812控制信号的时间值,同样与WS2812略有差别(不过仍在±0.15μs的公差范围内)。请注意,这两种代码的方波周期均保持不变,都为1.2μs。此外,SK6812的复位信号长度为80μs ,而非50μs。

5.jpg
图4:SK6812 LED的0位和1位的计时图。

步骤

由于NeoPixel的控制信号对计时要求非常严格,因此除非使用汇编语言,否则无法通过简单的比特带宽方法产生此信号。虽然还有许多其他方法可以利用各种MCU外设、外部硬件或其组合来生成该信号,但其中最直接的方法是配置MCU定时器来生成PWM输出信号。这是因为,如上一部分中所述,NeoPixel控制信号只是一种固定频率的PWM信号,采用不同的占空比表示0位和1位。为了以与传输协议相同的速率高效地在这两个占空比之间进行切换,还必须配置DMA流来管理更新。尽管这种方法可能是内存效率最低的方式,但它易于理解、CPU高效并且易于实施(得益于STM32Cube环境)。

以下应用程式利用STM32CubeIDE(版本1.8.0)、NUCLEO-F401RE开发板和RGBW 5x8 NeoPixel Shield实现上述的方法。不过,这些步骤可以轻松地推广到任何STM32 MCU/板和NeoPixel产品上。假定我们已经创建了一个STM32CubeIDE项目。如需使用其他IDE,你可以改为使用独立的STM32CubeMX代码配置器工具,将项目导出到所需的开发平台上。

1.配置PWM

a. 先打开STM32CubeMX配置.ioc 文件(如果还未打开的话)。随后,STM32CubeIDE将切换到*器件配置工具(*Device Configuration Tool ) 视图,供你配置MCU。

b. 将定时器通道备用功能分配给选定的GPIO引脚,以与NeoPixel进行连接。所选定时器通道应该能够生成PWM输出。图5显示了我的项目中的相关部分,我选择了引脚PB10,并将它分配给定时器2、通道3(TIM2_CH3)功能。

6.jpg

图5:将连接到DIN的GPIO引脚配置为定时器通道

c. 从左侧的组件列表中选择上一步中确定的定时器外设,以打开模式和配置(*Mode and Configuration ) 面板。在模式(*Mode ) 面板中,选择“内部时钟”作为时钟源,并从适当的定时器通道的下拉列表中选择“PWM生成CHx”。在图6中,定时器2、通道3已设为“PWM生成CH3”模式,因为我在上一步中选择了TIM2_CH3备用功能。请注意,在完成此步骤后,关联的GPIO引脚应在引脚排列视图中从黄色变为绿色。

d. 在定时器的*配置(*Configuration ) 面板中,验证“预分频器”和“脉冲”值是否都设置为0。计数器周期,即自动重载寄存器(ARR),需要进行设置以得到所需的PWM周期(如果使用RGB WS2812 LED,则为1.25μs;如果使用RGBW SK6812 LED,则为1.2μs)。这将取决于定时器外设输入的速率。只需将所需的PWM周期除以时钟周期,并减去1即可得到此值(减去1是因为定数器从0开始)。就我的器件而言,该公式得出的ARR值为99.8,我将其四舍五入为100(图6)。请参见下文,了解有关计算理想ARR值的详细说明。

7.jpg
图6:将所选定时器通道配置为PWM输出

计算ARR值

假设定时器“预分频器”值设为0,可以很容易的计算出ARR值

8.jpg

具体来说,ARR值等于PWM信号周期除以定时器外设的时钟信号周期。我们知道,根据使用的NeoPixel类型不同,TPWM可以是1.25μs或1.2μs(例如本例中,TPWM=1.2μs)。要确定Ttimer,你需要查阅器件的规格书,确定定时器外设连接到哪个总线。规格书可以在ST的网站上找到或STM32CubeIDE会随附提供:选择帮助>目标器件文档和资源( Help > Target Device Docs and Resources ) 。然后,在MCU 选项卡下选择规格书,如图7所示。

9.jpg

图 7 : 查找器件规格书

在我使用的MCU(STM32F401RE)规格书中,器件框图中显示我的定时器(TIM2)已连接到APB1(见图8)。

10.jpg

图 8 : STM32F401xD/xE的部分框图(源自DS10086

图9介绍了:通过切换到STM32CubeIDE中的*时钟配置(*Clock Configuration)选项卡,我们可以发现TIM2的时钟频率为84MHz11.jpg

12.jpg

图 9 : 确定定时器时钟频率
因此,
13.jpg

为了使PWM周期尽可能接近NeoPixel控制信号的周期,我们四舍五入至最接近的整数并得到 ARR=100 。

2.配置DMA

a. 从组件列表中选择DMA外设。

b. 在配置(Configuration) 面板的DMA1 选项卡下,点击添加 ( Add ) 按钮。在下拉菜单中,选择你的定时器/通道组合。在我的项目中,我选择了“TIM2_CH3/UP”。

c. 针对该新的DMA请求,将方向改为“内存到外设”。

d. 同时,将优先级改为“非常高”。

e. 验证默认的DMA请求设置是否与图10中显示的相匹配。

f. 保存.ioc 文件,以生成项目代码。

14.jpg

图 10 : 配置DMA流,以便有效更新PWM信号的占空比

3.编写代码

在main.c 文件中,按从上到下的顺序编写,本部分展示了一个简单的示例应用,用于测试NeoPixel LED的全彩能力。此处提供了两个版本的main() 函数,一个用于RGB WS2818 LED,另一个用于RGBW SK6812 LED。

a. 在main.c 文件的私有typedef部分,你可以创建一个新的数据类型,以便轻松访问单个LED颜色值以及整个NeoPixel数据结构(如图1和图3所示)。列表1提供了RGB和RGBW NeoPixel组件的typedef。此代码应粘贴在/* USER CODE BEGIN PTD */ 和/* USER CODE END PTD */ 注释之间。

列表 1 : 为RGB WS2812和RGBW SK6812 LED自定义数据类型

typedef union

{

struct

{

uint8_t b;

  uint8_t r;

uint8_t g;

} color;

uint32_t data;

} PixelRGB_t;

typedef union

{

struct

{

uint8_t w;

uint8_t b;

uint8_t r;

uint8_t g;

} color;

uint32_t data;

} PixelRGBW_t;

b. 更改“脉冲”寄存器(也称为CCRx)的值,这样可以改变PWM波形的占空比。因此,我们必须计算适当的CCRx值,以实现使用的NeoPixels所需的代码0和代码1方波(无论是在图2还是图4中所示的那些)。对于RGB WS2812 LED,这些值计算如下:

ZERO=(ARR+1)(0.32)

ONE=(ARR+1)(0.64)

对于RGBW SK6812 LED,其计算过程稍有不同。

ZERO=(ARR+1)(0.25)

ONE=(ARR+1)(0.5)

当然,这些计算出的值应该四舍五入到最接近的整数。在 main.c 文件的私有定义部分,为每个值创建一个#define指令(请参见以下图11中的示例)。

c. 除了CCRx值之外,还应在私有定义部分中定义控制的NeoPixel LED数量和DMA缓冲区大小。如图11所示,只需将LED的数量乘以相应的NeoPixel数据结构中的位数即可(回想图1和图3)。还必须分配一个额外的缓冲区元素,因为最后一个CCRx值应为零(复位信号)。

15.jpg

图 11 : WS2812和SK6812 LED的私有定义

d. 将列表2中提供的DMA完成回调函数添加到/* USER CODE BEGIN 0 /和/ USER CODE END 0*/之间的私有用户代码部分。务必将 TIM_CHANNEL_x 更改为步骤1c中配置的通道。

列表 2 : HAL_TIM_PWM_PulseFinishedCallback() 函数的实施

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)

{

HAL_TIM_PWM_Stop_DMA(htim, TIM_CHANNEL_x);

}

e. 最后,必须将应用代码添加到main() 函数中。列表3提供了一个使用WS2812 LED的示例main() 函数,而列表4提供了使用SK6812 LED的类似示例main() 函数。请注意,HAL_TIM_PWM_Start_DMA() 函数的TIM_CHANNEL_x 参数必须再次进行修改,以匹配步骤1c中配置的通道。

列表 3 : RGB WS2812 LED的示例main() 函数

int main(void)

{

/* USER CODE BEGIN 1 */

PixelRGB_t pixel[NUM_PIXELS] = {0};

uint32_t dmaBuffer[DMA_BUFF_SIZE] = {0};

uint32_t *pBuff;

int i, j, k;

uint16_t stepSize;

/* USER CODE END 1 */

/* MCU Configuration--------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */

SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_USART2_UART_Init();

MX_DMA_Init();

MX_TIM2_Init();

/* USER CODE BEGIN 2 */

/* USER CODE END 2 */

/* Infinite loop */

/* USER CODE BEGIN WHILE */

k = 0;

stepSize = 4;

while (1)

{

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

for (i = (NUM_PIXELS - 1); i > 0; i--)

{

pixel[i].data = pixel[i-1].data;

}

if (k < 255)

{

pixel[0].color.g = 254 - k; //[254, 0]

pixel[0].color.r =  k + 1;  //[1, 255]

pixel[0].color.b = 0;

}

else if (k < 510)

{

pixel[0].color.g = 0;

pixel[0].color.r = 509 - k; //[254, 0]

pixel[0].color.b = k - 254; //[1, 255]

j++;

}

else if (k < 765)
{

pixel[0].color.g = k - 509; //[1, 255];

pixel[0].color.r = 0;

pixel[0].color.b = 764 - k; //[254, 0]

}

k = (k + stepSize) % 765;

// not so bright

pixel[0].color.g >>= 2;

pixel[0].color.r >>= 2;

pixel[0].color.b >>= 2;

pBuff = dmaBuffer;

for (i = 0; i < NUM_PIXELS; i++)

{

for (j = 23; j >= 0; j--)

{

if ((pixel[i].data >> j) & 0x01)

{

*pBuff = NEOPIXEL_ONE;

}

else

{
*pBuff = NEOPIXEL_ZERO;

}

pBuff++;

}

}

dmaBuffer[DMA_BUFF_SIZE - 1] = 0; // last element must be 0!

HAL_TIM_PWM_Start_DMA(&htim2, TIM_CHANNEL_x, dmaBuffer, DMA_BUFF_SIZE);

HAL_Delay(10);

}

/* USER CODE END 3 */

}

列表 4 : RGBW SK6812 LED的示例main() 函数

int main(void)

{

/* USER CODE BEGIN 1 */

PixelRGBW_t pixel[NUM_PIXELS] = {0};

uint32_t dmaBuffer[DMA_BUFF_SIZE] = {0};

uint32_t *pBuff;

int i, j, k;

uint16_t stepSize;

/* USER CODE END 1 */

/* MCU Configuration--------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */

SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_USART2_UART_Init();

MX_DMA_Init();

MX_TIM2_Init();

/* USER CODE BEGIN 2 */

/* USER CODE END 2 */

/* Infinite loop */

/* USER CODE BEGIN WHILE */

k = 0;

stepSize = 4;

while (1)
{

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

for (i = (NUM_PIXELS - 1); i > 0; i--)

{
pixel[i].data = pixel[i-1].data;

}

if (k < 255)

{

pixel[0].color.g = 254 - k; //[254, 0]

pixel[0].color.r =  k + 1; //[1, 255]

pixel[0].color.b = 0;

pixel[0].color.w = 0;

}

else if (k < 510)

{

pixel[0].color.g = 0;

pixel[0].color.r = 509 - k; //[254, 0]

pixel[0].color.b = k - 254; //[1, 255]

pixel[0].color.w = 0;

j++;

}
else if (k < 765)

{

pixel[0].color.g = 0;

pixel[0].color.r = 0;

pixel[0].color.b = 764 - k; //[254, 0]

pixel[0].color.w = k - 509; //[1, 255]

}

else if (k < 1020)

{

pixel[0].color.g = k - 764; //[1, 255]

pixel[0].color.r = 0;

pixel[0].color.b = 0;

pixel[0].color.w = 1019 - k; //[254, 0]

}

k = (k + stepSize) % 1020;

// 50% brightness

pixel[0].color.g >>= 2;

pixel[0].color.r >>= 2;

pixel[0].color.b >>= 2;

pixel[0].color.w >>= 2;

pBuff = dmaBuffer;

for (i = 0; i < NUM_PIXELS; i++)

{

for (j = 31; j >= 0; j--)

{

if ((pixel[i].data >> j) & 0x01)

{

*pBuff = NEOPIXEL_ONE;

}

else

{

*pBuff = NEOPIXEL_ZERO;

}

pBuff++;

}

}

dmaBuffer[DMA_BUFF_SIZE - 1] = 0; // last element must be 0!

HAL_TIM_PWM_Start_DMA(&htim2, TIM_CHANNEL_x, dmaBuffer, DMA_BUFF_SIZE);

HAL_Delay(10);

}

/* USER CODE END 3 */

}

该项目现在应该能够成功构建,并支持你在器件上运行代码了。

结论

使用逻辑分析仪捕获了上面提供的RGB和RGBW配置生成的控制信号。分别如图12和图13中所示。请注意,它们与图2和图4中指定的预期输出相匹配。

16.jpg

图 12 : 生成的WS2812控制信号(正在发送0b0011……)

17.jpg

图 13 : 生成的SK6812控制信号(正在发送0b0010……)

来源:得捷电子DigiKey

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 63

01、前言

有客户反馈,使用STM32F4的TIM2结合DMA,产生的PWM波形不符合预期,但是相同的配置使用在TIM3上,得到的PWM波形就是符合预期的。其代码和配置都是从F1移植过来的,在F1上使用TIM2是没有问题的,对于F4的TIM2发生的问题,客户一直没有找到根本原因。

02、实验

根据客户的反馈,我们进行了实验。

硬件:STM32F401RE-NUCLEO

在STM32CubeMX中,将TIM2和TIM3所有参数均做相同的配置,其中配置DMA两端均为halfword长度。

1.png

2.png

生成代码,并定义两个数组如下图所示:

3.png

在主函数中开启Timer。

4.png

我们可以发现,实验结果如客户反馈的,TIM2输出的PWM是不正确的,TIM3输出的PWM是正确的。

5.png

03、分析

我们的实验中,TIM2和TIM3的配置是完全一样的,即使传输相同的数据,得到的PWM波形也是不同的。为此我们比较了TIM2和TIM3的硬件属性,可以很容易查看出,TIM2的计数器是32bit的,而TIM3的计数器是16bit的。

我想我们已经知道答案了,TIM2的计数器是32bit的,但是我们配置的DMA是halfword长度,这在AHB总线上解析数据时产生了非预期的结果。在调试界面我们也能看到,当问题发生时,TIM2的CCR1竟然比ARR的值要大,或者出现异常值,所以出现异常波形。

6.png

根本原因在于,对于大部分STM32系列,主设备基于AHB外设进行寻址是不支持byte/half-word传输的,总线会强制将数据转化为32bit传送到总线上,这就是为什么我们看到CCR1的高半字和低半字的值是相同的原因。

当我们将TIM2的DMA外设端修改为word长度,并将内存数组定义为32bit,再次实验,可以发现PWM的波形就是正常的了:

7.png

8.png

9.png

04、小结

因为F103上没有32bit计数器的Timer,所以客户在F103上并没有出现类似的问题。在使用DMA访问经过AHB转APB的桥接外设时,我们要注意DMA对外设的访问宽度配置问题。

来源:STM32单片机

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 183

基于STM32分析栈、堆、全局区、常量区、代码区、RAM、ROM

cathy的头像

在一个STM32程序代码中,从内存高地址到内存低地址,依次分布着栈区、堆区、全局区(静态区)、常量去、代码区,其中全局区中高地址分布着.bss段,低地址分布着.data段。

01、引言

在STM32的应用中,SPI算是用的比较多的外设了,也是单片机最常见外设之一。客户说它执行了关闭SPI的代码,竟然会导致Flash中的WRPERR标志置位,致使应用碰到一些问题。这就奇怪了,SPI和内部Flash看起来是风马牛不相及的事情,为什么会发生这种事呢?一起来看看吧。

02、问题

2.1 问题起源

客户在使用STM32L072RBT6的时候,使用STM32 CubeL0库,在程序编写时,发现执行关闭SPI代码时,会导致Flash的写保护错误标志WRPERR置位,导致其后面准备写EEPROM的时候,就无法对EEPROM写入了。

客户使用两个标志flag1和flag2,来观察WRPERR标志的变化。代码如图1所示。

1.png

图1.用户测试代码

在执行这个代码时,前面flag1还等于0,执行到flag2那句,就变成flag2等于1了,同样地取了WRPERR标志位的值。所以客户就怀疑执行_HAL_SPI_DISABLE()会把Flash的WRPERR标志置1了。

因为在对EEPROM编程中,需要先调用位于stm32l0xx_hal_flash.c中的FLASH_WaitForLastOperation()函数,此函数中,将会对Flash所有错误标志进行检查,如果出现了错误,它则返回HAL_ERROR,导致后续对EEPROM的编程不会被执行。

2.2 问题重现

使用NUCLEO-L053R8来验证客户的这个问题。在\STM32Cube_FW_L0_V1.10.0\Projects\STM32L052R8-Nucleo\Examples\SPI\SPI_FullDuplex_ComPolling例程中直接进行修改测试。

首先,把客户的测试代码加到例程中SPI初始化之后的位置。如图2所示。

2.png

图2.测试代码1(位于SPI初始化之后)

编译,并在线调试,发现并没有出现客户所描述的问题。如图3所示。

3.png

图3.测试代码1结果(位于SPI初始化之后)

可以看到,WRPERR的值并没有被置1,Flag1和Flag2的值也都是0。那么,为什么客户说他那边会有这个问题呢?

再回头仔细看一下客户的测试代码,发现客户的测试代码中并没有对SPI进行初始化,其_HAL_SPI_DISABLE()代码是放在其他外设初始化之后的。

好,那么再来修改一下测试代码,把客户这三句测试代码挪动到SPI初始化之前,如图4所示。

4.png

图4.测试代码2(位于SPI初始化之前)

编译,并在线调试,这时,会惊奇地发现客户所描述地问题来了。其结果如图5所示。

5.png

图5.测试代码2结果(位于SPI初始化之前)

可以看到,这时Flash的WRPERR标志位置1了,测试代码中,flag2的值也跟flag1不同了。

再做一个实验,将此处的HAL库写法,改成直接操作寄存器,来试一下。测试代码变成是图6这样的。

6.png

图6.测试代码3(位于SPI初始化之前,直接操作寄存器)

编译,在线调试,这次又惊喜地发现,问题不见了。结果如图7所示。

7.png

图7.测试代码3结果(位于SPI初始化之前,直接操作寄存器)

三种操作,为什么只有第二种方式有问题呢?而且为什么错的偏偏是Flash的写保护错误标志WRPERR呢?接下来可以分析一下它们的反汇编代码,看看到底是哪里出问题了。

2.3 反汇编分析

对于三种情况,把反汇编拉出来看最清楚其操作过程了。

先分析第一种情况——测试代码位于SPI初始化之后。其反汇编如图8所示。

8.png

图8.测试代码1的反汇编(位于SPI初始化之后)

从之前的Watch窗口,知道flag1的地址为 0x2000000c,flag2的地址为0x2000000d。

现在对三句C语言测试语句的反汇编语句进行解析,如下:

9.png

10.png

可以看到,这段汇编是一点问题都没有的。

接下来,先分析第三种情况——也就是测试代码放在SPI初始化之前,但是使用直接操作寄存器的方式。其反汇编如图9所示。

11.png

图9.测试代码3的反汇编(位于SPI初始化之前,直接操作寄存器)

从之前的Watch窗口,知道flag1的地址为0x2000000c,flag2的地址为0x2000000d。

现在对三句C语言测试语句的反汇编语句进行解析,如下:

12.png

13.png

可以看到,这段汇编也是一点问题都没有的。

最后,再来分析一下有问题的第二种情况,也就是测试代码放在SPI初始化之前,但是使用_HAL_SPI_DISABLE()关闭SPI的情况。其反汇编如图10所示。

14.png

图10.测试代码2的反汇编(位于SPI初始化之前)

从之前的Watch窗口,知道flag1的地址为0x20000008,flag2的地址为0x20000009。

现在对三句C语言测试语句的反汇编语句进行解析,如下:

15.png

16.png

可以看到,问题出在哪了?问题就出在“STR R3,[R 2]”这个语句上,这个语句在0x00000000这个位置写值,而0x00000000此时映射的是Flash的地址0x08000000,也就是Stack Pointer的位置。如图11和图12所示。

17.png

图11.0x00000000地址的数据

18.png

图12.0x08000000地址的数据

首先,这个位置本来就不应该被修改。

第二,因为没有对Flash程序存储器进行解锁,就往里边写值,就会造成写保护错误,导致WRPERR标志位置位。所以,可以明白为什么WRPERR会被置位了。

可是关键的问题在哪儿呢?在执行“LDR  R2,[R0,#4]”这条语句时,R2本来应该是SPI2_CR1的地址,但是它竟然是0x00000000!如图13所示。

19.png

图13.0x2000000c地址的数据

从Watch窗口来看一下SpiHandle的情况。如图14所示。

20.png

图14.SpiHandle(未初始化)

从图14可以看到,其实刚才的0x2000000c地址就是SpiHandle结构体的地址,也是SpiHandle.Instance的地址,而SpiHandle.Instance的值为0。SpiHandle.Ins tance.CR1的地址为0x0,导致显示它装载的值是Stack pointer的值0x20000468,这里本应该是SPI2_CR1的地址和SPI2_CR1的值。

也就是因为这里的问题,才会导致了后面的WRPERR错误。

2.4 代码分析

再回到代码这边来看一下,有问题的代码究竟是有什么情况。客户的代码主要就是一句关闭SPI的语句“_HAL_SPI_DISABLE(&SpiHandle);”。

这个语句是怎么解析的?它再stm32l0xx_hal_spi.h中解析,如图15所示。

21.png

图15._HAL_SPI_DISABLE函数

看到这个函数时,看到了重要的字眼——“Instance”!就明白是什么问题了,因为这个SpiHandle.Instance还没有被初始化呢!这也说明了为什么在图14中,看到的SpiHandle.Instance的值为0x0,而SpiHandle.Instance. CR2的值为0x20000468。关键就在于这个SpiHandle. Instance还没有初始化。

所以,把客户的测试代码放在SPI初始化代码之后没有问题,就是因为这个SpiHandle.Instance已经被初始化过了。所以,它不会有问题。

03、问题解决

本来客户的代码就没有必要这么写,因为SPI都没初始化,对它进行关闭并没有什么意义。

如果非要在这里关闭SPI的话,那就要先对SpiHandle.Instance进行初始化才行。如图16所示。

22.png

图16._HAL_SPI_DISABLE函数

加了“SpiHandle.Instance=SPIx;”初始化后,再跑这段代码,就不会出现客户所说的问题了。

现在再来看一下SpiHandle的情况。

23.png

图17.SpiHandle(SpiHandle.Instance已初始化)

经过对SpiHandle.Instance的初始化,这里就可以看到SpiHandle.Instance的值为0x40003800了,为SPI2外设寄存器的基地址,而且可以看到SpiHandle.Instance. CR1的地址就是SPI2_CR1的地址0x40003800,值也是SPI2_CR1的值0x0了。

04、小结

在用户代码中,SpiHandle只是定义了SPI_HandleTypeDef结构体,其各种参数并还没有进行实际初始化。在没有初始化的前提下,对其进行操作时不对的,也是危险的,应该在写代码的时候引起重视。

使用HAL库的时候,如果要对一个外设进行任何的操作,请务必记得它是被初始化过的。否则,出了问题可能都不一定知道。

来源:STM32单片机

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 36

1. 引言

随着市场对更高图像质量的需求不断增加,成像技术持续发展,各种新兴技术(例如3D、计算、运动和红外线)的不断涌现。如今的成像应用对高质量、易用性、能耗效率、高集成度、快速上市和成本效益提出了全面要求。为了满足这些要求,STM32 MCU 内置的数字照相机接口(DCMI),能够高效连接并行照相机模块。

对于使用STM32 DCMI 开发相机应用的客户,经常有以下问题:STM32 DCMI 最大支持的像素时钟是多少?STM32F4/F7/H7/U5 能支持1280×720 的相机分辨率吗?最大的帧率是多少?如何判断所设计的应用产生的带宽是否能充足?相机输出是选择8 位、10位、12 位、还是14 位?

针对这些问题,本文档从DCMI 使用的几个方面,介绍了STM32 DCMI 在连续抓取模式下带宽的估算,以及提升性能需要注意的事项。客户在设计相机应用时可以参考。2. STM32 DCMI

STM32 数字照相机接口(DCMI)采用同步并行数据总线。它可以轻松集成并适应相机的特殊应用要求。DCMI 可连接8、10、12 和14 位CMOS 照相机模块,并支持多种数据格式:8/10/12/14 位逐行视频、YCbCr4:2:2 逐行视频、RGB565 逐行视频、JPEG 等。像素最大支持16 位色深。

2.1. STM32 智能架构中的DCMI

DCMI 应用需要用帧缓冲区来存储采集的图像。必须根据图像大小和传输速度使用合适的目标存储区。在某些应用中,必须连接外部存储器(SDRAM),以便提供较大的数据存储空间。对于支持DMA2D(Chrom-ART Accelerator™控制器)的STM32 系列,也可以用它做色彩空间转换(例如RGB565 至ARGB8888),或使用DMA 从一个存储区到另一个存储区的数据转移。

下面图1 是STM32F2x7 系列智能架构中DCMI 的例子。这里DCMI 通过AHB2 外设总线连接到AHB 总线矩阵。DMA2 主控访问DCMI,将DCMI 接收到的图像数据传输到内部RAM 或外部SDRAM 中,具体目标位置取决于应用。

1.png

图1. STM32F2x7系列智能架构中的DCMI从设备AHB2外设

2.2. DCMI 最大像素时钟频率

STM32 DCMI支持的像素时钟频率,与AHB时钟频率比值必须小于0.4。具体的像素时钟频率最大值要查询所用STM32的数据手册。下面表1中列出了部分STM32系列DCMI最大像素时钟频率及相关可用资源的信息。如需更详细信息,请参考相应的参考手册/数据手册。

2.png
表1. DCMI及相关可用资源

2.3. DCMI 支持的图像分辨率

STM32 DCMI仅对输入像素时钟频率有硬件限制(DCMI_PCLK / fHCLK 最大0.4),对图像的分辨率没有限制。DCMI连续抓取模式下,图像分辨率会影响帧率(帧率的大小会影响视频的流畅度)。在固定的像素时钟频率下,高分辨率图像的带宽需求较高,对应的帧率则会下降。或者说,在相同的图像分辨率下,提高帧率需要相应地提高像素时钟频率。例如下表2(摘自三星S5K5CAGA CMOS Image Sensor的数据手册)所示,大家可以从中了解S5K5CAGA的像素频率、图像分辨率、帧率的关系(非RGB888,16位色深)。另外,图像分辨率主要通过设置相机的输出格式进行修改。

3.png

表2. S5K5CAGA YUV/RGB565像素时钟频率与帧率

对于中高分辨率的图像,一般采用双缓冲区或多缓冲区模式。这个主要原因是因为DCMI使用的DMA计数寄存器SxNDTR使用了16位用于计数。最大0xFFFF,即 65535 ,单位为32位Word,当图像分辨率超过65535 Words(262140字节)时,则要使用双缓冲区或多缓冲区模式。双缓冲区地址由DMA_SxM0AR/DMA_SxM1AR设定。多缓冲区时,则需要动态交替DMA_SxM0AR/DMA_SxM1AR,使之指向图像缓冲区的不同存储位置,相当于分块存储。

2.4. DCMI 带宽与性能

使用DCMI的相机应用,使用连续抓取模式,功能往往是由相机连续输出所摄图像数据流到STM32,STM32 DCMI捕获视频流后,再输出到屏幕显示(如监控)或做图像数据处理、传输等。如果相机输出的是高像素高色深高帧率的视频流,DCMI在接收过程中,如不能及时处理,DCMI FIFO即会产生溢出错误(Overrun),进而导致图像数据丢失,帧率下降等问题。

2.4.1. DCMI 带宽与性能

DCMI带宽计算公式为:带宽 = 分辨率 * 色深 * 帧率。

以三星S5K5CAGA为例,如表2中第1行数据(这里相机采用RGB565,16位/像素,8位输出格式),则QXGA输出的带宽需求 =(2048 * 1536)* 2 * 6 ≈ 38MBps。像素时钟为40MHz,8位输出,每2个CLK传输1个像素数据,对应的最大输出能力为40 MBps。则QXGA在40MHz的像素时钟频率下是可以以6帧/秒的帧率输入到DCMI的。DCMI捕获图像数据流,再由DMA传输到图像缓冲区,该例中,图像缓冲区(帧缓冲区)的大小为:2048 * 1546 * 2 ≈ 6.3 MByte。

高像素高色深的图像,对应的图像缓冲区较大。当MCU内置的SRAM不能满足DCMI图像缓冲区需求时,则需要用外部SDRAM来存储。例如STM32F469 MCU(见表1,第6行数据),其FSMC支持的最大频率为90MHz,宽度32位,则SDRAM的带宽 = 90 * 4 = 360 MBps,能够满足DCMI带宽的需求。一般,DCMI图像缓冲区中的数据是需要再次传输或由CPU进行计算处理的,理论上DCMI输入的带宽需求最大不应超过SDRAM的带宽的50%。这里需要注意SDRAM可能存在多个主控(如CPU、DMA、LTDC等)的访问,如遇到SDRAM性能瓶颈问题,可考虑下列方面进行优化:

(1)将各主控设备访问的存储器尽量分开,以减少竞争访问;

(2)将CPU访问的SDRAM Bank 与DCMI图像缓冲区的Bank分开;

(3)将DCMI图像缓冲区区域设为不可缓冲,CPU 访问的区域则可以设为可缓冲。

对于性能,另外一个重要因素是总线竞争问题。DCMI DMA申请的AHB总线访问(即使在使用FIFO的情况下)并非长Burst的访问。如果AHB总线上存在其它长Burst访问(最大1KByte),会造成DMA延迟访问DCMI,令其不能及时将DCMI FIFO中的数据传输出去。可以认定:DCMI需要传输数据时的总线繁忙是造成 其FIFO 溢出错误的根源。解决办法除了直接为设备分配不同SDRAM之外(将长Burst访问放在其他SDRAM),还可以考虑在内部SRAM增设DCMI LineBuffer,化零为整,巧妙避开AHB 长Burst 访问造成的DCMI延迟问题。数据流如下:

(1)DCMI(经DMA)=> 内部SRAM(LineBuffer) ;

(2)内部SRAM(LineBuffer)=> 外部SDRAM(图像Buffer)。

由LineBuffer 到SDRAM的数据中转传输请求,可使用DCMI IT_LINE 中断(行结束)触发。这里MCU如果是STM32F7/H7系列,还可使用MDMA 充分发挥AXI总线的优势,但要注意LineBuffer 最好是8字节的倍数(64位总线)。

2.4.2. DCMI 图像大小调整功能

当考虑了上面的措施,仍无法满足应用对高分辨率需求时,用户可以通过设置相机,修改相机输出分辨率,配合DCMI调整图像大小功能,找到合适的折中方案。DCMI提供的相关功能如下:

(1)窗口裁剪:

使用寄存器DCMI_CWSTRT指定起始坐标;

使用寄存器DCMI_CWSIZE指定窗口大小。

(2)图像数据调整(详见寄存器DCMI_CS中LSM/BSM等位域):

- 行选择:可选择2选1,行数减半;

- 数据选择:字节流上可进行2选1、4选1已经4选2 (注意:对于RGB565格式, 只能4选2可选,2选1及4选1会造成色彩数据错乱)。

2.5. DCMI 10/12/14数据线输入

DCMI 支持最多14条数据线(D13 - D0),如果将DCMI配置为接收10、12或14位数据,DCMI将用2个像素时钟周期捕获一个32位数据。以12位数据宽度为例,DCMI在第1个像素时钟捕获12位LSB(忽略D[13 :12]),存于DCMI_DR寄存器低16位字中低12位,高4位(D[15 :12)清零;第2像素时钟捕获的12位LSB则存于DCMI_DR高16位字的低12位,高4位(DCMI_DR的[31 : 28])清零。另外相机也必须配置为10/12/14位输出。具体情况则由应用决定。

3.小结

本文通过介绍STM32 DCMI支持的最大像素时钟频率,支持的图像分辨率及与帧率的关系,进而引出DCMI带宽与性能提升的注意事项。另外附带了DCMI图像大小的调整及10~14数据线的简介,为用户遇到相关问题时提供思路参考。

来源:STM32单片机

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 130

1. 引言

STM32 G0 系列产品具有丰富的外设和强大的处理性能以及良好的低功耗特性,被广泛用于各类工业产品中,包括一些需要低功耗需求的应用。

2. 问题描述

用户使用STM32G0B1 作为汽车多媒体音响控制器的控制芯片,用来作为收音机频道存贮和各种检测控制。在实验室条件下模拟汽车频繁打火的情形进行测试,连续工作72 小时实验中,进入STOP 模式后,会出现无法再继续运行的情况(屏幕没有显示输出,外部中断无反应)。

3. 问题重现

通常调查问题时采取调试监控的方式。但是用户产品是在检测外部掉电时,测外部电压(汽车ACC 电源,轿车12V)下降后,立刻进入低功耗模式,然后通过RTC 和外部中断(PC13 下降沿触发即汽车打火上电)唤醒MCU 继续工作。

那么既然是已经进入低功耗模式,并且在几十个小时内才会出现故障,通常的用ST-LINK 在线调试方式显然很困难重现问题,即使幸运的遇到了故障,也很容易错过引起故障的代码部分,看到了现象却无法定位。

在此种情况下,正面分析出问题的可能性极小,况且用户代码量超过200k。这时候采用排除法不失为一种可行的办法。通过增加测试样本数量,进行并行测试提高定位效率。

图1 是为了方便说明问题,模拟用户关键程序。主要是进入STOP 前后外设的处理,来复现故障现象。

1.png

图1 模拟ACC掉电唤醒程序

在经过一段时间的实验,并从增加和减少该段代码的排除中,最后验证并定位到下面的代码引起故障发生。

2.png

图2 定位到引起的故障代码

反复分析我们可以看到,在进入STOP前,用户需要停止ADC和DMA。但是在停止DMA时,用户程序直接停掉DMA的时钟。从函数名称上看,是从其他软件直接搬过来,并且误以为是DMA的默认初始化动作。

3.png

图3 DMA正确的停止方式

查询参考手册,停止循环模式的DMA应该从外设停止开始,而不是简单粗暴的停止DMA时钟。而且,在程序顺序上客户是先停止了DMA的时钟然后才去停止ADC的DMA请求。显然,当DMA开始工作时,突然停止时钟会使DMA和总线处于一个不确定阶段状态,因此才有极低概率发生唤醒故障。

到此已经找到了发生的原因,按说应该找到了前因后果。但奇怪的是无意中发现振荡器的波形比较奇怪,并不符合低功耗模式。

4.png

图 4 外部振荡器HSE 波形

在发生故障状态时发现外部震荡器还在持续震荡,因此判定此时并非进入低功耗模式。利用IAR编译器以HOT PLUG的方式连接调试与观测。

通过调试界面可以看到,代码会不停的进入DMA中断。

5.png

图5 故障模式下的调试

6.png

图6 代码进入循环过程


奇怪的是每次并没有看到DMA的寄存器内容,原因是已经关闭了DMA外设的时钟。所以无法看到任何状态标志。退出中断时在C语言下就无法单步调试了。切换到汇编界面下,可以看到代码可以继续运行到系统时钟配置函数,但是在配置函数中的除法部分进入了循环,然后又发生了DMA中断,并且循环没有出来。 

显然,正常的调试手段已显示出逻辑的不正常。

4.小结

至此,情况已经明了。由于软件在进入低功耗前试图关闭ADC加DMA工作,没有按照手册的规范,通过外设停止的方式关闭,而是简单粗暴的关闭DMA时钟,导致总线和运行逻辑出错,无法继续执行。

外部看起来像是进入低功耗模式后,外部中断触发没有执行,芯片没有唤醒,实际上是DMA进入了不正常的循环中断方式导致了系统卡在循环代码下。

芯片的外设功能强大,每种外设运行的方式也不相同,因此停止外设时需根据外设特点以及参考手册的建议来实施,切不可按自己想象的方式执行,这样引起隐蔽的偶发故障就很难去定位解决了。

此外ST已经建立好完整强大的生态系统,按照cube 软件库的规范编写调用驱动函数可以避免少走类似的弯路。

来源:STM32单片机

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 58

意法半导体STM32 微控制器 (MCU)软件生态系统 STM32Cube新增一个USB Type-C® 连接器系统接口(UCSI)软件库,加快USB-C供电(PD)应用的开发。

1.jpg

X-CUBE-UCSI是一款UCSI 认证的总包整体方案,组件包含即用型硬件和使用STM32 MCU充当UCSI PD控制器实现标准化通信的固件示例。客户可以直接复制粘贴这些参考设计,并从优化的物料清单(BoM)成本中受益。

该软件允许 MCU 连接系统主处理器,使用 UCSI 协议与操作系统交换信息,同时控制 USB-C 连接和 PD 协议。主处理器可以是系统芯片(SoC)、应用处理器或 STM32MP微处理器,主处理器的职责就是UCSI 操作系统策略管理器(OPM)。STM32 MCU上的 PD 控制器充当 UCSI平台策略管理器 (PPM)。STM32 MCU中有很多产品都提供USB Type-C供电(UCPD)所需外设。STM32G0系列是售价较低的USB Type-C供电微控制器,是MPU理想的低引脚数量的配套芯片,专门负责处理PD供电功能。

该软件还允许在生产线以及应用生命周期中用主处理器在STM32 MCU上烧写固件。主处理器使用微软或 Linux社区提供的UCSI驱动程序以及相关命令与 PD 控制器交换数据。除了节省开发时间外,该软件还扩展了 USB-C 设备之间的互操作性,支持该技术提供的最新用例。

X-CUBE-UCSI STM32Cube 扩展软件可帮助开发人员开发USB PD 双角色电源 (DRP) 应用,支持交替模式命令。

在USB认证(TID 8088) Discovery 板 STM32MP135F-DK上,应用主处理器STM32MP135连接UCSI PD 控制器 STM32G071 MCU,让开发者能够先人一步,快速启动开发流程。这块板子还使用了意法半导体的 TCPP03-M20 USB Type-C 高压端口保护 IC。

现在有500多款标准 STM32 MCU在片上实现了 ST UCPD 供电控制外设。此外,STM32 MCU 丰富的模拟数字外设作为端口扩展器,为实现主处理器不支持的附加功能提供了更高的灵活性。

想了解基于意法半导体MCU的USB Type-C 供电解决方案,请访问www.st.com/en/embedded-software/x-cube-ucsi.html

欢迎访问 STM32 开发者专区,一站式购齐全部工具和资源:

关于意法半导体(ST

意法半导体拥有5万名半导体技术的创造者和创新者,掌握半导体供应链和先进的制造设备。作为一家半导体垂直整合制造商(IDM),意法半导体与二十多万家客户、数千名合作伙伴一起研发产品和解决方案,共同构建生态系统,帮助他们更好地应对各种挑战和新机遇,满足世界对可持续发展的更高需求。意法半导体的技术让人们的出行更智能,电源和能源管理更高效,物联网和互联技术应用更广泛。意法半导体承诺将于2027年实现碳中和。详情请浏览意法半导体公司网站:www.st.com

围观 66

2023年7月11日,慕尼黑上海电子展盛大开幕。STM32携物联网&智能互联等领域的世界级领先产品和智能解决方案精彩亮相,各种前沿技术和应用演示令ST展位人气爆棚。

1.png

2.png

3.jpg

STM32:以边缘AI解决方案引领嵌入式AI新时代

2023年7月12日,ST微控制器市场部门市场经理丁晓磊在本次慕尼黑上海电子展的国际嵌入式系统创新论坛发表演讲,介绍ST在边缘人工智能领域的相关产品和技术,并分享ST边缘人工智能工具,实际应用案例以及生态系统等重点内容,让更多人了解了ST如何帮助客户使用我们的边缘人工智能产品和解决方案最终实现项目落地。

嵌入式人工智能将成为主流

随着企业的业务部署场景和数据产生正在向端侧、边缘侧“迁移”,嵌入式AI也迎来了快速发展的机遇期。

在边缘侧设备中运行AI有很多优势:设备响应速度快、超低延时;降低数据传输量;更有效地保护隐私、增强信息安全;降低边缘侧设备的运行功耗;还可以降低推理成本以实现其他新的功能操作。因此,边缘AI 可以为很多领域提供价值,比如:工业预测性维护,从家电到工业机器的控制系统,以及物联网 (IoT)应用,如智慧城市, 智慧楼宇, 智慧家庭和工业自动化等。

STM32 边缘AI解决方案加快嵌入式AI部署

作为该趋势的主要推动者,ST已经在AI方面投入大量资源,旨在帮助开发人员在基于微控制器/微处理器(STM32系列)和传感器(MEMS、ToF…)的嵌入式系统上快速部署AI应用。

ST提供了一整套工具、设计支持和服务,包括软件工具、模型库、 软件参考,硬件芯片,开发板等,在STM32 MCU、MPU和智能传感器上实现边缘AI,通过简单、快速、低成本的方式为许多解决方案带来智能化,例如:预测性维护、物联网产品、智能楼宇、资产跟踪、人数统计等等。

通过嵌入式AI,轻松增强应用,开启全新应用可能性,解锁AI应用普惠之道。ST在帮助客户使用我们的边缘人工智能产品和解决方案最终实现项目落地方面,已取得了丰富的应用案例,涵盖智慧城市、智能家居、娱乐、玩具、智能楼宇、交通运输、智能办公、工业、家电等各个领域。

4.png

▲ 图:STM32在电弧检测中的应用

STM32 Cube.AI:一个工具,两个版本,轻松将AI部署到STM32

STM32Cube.AI 软件工具,是ST提供的嵌入式AI工具,支持全系列STM32芯片,致力于在STM32实现优异的AI性能,可在 STM32硬件上实现更加便捷的评估、转换和部署机器学习或深度神经网络。该工具集成在STM32Cube MCU开发环境中,可以优化和调整模型,直接部署在目标板上。

STM32Cube.AI工具的两个版本包括:STM32Cube.AI和STM32Cube.AI开发者云。

5.png

STM32Cube.AI是STM32嵌入式AI工具的PC版本,可帮助优化STM32项目中经过训练的AI模型的性能和内存占用。

STM32Cube.AI开发者云平台是STM32最新的线上 AI 服务器,可直接评估模型的在板推理时间。它可用来创建、优化和生成适用于STM32微控制器的人工智能,以及进行基准测试。无需安装任何软件,也无需评估板。

NanoEdge AI Studio软件工具是ST为无AI专业知识的嵌入式开发者提供等一体化机器学习方案,助用户从头开始做自己的AI解决方案。ST重写了从代数、机器学习和信号处理的各种算法,并且使这些算法能够在MCU内学习和推理。

ST为嵌入式AI准备了一站式网站资源: https://stm32ai.st.com/zh,客户可随时登陆获取相关信息。

STM32 DEMO 展示精选
在本次慕尼黑电子展上,ST展示了两个重磅边缘AI技术方案:边缘人工智能洗衣机DEMO:该Demo演示了AI如何通过提供更准确的衣服重量测量, 帮助经典的电机控制设备达到更高的节能与节水等级。由NanoEdge AI Studio 生成的AI模型通过对电流信号进行特征分析与学习,使测量精度相对传统算法得到大幅提升。

6.jpg


STM32最新一代高性能MPU ——STM32MP257。STM32MP2是ST新推出的第二代64位工业4.0级边缘AI MPU,通过SESIP 3级认证,配备工业应用接口和专用边缘 AI加速单元。该产品在继承了STM32生态系统基础上,采用了全新的处理器架构,提升了工业和物联网边缘应用的性能和安全性。

7.jpg


STM32展台还展出了更多丰富的产品技术和解决方案Demo,涵盖图形界面、无线连接、安全类应用以及基于STM32的各类开发板演示。

图形界面类Demo包括:基于STM32U599驱动大圆屏的集合DEMO,Qt图形界面演示 -基于Qt+openST Linux的图形方案,基于LVGL+ 裸机程序图形方案的LVGL图形界面演示,基于OpenST Linux + LVGL的图形界面演示。

STM32WBA无线连接 Demo: 演示了STM32WBA 灵活的主从一体和强大的多连接功能,在低功耗蓝牙常规点对点通信功能上,扩展实现低延时和低功耗的星状网络通信,满足客户低功耗蓝牙更广的网络覆盖需求。

安全类应用Demo:STMH573I-DK板TrustZone隔离保护和OTFDEC性能演示

板卡类Demo包括:STM32C031系列NUCLEO板,STM32C031系列Discovery板,STM32C011系列Discovery板。

8.png

9.png

10.jpg

11.jpg

12.jpg

13.jpg

来源:STM32

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 176

STM32嵌入式面试知识点总结

cathy的头像

一、STM32F1和F4的区别?

解答:

参看:STM32开发 – STM32初识

内核不同:F1是Cortex-M3内核,F4是Cortex-M4内核;

主频不同:F1主频72MHz,F4主频168MHz;

浮点运算:F1无浮点运算单位,F4有;

功能性能:F4外设比F1丰富且功能更强大,比如GPIO翻转速率、上下拉电阻配置、ADC精度等;

内存大小:F1内部SRAM最大64K,F4有192K(112+64+16)。

二、介绍以下STM32启动过程?

解答:

页面

订阅 RSS - STM32