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

需要根据使用查询!!

相关推荐
yutian06066 小时前
Keil MDK下载程序后MCU自动重启设置
单片机·嵌入式硬件·keil
析木不会编程8 小时前
【小白51单片机专用教程】protues仿真独立按键控制LED
单片机·嵌入式硬件·51单片机
枯无穷肉12 小时前
stm32制作CAN适配器4--WinUsb的使用
stm32·单片机·嵌入式硬件
不过四级不改名67713 小时前
基于HAL库的stm32的can收发实验
stm32·单片机·嵌入式硬件
嵌入式科普13 小时前
十一、从0开始卷出一个新项目之瑞萨RA6M5串口DTC接收不定长
c语言·stm32·cubeide·e2studio·ra6m5·dma接收不定长
嵌入式大圣13 小时前
单片机UDP数据透传
单片机·嵌入式硬件·udp
云山工作室13 小时前
基于单片机的视力保护及身姿矫正器设计(论文+源码)
stm32·单片机·嵌入式硬件·毕业设计·毕设
嵌入式-老费14 小时前
基于海思soc的智能产品开发(mcu读保护的设置)
单片机·嵌入式硬件
qq_3975623115 小时前
MPU6050 , 设置内部低通滤波器,对于输出数据的影响。(简单实验)
单片机
liyinuo201715 小时前
嵌入式(单片机方向)面试题总结
嵌入式硬件·设计模式·面试·设计规范