STM32初识1

什么是单片机?

单片机( Single-Chip Microcomputer )是一种集成电路芯片,把具有数据处理能力的中央处
理器 CPU 、随机存储器 RAM 、只读存储器 ROM 、多种 I/O 口和中断系统、定时器 / 计数器等功
能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、 A/D 转换器等电路)集成
到一块硅片上构成的一个小而完善的微型计算机系统,在工业控制领域广泛应用。

STM****系列单片机命名规则

ST -- 意法半导体
M -- Microelectronics 微电子
32 -- 总线宽度

STM32F103C8T6****单片机简介

|----------|----------------------------------------------------------------------------------------------------------|
| 项目 | 介绍 |
| 内核 | Cortex-M3 |
| Flash | 64K x 8bit |
| SRAM | 20K x 8bit |
| GPIO | 37 个 GPIO ,分别为 PA0-PA15 、 PBO-PB15 、 PC13-PC15 、 PDO-PD1 |
| ADC | 2 个 12bit ADC 合计 12 路通道,外部通道 : PAO 到 PA7+PBO 到 PB1 内部通道 : 温度传感器通道ADC Channel 16 和内部参考电压通道 ADC Channel 17 |
| 定时器/ 计数器 | 4 个 16bit 定时器 / 计数器,分别为 TIM1 、 TIM2 、 TIM3 、 TIM4TM1 带死区插入,常用于产生PWM 控制电机 |
| 看门狗定时器 | 2 个看门狗定时器 ( 独立看门狗 IWDG 、窗口看门狗 WWDG) |
| 滴答定时器 | 1 个 24bit 向下计数的滴答定时器 systick |
| 工作电压、温度 | 2V3.6V 、 -40°C85°C |
| 通信串口 | 2 * IIC , 2 * SPI , 3 * USART , 1 * CAN |
| 系统时钟 | 内部 8MHz 时钟 HSI 最高可倍频到 64MHZ ,外部 8MHZ 时钟 HSE 最高可倍频到72MHZ |
| | |

标准库与HAL库区别

  1. 寄存器
  • 寄存器众多,需要经常翻阅芯片手册,费时费力;
  • 更大灵活性,可以随心所欲达到自己的目的;
  • 深入理解单片机的运行原理,知其然更知其所以然。
  1. 标准库
  • 将寄存器底层操作都封装起来,提供一整套接口(API)供开发者调用每款芯片都编写了一份库文件,也就是工程文件里stm32F1xx...之类的;
  • 配置结构体变量成员就可以修改外设的配置寄存器,从而选择不同的功能;
  • 大大降低单片机开发难度,但是在不同芯片间不方便移植。
  1. HAL 库
  • ST公司目前主力推的开发方式,新的芯片已经不再提供标准库;
  • 为了实现在不同芯片之间移植代码;
  • 为了兼容所有芯片,导致代码量庞大,执行效率低下

通用输入输出端口****GPIO

什么是GPIO

定义
GPIO 是 通用输入输出 端口的简称,简单来说就是 STM32 可控制的引脚 STM32 芯片的 GPIO 引脚与
外部设备连接起来,从而实现与外部通讯、控制以及数据采集的功能。
简单来说我们可以控制 GPIO 引脚的电平变化,达到我们的各种目的。
命名规则

组编号**+**引脚编号 GPIOx

组编号: GPIOA, GPIOB, GPIOC, GPIOD .. GPIOG
引脚编号: 0 , 1 , 2 , 3 , 4...15
组合起来:
PA0, PA1, PA2 .. PA15
PB0, PB1, PB2 .. PB15
PC0, PC1, PC2 .. PC15
...
**有一些特殊功能的引脚是不能用作IO的:**例如,我使用的STM32F103C8T6有48个引脚,但只有37个GPIO口,而剩下的都是用作特殊功能的,比如VCC,BOOT等...
内部框架图

推挽输出和开漏输出:

推挽输出 :可以真正的输出高电平和低电平

开漏输出: 开漏输出无法真正输出高电平,即高电平时没有驱动能力,需要借助外部上拉电阻完 成对外驱动

什么是GPIO的推挽输出和开漏输出_gpio推挽输出-CSDN博客

点亮LED

其实点亮LED的操作在上节已经实现了,这里在深入了解一下相关函数:

  1. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);

效果是对一个GPIO口写入1或者0,第一个参数是GPIO的组第二个参数是GPIO的引脚第三个参数是引脚的状态

cpp 复制代码
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{
  /* Check the parameters */
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  assert_param(IS_GPIO_PIN_ACTION(PinState));

  if (PinState != GPIO_PIN_RESET)
  {
    GPIOx->BSRR = GPIO_Pin;
  }
  else
  {
    GPIOx->BSRR = (uint32_t)GPIO_Pin << 16u;
  }
}
  1. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

效果是初始化GPIO口,第一个参数是GPIO的组第二个参数是一个结构体指针,可以通过跳转查看具体信息:

cpp 复制代码
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;

因此在执行GPIO的初始化之前需要自己定义一个结构体 GPIO_InitTypeDef GPIO_InitStruct = {0};

并对其中的成员进行赋值:

cpp 复制代码
void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

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

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_RESET);

  /*Configure GPIO pins : PB8 PB9 */
  GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
  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);

}
  1. void HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);

效果是反转GPIO口的状态,第一个参数是GPIO的组第二个参数是GPIO的引脚

使用轮询法实现按键点亮LED灯

由原理图可见, 如果按钮SW1,2被按下,会对应KEY1,2被拉低,所以可以通过观察A0和A1是否被拉低来判断按钮是否被按下。

那么首先要涉及到PA0,PA1的初始化,所以可以打开上节编辑到一半的CubeMX软件来配置:

由于按键是触发输入信号将PA0和PA1设计成"GPIO_Input":

可以将PB8,9的初始值设置为高电平,这样程序烧录之后灯不会立刻亮起来

由于是在上节的工程基础上改的,所以不需要在设置Project Manager里面的内容

点击"GENERATE CODE"生成代码:

实现的是 按钮1被按下时,LED1亮,再次按下熄灭;如果按钮2被按下时,LED2亮,再次按下熄灭

cpp 复制代码
#define KEY_ON 0
#define KEY_OFF 1

uint8_t Key_scan(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
	if(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == GPIO_PIN_RESET)
	{
		/*按键按下*/
		while(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == GPIO_PIN_RESET);//按键消抖,如果按键没有被按下不会触发return
		return KEY_ON;
	}
	else
	{
		/*按键松开*/
		return KEY_OFF;
	
	}
}

int main(void)
{

  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  while (1)
  {
    
		//HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_RESET);
		if(Key_scan(GPIOA ,GPIO_PIN_0) == KEY_ON)//如果A0对应的按钮按下
		{
			HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);//反转LED1的状态
		}
		if(Key_scan(GPIOA ,GPIO_PIN_1) == KEY_ON)//如果A1对应的按钮按下
		{
			HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_9);//反转LED2的状态
		}

}

注意!!!HAL库有很多重定义的类型,例如uint8_t

需要根据使用查询!!

相关推荐
来自晴朗的明天22 分钟前
16、电压跟随器(缓冲器)电路
单片机·嵌入式硬件·硬件工程
钰珠AIOT37 分钟前
在同一块电路板上同时存在 0805 0603 不同的封装有什么利弊?
嵌入式硬件
代码游侠38 分钟前
复习——Linux设备驱动开发笔记
linux·arm开发·驱动开发·笔记·嵌入式硬件·架构
代码游侠12 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
xuxg200514 小时前
4G 模组 AT 命令解析框架课程正式发布
stm32·嵌入式·at命令解析框架
CODECOLLECT15 小时前
京元 I62D Windows PDA 技术拆解:Windows 10 IoT 兼容 + 硬解码模块,如何降低工业软件迁移成本?
stm32·单片机·嵌入式硬件
BackCatK Chen16 小时前
STM32+FreeRTOS:嵌入式开发的黄金搭档,未来十年就靠它了!
stm32·单片机·嵌入式硬件·freertos·低功耗·rtdbs·工业控制
全栈游侠18 小时前
STM32F103XX 02-电源与备份寄存器
stm32·单片机·嵌入式硬件
Lsir10110_19 小时前
【Linux】中断 —— 操作系统的运行基石
linux·运维·嵌入式硬件