一板网电子技术论坛

天南地北客
发表于: 2017-1-3 16:41:53 | 显示全部楼层

stm32-nucleo.jpg

AVR到ARM

我初次了解微控制器是通过Arduino平台。但很快开始深入学习,并且进入到(8位)AVR编程。过去我特别着迷的tinyAVR线,现在仍然觉得它和微型电脑一样,足以满足我的需求。我越来越多的听到有关32位ARM Cortex-M处理器的信息,但是被这些芯片编程的复杂性所吓倒。当我开始使用Nordic nRF51 / 52(BLE)和TI CC3200(WiFi)等连接设备时,我开始接触到了SoC - 片上系统的概念,其中的无线设备配有处理器 - 通常是ARM Cortex- M。然后接触到了Arduino Zero(类似Neutrino兼容的板子),采用了Atmel SAMD21 ARM Cortex-M0 +芯片。所以我开始熟悉ARM,但我使用的库和工具的各个层对我隐藏了ARM架构。

在我看来,与(8位)AVR相比,ARM微控制器的一个明显的优势是更强大的功能 - 更快的处理器速度、更多的外设如ADC和GPIO、USB、RTOS(实时操作系统)等等。令人惊讶的是成本因素。 32位ARM处理器实际上比8位AVR更便宜!所以,如果你正在开发一个产品,可以考虑。了解这些处理器已成为一种趋势。


选择一款ARM芯片

编程AVR就像在公园里散步。只需下载avrdude + avr-gcc,以及一个便宜的USB烧写器,就可以搞定了。相比之下,开发ARM就像在漫漫的战场中漫步。首先,您需要选择一个ARM芯片内核 - Cortex-M0、Cortex-M3等。然后,您需要选择一个供应商 - Atmel、ST、NXP、Microchip等,并在他们提供的各种产品中确定你最后的选择。接下来是为您的芯片选择一个开发板 - 可以是集成一个仿真器(例如J-LINK OB、ST-Link)或单独的开发板和通用仿真器(例如J-Link)。 (仿真器可以帮助您调试芯片中运行的代码,并将其烧写到闪存)。然后,最有趣的是为您的芯片选择开发工具。 “专业”的ARM程序工具价格昂贵 - 大约几千美元(供应商还提供昂贵的Pro工具的无代码大小限制的版本。)幸运的是,开源来到再次救援,可以使用ARM GCC、OpenOCD和Eclipse的。关于这个主题,可以参考以下链接:If you had to start over today with STM32... which toolchain? GCC? Keil?

一旦你决定了上面的所有内容,你仍然必须选择如何构建你的代码 - 使用“裸机”(只是寄存器+ C)、供应商的HAL或中间件、CMSIS,或者可能“完全裸机编程“,使用汇编语言编写代码。

我自己选择ARM Cortex-M3芯片的经验如下:浏览互联网论坛中有关Atmel、恩智浦、ST、Microchip或其他ARM之间对比的帖子。 几天后,我相信一件事 - 我们人类是一个很难满足的个体,不会在任何事情上达成一致。所以我根据经济学做出了选择--ST有最低的ARM芯片价格。

所以最后,我决定使用STMicroelectronics的STM32F103 ARM Cortex-M3芯片开始我的ARM旅程。


开始使用STM32

当开始ARM编程时,我觉得最好是使用供应商的官方开发板,而不是用第三方提供的开发板,主要是因为:

●     官方的开发板价格低廉。

●     文档丰富,工作正常的参考设计。

●     配有硬件调试器。

●     容易原型设计。

由于不需要对11美元板子进行过多的考虑,我购买了带有STM32F103RB芯片的STMicroelectronics NUCLEO-F103RB板。


在本文中,我将使用该开发板构建一个小项目。 我们的目标是:

●     设置开发环境。

●     了解如何调试和上传代码。

●     使LED闪烁。

●     了解如何使用USART外设。


首先要做的是建立一个开发环境。 正如我提到的,我决定使用GCC,但即使是GCC,也有几种选择,包括支持的付费选项。 我选择了ARM GCC工具链Eclipse IDE和OpenOCD进行调试。 我发现使用这些工具的最简单的方法是通过由Liviu Ionescu开发的ARM GCC的Eclipse扩展

关于安装,请按照以下Liviu的优秀文档:

http://gnuarmeclipse.github.io/install/

确保您按照给定顺序中的步骤。 引用作者:

“初学者注意:如果是第一次执行,建议按照书中的步骤,避免poetic 许可,因为它们可能会导致棘手的情况和微妙的功能问题。


完成安装后,在Eclipse中通过选择File-> New-> C Project启动一个新项目,显示以下对话框:

stm32-init1.png

选择合适的芯片,然后就会弹出以下对话框:

stm32-init2.png

在content中,您可以选择空。 在对话框的最后,你将得到一个类似于下面的目录结构:

stm32-list.jpg

在上面的目录树中,我删除了项目提供的_write.c文件,我也有上面的Debug / Release,因为我已经构建了可执行文件。

上面的stm32f1-stdperiph目录是标准外设库,它是STMicroelectronics提供的一个代码层,它允许您使用GPIO,ADS,USART等芯片外设,而无需直接设置寄存器。

需要注意的是,许多未使用的代码在项目设置中被过滤掉,可以在这里找到:

stm32-src-filter.png

一旦你开始使用这些文件(例如stm32f10x_usart.c),你需要从上面的排除过滤器中删除。

接下来,您需要设置OpenOCD进行调试。 这已经包含在安装列表中。 但是我发现有一件事没有做,使用OpenOCD将代码写入芯片的闪存。 可以很容易地设置:Run->External Tools->External Tools Configuration

stm32-ext-tools.png


现在差不错可以开始写代码了。 但在此之前,你需要读一些文档,这里是名单:

●     STMicroelectronics的STM32F103x数据表

●     STMicroelectronics的STM32F103x参考手册

●     UM1724 STMicroelectronics的STM32 Nucleo-64板的用户手册

●     AN2586应用笔记 - STM32F10xxx硬件开发入门


在进入我们的程序之前,让我们简单看看编程STM32的几种方法(不全面):

●     使用Registers + C代码

●     使用标准外设库

●     使用CMSIS

●     使用STM32Cube + HAL

●     使用上面的一些和自己写的“中间件”


以下代码将引脚PA5设置为输出,这样我们可以在Nucleo开发板上闪烁LED(USR LD2)。

  1. // enable clock for GPIOA and GPIOC
  2. RCC->APB2ENR |= (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN);

  3. // set up PA5 as output
  4. // clear bits Mode5[1:0] and CNF5[1:0]
  5. uint32_t bitmask = GPIO_CRL_MODE5 | GPIO_CRL_CNF5;
  6. uint32_t tmpReg = GPIOA->CRL;
  7. tmpReg &= ~bitmask;
  8. // set CNF5[1:0] and Mode5[1:0]
  9. // CNF5[1:0]  -> 00: General purpose output push-pull
  10. // MODE5[1:0] -> 10: Output mode, max speed 2 MHz.
  11. tmpReg |= (GPIO_CRL_MODE5_1);
  12. // set values to GPIOA_CRL
  13. GPIOA->CRL = tmpReg;
复制代码

上面,我们首先启用GPIOA的外设时钟,然后继续设置相关的寄存器(见数据手册)以将PA5设置为输出。

可以说,上面的代码不够“裸机编程”。 RCC-> APB2ENR的定义来自stm32f10x.h文件。 你可以跳过这些头文件,直接使用数据表中给出室温寄存器地址进行编程。


现在让我们使用标准外设库来编程:

  1. // enable clock for peripheral
  2. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

  3. // initialize GPIO structure
  4. GPIO_InitTypeDef gpioInitStruct;
  5. GPIO_StructInit(&gpioInitStruct);
  6. gpioInitStruct.GPIO_Pin = GPIO_Pin_5;
  7. gpioInitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  8. gpioInitStruct.GPIO_Speed = GPIO_Speed_2MHz;
  9. GPIO_Init(GPIOA, &gpioInitStruct);
复制代码

正如你所看到的,代码比上一版更容易阅读。 另一方面,这个代码很容易从STMicroelectronics移植到其他芯片。 但缺点是,通用的代码,涵盖了很多的东西,可能不适用于你的具体使用。 看看在stm32f10x_gpio.c中的GPIO_Init实现,并将其与上面的“裸机代码”进行比较。


使用NUCLEO-F103RB进行外部编程

正如我上面提到的,使用官方开发板的一个优点是其内置硬件调试器。 该硬件在大多数情况下可用于编程外部设备。 NUCLEO-F103RB有一个SWD接口可用于外部编程。

stm32-nucleo-ext.png

上图摘自Nucleo用户手册,它显示了如何去除CN2跳线,并使用CN4 SWD端口编程外部目标。

我从ebay买了一个便宜的STM32F103C8T6板来进行测试。

stm32-nucleo-bo.jpg

工作正常! 需要连接Nucleo板上的CN4上的管脚1至5。 没有什么特别的事情要做 - 一旦连接,调试和程序将自动转到外部目标。 我写了一个简单的闪烁程序进行测试,对于这个板子,LED连接到PC13上。


原英文链接Getting Started with STM32 ARM Cortex-M3 using GCC (STM32F103, NUCLEO-F103RB)

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 26 | 回复: 45



手机版|

GMT+8, 2020-6-6 10:34 , Processed in 0.062500 second(s), 32 queries . Powered by Discuz! X3.4

YiBoard一板网 © 2015-2018 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表