欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

STM32裸机开发基础篇02-点亮LED (HAL库)

程序员文章站 2022-03-16 11:12:02
前言上一节,我们完成了STM32单片机开发环境的搭建,本节我们正式学习STM32单片机,编程语言的学习,通常是从第一个"hello world"开始,而点灯实验便是单片机学习的开始。一、基础知识1. STM32最小系统简介一个最小的STM32系统,需要有单片机、电源电路、晶振电路、复位电路、启动电路、调试电路组成,这几部分存在就可以使STM32正常工作。(1) STM32F103C8T6ARM的Cortex-M3处理器是最新一代的嵌入式ARM处理器,它为实现MCU的需要提供了低成本的平台、缩减...

前言

上一节,我们完成了STM32单片机开发环境的搭建,本节我们正式学习STM32单片机,编程语言的学习,通常是从第一个"hello world"开始,而点灯实验便是单片机学习的开始。

一、基础知识

1. STM32最小系统简介

一个最小的STM32系统,需要有单片机、电源电路、晶振电路、复位电路、启动电路、调试电路组成,这几部分存在就可以使STM32正常工作。

(1) STM32F103C8T6
STM32裸机开发基础篇02-点亮LED (HAL库)

ARM的Cortex-M3处理器是最新一代的嵌入式ARM处理器,它为实现MCU的需要提供了低成本的平台、缩减的引脚数目、降低的系统功耗,同时提供卓越的计算性能和先进的中断系统响应。

ARM的Cortex-M3是32位的RISC处理器,提供额外的代码效率,在通常8和16位系统的存储空间上发挥了ARM内核的高性能。

(2) 电源电路

和STC89C52单片机5V供电不同,STM32需要3.3V电压供电,直接输入的电压不太稳定性,需要电路稳压,同时点亮LED1,可以通过LED1的亮灭初步观察系统运行情况,正常运行情况,LED1常亮。

使用稳压芯片,将USB输入的5V电压转换为STM32需要的3.3V电压
STM32裸机开发基础篇02-点亮LED (HAL库)

LED1电路如下,插上Micro USB线后即可点亮
STM32裸机开发基础篇02-点亮LED (HAL库)

(3) 复位电路
STM32裸机开发基础篇02-点亮LED (HAL库)

单片机有一个RESET引脚,只需要将此引脚保持一段时间低电平即可复位STM32单片机,当按键按下瞬间,RESET电平为低电平,复位STM32单片机,之后C2开始充电,C2电源不断上升,R2两端电压不断下降,当C2两端电压达到3.3V时,充电结束,此时RESET引脚变为高电平,单片机进入正常工作状态,复位完成。

注意:51单片机是高电平复位,STM32是低电平复位

(4) 晶振电路
STM32裸机开发基础篇02-点亮LED (HAL库)

上图中有两个晶振,一个是8MHz,另一个是32.768KHz,8M晶振的作用是为最小系统提供最基本的时钟信号,方便倍频,一般STM32F103系列正常使用过程需要倍频到72MHz。32.768KHZ晶振经过15次分频后可以得到1HZ的频率(原因是32768 = 2^15),可以实现精准定时,用于精准计时电路,比如作为万年历。

(5) boot启动电路
STM32裸机开发基础篇02-点亮LED (HAL库)
启动方式如下表所示:
STM32裸机开发基础篇02-点亮LED (HAL库)

(5) 调试接口电路

本系列教程使用STM32F103C8T6核心板,其调试接口电路采用JLink SWD方式进行
STM32裸机开发基础篇02-点亮LED (HAL库)

2.LED灯发光原理

LED灯中有电流通过时候,将点亮LED灯,单片机系统中,常见的LED灯如下所示,其中长的引脚一端为正极,短的为负极。
STM32裸机开发基础篇02-点亮LED (HAL库)

那么问题来了,如何让LED中有电流通过呢?电流到多少才能点亮LED呢?我们先看下实际电路设计中常用的LED设计电路
STM32裸机开发基础篇02-点亮LED (HAL库)

上图中LED1左边接入电源正极、右边接入负极,电流方能通过点亮LED,此时LED电阻几乎为0,如果电源接反方向了,LED产生很大电阻,阻止电流通过,此时,不能LED不能点亮,一般而言LED正向接入电源,保证通过LED中的电流为20mA左右即可点亮LED。

3.查看开发底板LED部分原理图

STM32裸机开发基础篇02-点亮LED (HAL库)

上图中led_wifi led_red led_green分别连接单片机PB12 PB13 PB14引脚,只需要控制单片机给低电平即可点亮LED。

开发板实物图如下:
STM32裸机开发基础篇02-点亮LED (HAL库)

二、实例

1. 新建工程

使用STM32CubeMX创建一个新的工程,参考上节配置方式,设置RCC和PB12 PB13 PB14引脚输出
STM32裸机开发基础篇02-点亮LED (HAL库)

进入Clock configuration页面,选择HSE时钟源,倍频后主时钟为72MHz
STM32裸机开发基础篇02-点亮LED (HAL库)

切换到Project Manager栏目,设置工程名字、工程保存目录、工具链等信息,具参数如下图所示
STM32裸机开发基础篇02-点亮LED (HAL库)

点击左边栏目Code Generator,然后勾选Generate peripheral initialization as a pair of ‘.c/.h’ files per peripheral,勾选此选项,外设将单独保存在一个文件中,而不是全部都在main.c中。
STM32裸机开发基础篇02-点亮LED (HAL库)

然后打开02Led.uvprojx工程
STM32裸机开发基础篇02-点亮LED (HAL库)

打开后工程如下
STM32裸机开发基础篇02-点亮LED (HAL库)

可以看到多了一个gpio.c文件,main.c中MX_GPIO_Init()便是调用的gpio.c中的文件,其函数声明在gpio.h中
STM32裸机开发基础篇02-点亮LED (HAL库)

2. GPIO函数说明

(1) 首先查看下gpio.c中MX_GPIO_Init()函数

void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14, GPIO_PIN_RESET);

  /*Configure GPIO pins : PB12 PB13 PB14 */
  GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

在GPIO初始化函数中,首先使能GPIOB时钟,然后初始化PB12 PB13 PB14,初始化函数用到了GPIO_InitTypeDef定义的GPIO_InitStruct,我们接下来看看GPIO_InitTypeDef结构

typedef struct
{
  uint32_t Pin;       /*!< Specifies the GPIO pins to be configured.
                           This parameter can be any value of @ref GPIO_pins_define */

  uint32_t Mode;      /*!< Specifies the operating mode for the selected pins.
                           This parameter can be a value of @ref GPIO_mode_define */

  uint32_t Pull;      /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.
                           This parameter can be a value of @ref GPIO_pull_define */

  uint32_t Speed;     /*!< Specifies the speed for the selected pins.
                           This parameter can be a value of @ref GPIO_speed_define */
} GPIO_InitTypeDef;

其中Pin表示需要操作的GPIO引脚,GPIO_PIN_All表示选择该端口所有引脚GPIO_PIN_0~GPIO_PIN_15

Mode 用以设置选中管脚的工作状态
STM32裸机开发基础篇02-点亮LED (HAL库)

Pull表示引脚下拉或上拉设置
STM32裸机开发基础篇02-点亮LED (HAL库)

Speed引脚驱动速率设置
STM32裸机开发基础篇02-点亮LED (HAL库)

3. 修改程序

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* 一个__NOP()为1/72us */
void delay_us(uint32_t time)
{
        uint32_t i=0;
        for(i=0;i<time;i++){
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        }

}

void delay_ms(uint16_t time)
{    
   delay_us(time*1000);
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* 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();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    HAL_GPIO_WritePin(GPIOB,           GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14,GPIO_PIN_SET);
    delay_ms(1000);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14, GPIO_PIN_RESET);
    delay_ms(1000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */

  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

三、下载运行

按照上一节方式给核心板下载程序,然后将核心板直插到底板上面,可以看到底板三个LED灯在交替闪烁。
STM32裸机开发基础篇02-点亮LED (HAL库)

四、小结

如您在使用过程中有任何问题,请加QQ群进一步交流。

QQ交流群:906015840 (备注:物联网项目交流)

源码获取:关注公众号,回复stm32_hal获取资料

硬件获取:某宝搜索小驿物联

PCB开源:https://lceda.cn/solitary_sand/51-dan-pian-ji-wu-lian-wang-kai-fa-ban_base
STM32裸机开发基础篇02-点亮LED (HAL库)
一叶孤沙出品:一沙一世界,一叶一菩提

本文地址:https://blog.csdn.net/weixin_45006076/article/details/109008161

相关标签: STM32玩转物联网