STM32F103C8T6实操学习1(Cube+HAL库)-点亮LED灯

在点亮LED灯之前,让我们来学习一下什么是GPIO的输出,学习完再操作能加深理解哦。

一、GPIO

1.1 什么是GPIO?

General Purpose Input Output,即通用输入输出端口,简称GPIO

作用:负责采集外部器件的信息或者控制外部器件工作,即输入输出。

1.2 GPIO的特点

  • 可配置为8种输入输出模式
  • 引脚电平:0V~3.3V,部分引脚可容忍5V(数据手册中有标注FT的引脚)
  • 输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等
  • 输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等

1.3 GPIO结构

基本结构

I/O端口位基本结构

PS:施密特触发器就是一种整形电路,可以将非标准方波,整形成方波

特点:

  • 当输入电压高于正向阈值电压,输出为高;
  • 当输入电压低于负向阈值电压,输出为低;
  • 当输入在正负向阈值电压之间,输出不改变。

作用:整形!如正弦波转方波!

P-MOS & N-MOS管简介

MOS管是压控型元件,通过控制栅源电压( Vgs )来实现导通或关闭。

1.4 GPIO的八种模式分析

通过配置GPIO的端口配置寄存器,端口可以配置成以下8种模式

(1)输入浮空

(2)输入上拉

Tips:

上拉电阻和下拉电阻是在数字电路中常见的电路连接方式,用于确保信号在特定逻辑状态下的稳定性。它们通常用于输入/输出引脚或开关控制线上。

  1. 上拉电阻(Pull-up Resistor):

    (1)上拉电阻是连接到信号线上的电阻,将信号线连接到高电平(通常是电源电压)。(2)在数字电路中,当没有外部驱动器或开关将信号线拉向低电平时,上拉电阻会将信号线拉向高电平。这样可以确保信号线在未连接或未驱动时保持在已定义的状态上。
  2. 下拉电阻(Pull-down Resistor):

    (1)下拉电阻是连接到信号线上的电阻,将信号线连接到低电平(通常是地/0V)。          (2)在数字电路中,当没有外部驱动器或开关将信号线拉向高电平时,下拉电阻会将信号线拉向低电平。这样可以确保信号线在未连接或未驱动时保持在已定义的状态上。

上拉电阻和下拉电阻的作用是确保信号线在未连接到任何外部设备或驱动器时,仍能保持在已定义的逻辑状态上,而不会漂浮或处于不确定状态。这对于数字电路的稳定性和可靠性非常重要。

需要注意的是,上拉电阻和下拉电阻一般在需要稳定信号的输入/输出引脚上使用,通常与开关、按键、传感器等设备一起使用。它们的数值和连接位置需要根据具体的电路和系统要求来选择和设计。

(3)输入下拉

(4)模拟输入

(5)开漏输出

(6)复用开漏输出

(7)推挽输出

(8)复用推挽输出

F1在输出模式,禁止使用内部上下拉。

二、硬件组成

  • 器件:

1.面包板

2.LED发光二极管

3.电阻(500Ω-1000Ω,最好有,此次操作没用)

4.杜邦线若干

5.ST-LINK下载线

  • 硬件简介:

面包板:+代表正极,-代表负极。

正面

背面

LED:发光二极管,正向通电点亮,反向通电不亮 有源蜂鸣器:内部自带振荡源,将正负极接上直流电压即可持续发声,频率固定。

硬件电路:

ST-LINK下载线:按照ST-LINK上的丝印连接(一一对应,注意不要连错,若连错在Keil中下载程序时将无法正常下载!)

接线图:

实物接线图(注意,下图没有加上电阻)

三、CUBE配置(部分内容转载至https://blog.csdn.net/qq_38191568/article/details/126021237)

1.打开STM32CubeMX,点击“ACCESS TO MCU SELECTOR”

2.CubeMX自动下完补丁包之后,会弹出芯片选择界面,在Commercial搜索框输入F103C8T6右下方会自动出现STM32F103C8T6,双击芯片。

(这里也可以点击⭐收藏然后之后打开时可以不用搜索直接点击⭐,双击对应芯片即可)

3.进入配置界面后单击System Core(系统的核心) → SYS → Debug → Serial Wire(这个是调试模式,如果不选Serial Wire则可能会使得无法使用Stlink或Jlink下载,如果用串口线下载,不调试,不选也没关系),这时PA13与PA14被用来做调试的LCK和DIO口,如果引脚不够用的情况可以不配置为LCK和DIO口,可以把PA13、PA14当做普通IO口使用。

4.单击System Core(系统的核心) → RCC(配置晶振) → High speed Clock(HSE)(高速晶振)→ Crystal/Ceramic Resonator(外部晶振,8M)(如果这里选Disable则无法使用外部高速晶振),这时PD0与PD1被用来做晶振的接口,如果不配置则可以把PD0、PD1当做普通IO口使用。

5.依次单击Pinout & Configuration → System Core → GPIO →右边的PB9和PB6(因为此操作中我LED灯接的PB9和PB6,未后续流水灯做准备,所以这里都选) → GPIO_Output

对PB9进行命名(此处只有PB9进行命名,PB6没有进行命名)


6.设置好之后PB6和PB9变成绿色


7.单击Clock Configuration在这里输入72,按下回车 → OK,自动配置时钟频率为72Mhz


注:如果弹出这个窗口,不能使用72Mhz只能设置为64Mhz,那就是在RCC没有配置外部高速晶振,回去配置即可,如果还不行,那就是芯片选错了。


8.单击Project Manager → Project ,配置准备要生成的工程


9.单击Code Generator 单选Copy only the nacassary library files,勾选Generate peripheral…peripheral,上述的配置都设置好后就可以单击右上角的GENERATE CODE生成工程了。


10.打开工程


四、程序代码


(1)打开工程后,进入Keli5软件,依次打开工程结构树,双击main.c开始写源码
切忌:一定要在BEGIN END里写代码,不然后面STM32CubeMX重新配置生成代码会删除BEGIN END外面的代码


(2)找到Drivers文件夹里的stm32f1xx_hal_gpio.c(双击打开),找到第465行的HAL_GPIO_WritrPin函数,复制其函数名,并在main方法里的wihile(1)调用

(3)在main.c中的wihile(1)编写程序

(4)编译并烧录程序(将ST-LINK插入电脑中)

结果展示:(此处只点亮了PB9即绿灯,没有点亮PB6)

补充

流水灯(PB6和PB9):(加上HAL_Delay起到延时的作用,依次点亮LED灯,我这里是两个,大家可酌情添加)

红色箭头为有命名的引脚,绿色箭头为无命名的引脚,稍有差异,自己体会一下。

结果展示:

绿灯亮,红灯灭

红灯亮,绿灯灭

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F103C8T6是一款常用的单片机,它基于ARM Cortex-M3内核,具有丰富的外设资源。HAL库(Hardware Abstraction Layer)是ST公司提供的一套硬件抽象层库,可以简化对STM32外设的操作。 要实现按键控制LED亮度,可以按照以下步骤进行: 1. 初始化GPIO:首先需要初始化按键和LED所连接的GPIO引脚。使用HAL库提供的函数可以方便地进行GPIO初始化,设置引脚为输入或输出模式。 2. 配置中断:为了实现按键的响应,可以配置外部中断。当按键按下时,触发中断,并执行相应的中断服务函数。 3. 编写中断服务函数:在中断服务函数中,可以编写代码来控制LED的亮度。可以通过改变LED的PWM占空比来实现不同的亮度调节。 4. 启动中断:在主函数中,启动外部中断,使其开始监听按键的状态变化。 下面是一个简单的示例代码,演示了如何使用STM32F103C8T6HAL库实现按键控制LED亮度: ```c #include "stm32f1xx_hal.h" // 定义LED引脚和按键引脚 #define LED_PIN GPIO_PIN_13 #define LED_PORT GPIOC #define KEY_PIN GPIO_PIN_0 #define KEY_PORT GPIOA // 定义PWM相关参数 #define PWM_PERIOD 1000 // PWM周期 #define PWM_CHANNEL TIM_CHANNEL_1 // 使用的PWM通道 // 全局变量 TIM_HandleTypeDef htim; uint32_t pwmValue = 0; // PWM占空比 // 按键中断回调函数 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin == KEY_PIN) { // 按键按下时,增加PWM占空比 pwmValue += 100; if (pwmValue > PWM_PERIOD) { pwmValue = 0; } __HAL_TIM_SET_COMPARE(&htim, PWM_CHANNEL, pwmValue); } } int main(void) { // 初始化HAL库 HAL_Init(); // 初始化时钟 SystemClock_Config(); // 初始化GPIO GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = LED_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); GPIO_InitStruct.Pin = KEY_PIN; GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(KEY_PORT, &GPIO_InitStruct); // 初始化定时器 __HAL_RCC_TIM3_CLK_ENABLE(); htim.Instance = TIM3; htim.Init.Prescaler = 0; htim.Init.CounterMode = TIM_COUNTERMODE_UP; htim.Init.Period = PWM_PERIOD - 1; htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_PWM_Init(&htim); TIM_OC_InitTypeDef sConfigOC = {0}; sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = pwmValue; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(&htim, &sConfigOC, PWM_CHANNEL); HAL_TIM_PWM_Start(&htim, PWM_CHANNEL); // 启动中断 HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0); HAL_NVIC_EnableIRQ(EXTI0_IRQn); while (1) { // 主循环 } } // 系统时钟配置函数 void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值