HAL编程1-入门级

一、UART示例升级版

1. 升级1,优化工程生成

STM32CubeMX操作同样的步骤,升级后生成代码。

2. 升级2,用UART接收控制指令,控制LED亮灭

修改源码:

main.c

#include <stdio.h>


#include "main.h"
#include "usart.h"
#include "gpio.h"


void SystemClock_Config(void);


int main(void)
{
  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  MX_USART1_UART_Init();

  printf("Hello from STM32 HAL UART!\r\n");

  while (1)
  {
    //主循环不处理
  }
}

usart.c(在此添加重定向和中断处理回调函数)

要记得在启动UART接收中断,此外全是CubeMX自动生成

#include <stdio.h>
#include <string.h>


uint8_t rx_data;


// 重定向printf和scanf到USART1
int fputc(int ch, FILE *f)
{
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
    return ch;
}

int fgetc(FILE *f)
{
    uint8_t ch = 0;
    HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
    return ch;
}

// 接收到数据后的中断回调
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if (huart->Instance == USART1)
  {
    if (rx_data == '1') {
      HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET);  // 点亮LED
      const char *msg = "LED ON\r\n";
      HAL_UART_Transmit(&huart1, (uint8_t *)msg, strlen(msg), HAL_MAX_DELAY);
    }
    else if (rx_data == '0') {
      HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET); // 熄灭LED
      const char *msg = "LED OFF\r\n";
      HAL_UART_Transmit(&huart1, (uint8_t *)msg, strlen(msg), HAL_MAX_DELAY);
    }
    else {
      const char *msg = "Unknown command\r\n";
      HAL_UART_Transmit(&huart1, (uint8_t *)msg, strlen(msg), HAL_MAX_DELAY);
    }

    // 再次启动接收
    HAL_UART_Receive_IT(&huart1, &rx_data, 1);
  }
}

现象展示

现在就可以用串口控制LED的亮灭了。升级结束。

二、Timer示例编程

回想一下UART的实例现象,是UART发送一条信息,LED每隔500ms亮灭翻转,实现闪烁。当时使用的是HAL_Delay(500)。

现在改为用定时器实现LED每隔500ms亮灭翻转,在LED每次状态翻转的同时,UART发送一条信息“Hello,Timer!”

1. 使用STM32CubeMX 生成工程

第一步:启动 CubeMX 工程

打开 STM32CubeMX;

点击 “New Project”;

搜索并选择芯片:STM32F407VET6;

点击 “Start Project”。

第二步:配置外设(重点)

配置RCC和SYS----很重要,很简单,不赘述

1. 配置 GPIO
在 Pinout 视图点击 PA6,设置为 GPIO_Output;

2. 配置 USART1
点击 PA9 设置为 USART1_TX,PA10 设置为 USART1_RX;

在 Peripherals > USART1 中设置:

Mode: Asynchronous

Baud Rate: 115200

Enable USART1 global interrupt(中断可选,printf 不需要)

定时器配置如图:(图中没有使能中断,还要在NVIC Settings中使能中断)

3. 配置定时器 TIM2

在 Peripherals > TIM2:

3.1. 在 Mode > Clock Source:Internal Clock(内部时钟)

3.2. 在 Configuration > Parameter Settings 中设置:

      Prescaler = 7199(定时器分频系数)

      Counter Period = 4999(自动重装载值Arr)

定时器溢出时间:T = (Prescaler+1)×(Arr+1)​ / 定时器时钟频率(Hz)

分频:72MHz / (7199 + 1) = 10KHz

重装一次:10KHz / (4999  + 1) = 2Hz

换算成时间:1/2 = 0.5s  = 500ms

也就是每 500ms 中断一次,也可以代入公式去计算

3.3. 在 Configuration > NVIC Settings中设置:勾选中断使能

第三步:配置时钟(Clock Configuration)

同前 

第四步:Project Settings

点击左上角菜单栏 Project > Settings

设置项目名:HAL_LedUsart_Timer

选择工具链:MDK-ARM

Code Generation 默认问题不大,但是建议如升级示例设置

第五步:生成代码

点击右上角的 “GENERATE CODE”

代码结构已就绪

2. 编写 main.c 测试代码

#include "main.h"
#include "stdio.h"

UART_HandleTypeDef huart1;
TIM_HandleTypeDef htim2;

int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
  return ch;
}

int main(void)
{
  HAL_Init();
  SystemClock_Config();      // CubeMX 自动生成
  MX_GPIO_Init();            // PA6
  MX_USART1_UART_Init();     // PA9/PA10
  MX_TIM2_Init();            // TIM2 1Hz

  HAL_TIM_Base_Start_IT(&htim2);   // 启动定时器中断

  while (1)
  {
    // 主循环无需处理,交给中断完成
  }
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if (htim->Instance == TIM2)      //判断中断来自TIM2
  {
    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_6);
    printf("Hello,Timer!\r\n");
  }
}

3.  编译下载

使用 Keil 编译
勾选如开篇文尾的Tips2和Tips3
 
使用 DAP 调试下载(有什么用什么吧)
 
用串口助手SSCom(115200 8N1)查看串口输出(PA9, PA10 接 USB 转串口)

4. 现象展示

同时伴有LED闪烁。

今天HAL库的简单示例:定时器就到这里啦!

Gitee代码仓库分享:

https://gitee.com/jinjing616/HAL_Test.git

明天继续分享下一个小示例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LilyJin616

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值