este em profundidade artigo você vai aprender como desenvolver firmware incorporado para STM32 Cortex-M 32-bits microcontroladores utilizando as várias ferramentas de desenvolvimento.
a série STM32 é alguns dos microcontroladores mais populares utilizados numa grande variedade de produtos. Eles também têm uma excelente base de suporte de múltiplos fóruns de desenvolvimento de microcontroladores.esta família de microcontroladores da Stmicroeletronics é baseada no núcleo do processador ARM Cortex-M 32-bit.os microcontroladores STM32 oferecem um grande número de periféricos de comunicações seriais e paralelas que podem ser interligados com todos os tipos de componentes eletrônicos, incluindo sensores, visores, câmeras, motores, etc. Todas as variantes do STM32 vêm com memória Flash interna e memória RAM.
A gama de desempenho disponível com o STM32 é bastante expansivo. Algumas das variantes mais básicas incluem a sub-série STM32F0 e STM32F1 que começam com uma frequência de clock de apenas 24 MHz, e estão disponíveis em pacotes com apenas 16 pinos.
no outro extremo de Desempenho, O STM32H7 opera em até 400 MHz, e está disponível em pacotes com até 240 pinos.os modelos mais avançados estão disponíveis com unidades de vírgula flutuante (FPU) para aplicações com sérios requisitos de processamento numérico. Estes modelos mais avançados desfocam a linha entre um microcontrolador e um microprocessador.finalmente, a sub-série STM32L é projetada especificamente para aplicações portáteis de baixa potência que funcionam a partir de uma pequena bateria.
Ferramentas de desenvolvimento
ferramentas de desenvolvimento são necessárias para desenvolver o código, programar o microcontrolador e testar/depurar o código. O desenvolvimento de ferramentas incluem:
- Compilador
- Depurador
- In-Circuit Serial Programmer (ICSP)
a Programação do STM32 via In-Circuit Serial Programmer (ICSP).
Existem várias ferramentas de desenvolvimento de software disponíveis para o desenvolvimento de código em microcontroladores STM32. As ferramentas de software estão disponíveis como Ambientes de Desenvolvimento Integrado (IDE), que combina todas as ferramentas necessárias em um ambiente integrado.
dois pacotes de desenvolvimento comuns incluem:
- Keil MDK ARM (UVISON5 IDE) – o MDK ARM IDE é um ambiente de desenvolvimento muito estável que pode ser baixado gratuitamente. Ele permite o desenvolvimento de código até um tamanho de programa de 32 KB. Para desenvolver programas maiores, uma versão licenciada precisa ser comprada aqui.
- CoIDE-uma cadeia de ferramentas livre que é baseada em uma versão aparada para baixo do IDE Eclipse integrado junto com uma versão embutida do ARM do compilador GCC livre.
Existem também vários outros IDEs que estão disponíveis para uso com microcontroladores STM32. No entanto, este artigo se concentra no desenvolvimento e flashing de um programa usando o muito popular Keil MDK ARM uVision5 IDE.
além das ferramentas de software, um programador em circuito Serial (ICSP) é necessário para programar e testar o código no microcontrolador real. O ICSP é necessário para interface o microcontrolador para as ferramentas de software PC através de uma porta USB.
os microcontroladores ARM Cortex-M suportam dois protocolos de programação: JTAG (nomeado pela Associação da indústria eletrônica o Grupo Joint Test Action Group) e Serial Wire Debug (SWD).
Existem vários ICSP programadores disponíveis que suportam estes protocolos, incluindo:
- Keil U-Link 2
- Segger J-Link
- ST-Link
a Desenvolver o primeiro aplicativo
É sempre mais fácil começar com uma prontamente disponíveis código basic do quadro. Em seguida, adicione o código que é necessário para a aplicação específica e modelo de microcontrolador.
felizmente, a STMicroelectronics fornece uma ferramenta gráfica muito útil chamada STM32CubeMx que ajuda na criação de um projeto básico de aplicação para qualquer microcontrolador STM32 de sua escolha. Ele também pode ser usado para configurar os periféricos nos pinos multiplexados do microcontrolador.
a ferramenta STM32CubeMX pode ser obtida a partir daqui. O STM32Cube vem com um extenso conjunto de drivers para todos os tipos de periféricos e suporte para um FreeRTOS opcional (um sistema operacional livre em tempo Real) pré-integrado com o código.
a secção seguinte descreve em detalhe como criar uma aplicação UART simples para o microcontrolador STM32F030 que ecoa o que estiver escrito numa janela de terminal.
- Instale o software STM32CubeMX.
- execute a aplicação e seleccione o novo projecto. Ele irá então abrir a janela seletora MCU como mostrado abaixo.
- duplo-click para seleccionar o modelo de microcontrolador a ser utilizado. Neste caso estamos a usar o STM32F030K6. Ele então leva você para a página de pinout para o microcontrolador selecionado.
The STM32F030K6 is an ARM Cortex-M0 core with 32KB of Flash memory and 4KB of RAM memory. O código de exemplo permite ao UART que usa os pinos PA9 e PA10 para receber e transmitir dados seriais como mostrado abaixo com os Pinos Verdes.
Configure a configuração do UART sob a Página de configuração e escolha a configuração do UART como mostrado abaixo. Active a opção nvic global interrupt sob a página de configuração NVIC.
seguinte, navegue para o Project–configuração, a fim de adicionar o novo nome do projecto e seleccionar o IDE da cadeia de ferramentas a usar. Para este exemplo, defina o nome do projeto como ‘UARTEcho’ e selecione o IDE Keil-MDK5 para o desenvolvimento do projeto.
finalmente, gerar o código do projecto clicando em Project – Gerar Código.
construir e mostrar o código
Agora abra o ficheiro de projecto MDK-ARM gerado UARTEcho\MDK-ARM\UartEcho.rebuliço.
Este programa até agora apenas inicializa o periférico UART e pára em um loop infinito.
é importante notar que o STM32Cube gera /* o código do usuário inicia x */ e /* o código do usuário termina x */ blocos de comentários para implementar o código específico do Usuário. O código do Usuário deve ser escrito dentro destes blocos de comentários. Sempre que o código é re-gerado com configurações modificadas, a ferramenta STMCube retém o código do usuário dentro destes blocos de comentários do Usuário.
em seguida, defina uma variável global para receber um byte do UART na principal.c ficheiro de código:
/* USER CODE BEGIN PV *//* Private variables ———————————————————*/static uint8_t recv_data;/* USER CODE END PV */
Depois de todo o código de inicialização, permitir ao controlador receber 1 byte. A seguinte função activa o bit de interrupção RXNE.
/* USER CODE BEGIN 2 */HAL_UART_Receive_IT(&huart1, &recv_data, 1);/* USER CODE END 2 */
Agora, adicione uma função de callback para lidar com a interrupção de recepção e transmitir o byte recebido.
/* USER CODE BEGIN 0 */void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){HAL_UART_Transmit(huart, huart->pRxBuffPtr, 1, 1000);}/* USER CODE END 0 */
Finally, we need to compile the code and flash (download) it to the microcontroller.quando o Keil MDK ARM IDE está instalado, os drivers para ST-LINK V2, J-Link e Ulink2 estão disponíveis. O depurador de St-Link será seleccionado por omissão. Go to Projects – Options for Target and in the Debug tab select the ICSP programmer used.
Flash o código selecionando Flash- Download.
o microcontrolador irá agora ecoar quaisquer dados recebidos sobre o UART. Ele pode ser conectado a um PC usando um conversor USB-to-Serial. No PC, abrir a porta COM COM COM com uma aplicação terminal usando as configurações de 115200-8-n-1. Tudo o que for enviado do terminal irá ecoar de volta através do microcontrolador.
sistema de interrupção
o sistema de interrupção STM32 é baseado no núcleo do córtex m periférico NVIC do braço. O STM32 MCUs suporta múltiplos canais de interrupção maskable, além dos 16 canais de interrupção do núcleo do braço.
Por exemplo, a série STM32F0 MCU suporta 32 interrupções maskable. A exceção e a tabela vetorial de interrupção para esta família de MCUs é dada na tabela abaixo.
Interrupt | Description | Vector Address |
– | Reserved | 0x00000000 |
Reset | Reset | 0x00000004 |
NMI | Non maskable interrupt. The RCC clock security system (CSS) is linked to the NMI vector | 0x00000008 |
HardFault | All class of faults | 0x0000000C |
SVCall | System service call via SWI Instruction | 0x0000002C |
PendSV | Pendable request for system service | 0x00000038 |
SysTick | System tick timer | 0x0000003C |
WWDG | Window watchdog interrupt | 0x00000040 |
PVD_VDDIO2 | PVD and VDDIO2 supply comparator interrupt (combined with EXTI lines 16 and 31) | 0x00000044 |
RTC | RTC interrupts (combined EXTI lines 17, 19 and 20) | 0x00000048 |
Flash | Flash global interrupt | 0x0000004C |
RCC_CRS | RCC and CRS global interrupts | 0x00000050 |
EXTI0_1 | EXTI line interrupts | 0x00000054 |
EXTI2_3 | EXTI line interrupts | 0x00000058 |
EXTI4_15 | EXTI line interrupts | 0x0000005C |
TSC | Touch sensing interrupt | 0x00000060 |
DMA_CH1 | DMA channel 1 interrupt | 0x00000064 |
DMA_CH2_3 DMA2_CH1_2 |
DMA channels 2 and 3 interrupts DMA2 channel1 and 2 interrupts |
0x00000068 |
DMA_CH4_5_6_7 DMA2_CH3_4_5 |
DMA channel 4,5,6 and 7 interrupts DMA2 channel 3, 4, and 5 interrupts |
0x0000006C |
ADC_COMP | ADC and COMP interrupts (Combined EXTI lines 21 and 22) | 0x00000070 |
TIM1_BRK_UP_TRG_COM | TIM1 break, update, trigger and commutation interrupts | 0x00000074 |
TIM1_CC | TIM1 capture compare interrupt | 0x00000078 |
TIM2 | TIM2 global interrupt | 0x0000007C |
TIM3 | TIM3 global interrupt | 0x00000080 |
TIM6_DAC | TIM6 global interrupt and DAC underrun interrupt | 0x00000084 |
TIM7 | TIM7 global interrupt | 0x00000088 |
TIM14 | TIM14 global interrupt | 0x0000008C |
TIM15 | TIM15 global interrupt | 0x00000090 |
TIM16 | TIM16 global interrupt | 0x00000094 |
TIM17 | TIM17 global interrupt | 0x00000098 |
I2C1 | I2C1 global interrupt (combined with EXTI line 23) | 0x0000009C |
I2C2 | I2C2 global interrupt | 0x000000A0 |
SPI1 | SPI1 global interrupt | 0x000000A4 |
SPI2 | SPI2 global interrupt | 0x000000A8 |
USART1 | USART1 global interrupt (combined with EXTI line 25) | 0x000000AC |
UART2 | USART2 global interrupt (combined with EXTI line 26) | 0x000000B0 |
USART3_4_5_6_7_ 8 | USART3, USART4, USART5, USART6, USART7, USART8 global interrupts (combined with EXTI line 28) | 0x000000B4 |
CEC_CAN | CEC and CAN global interrupts (combined with EXTI line 27 | 0x000000B8 |
USB | USB global interrupt (combined with EXTI line 18) | 0x000000BC |
Extended Interrupts and Events Controller (EXTI)
the STM32 MCUs have an Extended interrupts and Events controller which manages the external and internal assynchronous events/interrupts and generates the event request to the CPU/Interrupt Controller and a wake-up request to the Power Manager.
cada uma das Uma ou mais linhas EXTI são mapeadas para um dos vetores de interrupção NVIC.
para as linhas de interrupção externas, para gerar uma interrupção, a linha de interrupção deve ser configurada e ativada. Isto é feito programando os dois registros de gatilho com a detecção de borda desejada e permitindo o pedido de interrupção escrevendo um ‘ 1 ‘ para o bit correspondente no registro de máscara de interrupção.
interrupção externa e mapeamento GPIO
cada uma das GPIO disponíveis no sistema pode ser configurada para gerar uma interrupção. Mas cada uma das linhas de interrupção EXTI é mapeada para múltiplos pinos GPIO. Por exemplo,PIO0 em todas as portas GPIO disponíveis (A,B, C, etc.) será mapeada para a linha externa. PIO1 para todas as portas será mapeado para a linha EXTI1 e assim por diante.algumas das linhas EXTI são combinadas a um único vetor NVIC. Por exemplo, o EXTI4_15 é mapeado para um único endereço vetorial de modo que haverá uma única rotina de interrupção para todas as interrupções de PIO4 para PIO15. Mas a fonte da interrupção pode ser identificada lendo o registro pendente da interrupção.
Uma coisa importante a considerar ao projetar um sistema usando o MCUs STM32 é a seleção dos pinos GPIO para as interrupções. A MCU pode ter mais de 16 GPIOs disponíveis no dispositivo, mas há apenas 16 linhas externas de interrupção disponíveis.
Por exemplo, o EXTI_0 pode ser mapeado para PA0 ou PB0, mas não ambos. Assim, ao escolher os pinos para interrupções externas, eles devem ser escolhidos de modo que eles possam ser mapeados de forma única para uma das linhas EXTI.
a secção seguinte descreve como configurar uma interrupção usando o cubo STM32.
seleccione a Página de configuração e escolha o módulo de ‘hardware’ para o qual a interrupção tem de ser configurada. A janela de configuração do módulo abre.
depois seleccione a página de configuração NVIC e active a interrupção global.
o código para activar a interrupção para o módulo será gerado no stm32f0xx_hal_msp.c in the HAL_<module_MSPInit(…) function.
/* USART1 interrupt Init */HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);HAL_NVIC_EnableIRQ(USART1_IRQn);
o código gerado pelo cubo STM32 terá a implementação IRQ_Handler de todas as interrupções. Quando a interrupção estiver ativada, o código será incluído na aplicação.
Geralmente o código gerado já lida com a IRQ e limpa a bandeira que gerou a interrupção. Ele então chama um callback de aplicação que corresponde ao evento que gerou a interrupção para o módulo.
o STM32 HAL (camada de abstração de Hardware) implementa um callback para cada um dos tipos de eventos dentro de cada módulo como parte do driver. Neste exemplo, a transferência Rx chamada completa deve ser copiada do stm32f0xx_hal_UART.c file.
As funções de callback dentro do driver serão implementadas com um atributo __linker fraco. O usuário precisa implementar uma cópia da função de callback necessária, removendo o atributo _ _ weak em um dos arquivos da aplicação e, em seguida, escrevendo o tratamento específico necessário dentro dessa função.
/*** @brief Rx Transfer completed callback.* @param huart UART handle.* @retval None*/__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){/* Prevent unused argument(s) compilation warning */UNUSED(huart);/* NOTE : This function should not be modified, when the callback is needed,the HAL_UART_RxCpltCallback can be implemented in the user file.*/}
Conclusion
este tutorial é uma introdução à escrita de uma aplicação que trabalha com a família STM32 de microcontroladores. Existem vários outros métodos para escrever uma aplicação, mas o STM32Cube discutido é um método fácil e intuitivo para começar.
Esta ferramenta simplifica a inicialização dos periféricos microcontroladores. Ele também melhora a manutenção do Código, especialmente quando há revisões de hardware que requerem remapeamento dos sinais para diferentes pinos.
outra vantagem de usar a ferramenta STM32Cube é que ela gera um relatório da configuração do Usuário para o microcontrolador. Neste relatório ele detalha a árvore do relógio, mapeamento pin e configuração do módulo de hardware que são todos muito úteis.
existem também várias outras bibliotecas de código e programas de exemplo disponíveis para todas as variantes STM32. O suporte para vários IDEs também está incluído.se o seu projecto requer um microcontrolador sofisticado de 32 bits, recomendo vivamente a série STM32. Não só são poderosos e populares, mas os microcontroladores STM32 também são bastante acessíveis.precisa de mais formação em microcontroladores de programação STM32? Se sim, aqui está um curso introdutório mais profundo que você deve verificar.este artigo foi escrito por Mohan Kashivasi da Vithamas Technologies. Ele também é um dos especialistas disponíveis para ajudá-lo com o seu produto dentro da Academia de Hardware.
finalmente, não se esqueça de baixar o seu PDF gratuito: Ultimate Guide to Develop and Sell Your New Electronic Hardware Product. Você também receberá minha newsletter semanal onde eu compartilho conteúdo premium não disponível no meu blog.
Outros conteúdos que você pode gostar:
- Introdução ao STM32CubeIDE para STM32 Microcontroladores
- Como escolher o Microcontrolador para o Seu Novo Produto
- Utilizando o Arduino como uma Incorporado a Plataforma de Desenvolvimento
- Datasheet Revisão: Entry-Level STM32 Cortex-M0 Microcontroller (Blog + Video)
- Introduction to the Ultra High-Performance STM32H7 32-bit Microcontroller