STM32CubeMX学习笔记

本文详细介绍了STM32CubeMX中的GPIO配置步骤,包括初始化、电平控制、串口发送、用户标签的使用以及如何提高代码重用性和调试技巧,还涉及了外部中断和测量PWM频率的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.生成代码前的准备及点亮led

配置:在新的工程建立之初的左边的第一个systrm core中的

(1)sys配置:Debug选择第二个Serial Wire(选上后可以使用仿真器下载)

(2)RCC配置:选择高速时钟

(3)配置系统时钟:在上方的Clock configuration将系统时钟配置为72mhz

然后选择好引脚然后将引脚的初始状态设置为高电平(熄灭的状态)即

然后是GPIO mode分为推挽和开漏输出

GPIO Pull-up/Pull-down(GPIO的上拉和下拉一般用于按键)

Maximum output speed(输出的速度一般用于通信协议)

最后需要为代码文件命名,然后就是选择编译软件(这里我用的是keil选“MDK-ARM  V5”)

然后在第5步中将第一个打对钩(可以生成对应的.c和.h文件也就是模块化)

最后就可以生成代码了

2.STM32CubeMX中的一些常用的函数

  1. GPIO初始化

    HAL_GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

    • GPIOx:指定要配置的GPIO端口。
    • GPIO_InitStruct:指向包含所需配置参数的结构体。例如:

      GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  2. 读取GPIO引脚电平

    GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

    • GPIOx:指定要读取的GPIO端口。
    • GPIO_Pin:指定要读取的GPIO引脚。
    • 返回值:返回该引脚的电平状态(GPIO_PIN_SETGPIO_PIN_RESET)。
  3. 设置GPIO引脚电平

    void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);

    • GPIOx:指定要写入的GPIO端口。
    • GPIO_Pin:指定要写入的GPIO引脚。
    • PinState:指定要设置的电平状态(GPIO_PIN_SETGPIO_PIN_RESET)。
  4. 翻转GPIO引脚电平

    void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

    • GPIOx:指定要翻转的GPIO端口。
    • GPIO_Pin:指定要翻转的GPIO引脚。
  5. 串口发送数据

    HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

    • huart:指向UART句柄的指针。
    • pData:指向要发送的数据缓冲区的指针。
    • Size:要发送的数据长度。
    • Timeout:超时时间(单位为毫秒)。
    • 返回值:如果成功发送,则返回HAL_OK;否则,返回错误代码。
  6. 延时

    void osDelay(uint32_t delay);

    • delay:以毫秒为单位的延迟时间。
  7. 队列发送

    BaseType_t xQueueSend( QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait );

    • xQueue:指向队列句柄的指针。
    • pvItemToQueue:指向要发送到队列的数据项的指针。
    • xTicksToWait:等待插入操作完成的滴答数(在FreeRTOS环境下)。
    • 返回值:如果成功发送,则返回pdTRUE;如果超时则返回pdFALSE

3.User Lable提高代码的重用性

当你因为种种原因需要更换你的引脚后,发现代码中需要修改的引脚太多了,这时候为了解决这一问题我们就可以使用用户标签

那么什么是User Lable,它可以作什么?它可以帮我们在main.h中生成define语句具体如下。

弄完用户标签后就可以生成代码了。然后将代码中的替换成main.h中的宏定义(建议在一个工程开始的时候就用宏定义这样如果后面需要更改引脚,就只需要在cubeMX中将之前的用户标签填入新定义的引脚中。)

4.串口通信

(1)知道引脚对应的功能

当知道哪个引脚是想要的功能时可以直接在图中勾选,然后在左边的界面中选择串口数,然后右边所选的引脚会变绿

(2)不知引脚对应的功能

这个时候我们就可以借用该软件自动配置,方法如下:

先选择所需的串口数,然后在模式中选择“Asynchronous”,这时它就会自动配置好(如果其中可用引脚被占用了,系统会自动选择其他具有同样功能的引脚,为我们标绿)

除此之外对串口的配置也在步骤二下面的方框中,可以直接设置波特率,奇偶校验位等。然后就可以生成代码了。

以下是一些串口对应的函数

在使用printf函数时需要引入头文件<stdio.h>并且在

/* USER        CODE        BEGIN        0*/和/* USER        CODE        END        0*/之间填入

int fputc(int ch,FILE *f)
{
    uint8_t temp[1] = {ch};
    HAL_UART_Transmit(&huart1,temp,1,2);
    return ch;
 

}

改代码的作用是对printf重定向以便于我们在函数中任意的使用printf来进行一个窗口的输出。

这里我有一种喜欢的格式printf(“【\t + 文件名】+信息”);这样写的好处是当你的代码变复杂时你可以清楚的知道打印数据的地方和它所处的装态。

(3)条件编译

条件编译就是当你在开发的时候你可以打印一些状态以此来调试你的产品,但是当你的产品完成后你可以将不需要打印的东西不执行

代码编写如下首先在/* USER CODE BEGIN PD */和/* USER CODE END PD */之间编写一个这样的函数

#define Log 1

 #if Log        // 如果是“1”就会执行下方的函数反之则不会

函数

#endif

(4)打印一些奇奇怪怪的字

在网址:

https://patorjk.com/software/taag/

中配置好自己的文字然后在主函数中while上面打多行printf函数然后将生成的字符一行一行的复制进去

(5)可变参数宏

/* USER        CODE        BEGIN       includes*/和/* USER        CODE        END        includes*/之间填入头文件和

#define   USER_MAIN_DEBUG

#ifdef      USER_MAIN_DEBUG

#define  user_main_printf(format, ...)printf(format"\r\n",##__VA_ARGS__)

#define  user_main_info(format, ...)        printf("[main]  info:"  foemat "\r\n",##__VA_ARGS__)

#define  user_main_debug(format, ...)    printf("[main]  debug:"  foemat "\r\n",##__VA_ARGS__)

#define  user_main_error(format, ...)      printf("[main]  error:"  foemat "\r\n",##__VA_ARGS__)

#else

#define  user_main_printf(foemat,...)

#define  user_main_info(foemat,...)

#define  user_main_debug(foemat,...)

#define  user_main_error(foemat,...)

#endif

效果:当在下面使用user_main_printf(“stm32”);它会自动在里面添加\r\n

如果去掉#define   USER_MAIN_DEBUG后就只会

user_main_printf(“stm32”);输出结果和普通的printf一样

        

5.注意事项

在编写代码的时候一定要将代码写到其对应的(Private includes 带有这个单词的地方下面的)

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

之间,否者当你再次使用cubeMX改变东西时不按这个规则写的代码会直接消失。

6.外部中断(测量PWM频率)

1.首先选择你需要作为中断的引脚设置为中断引脚

2.进入system view使能中断,将EXTI line 0 inter和PVD interrupt though EXTI line 16勾选上

3.对GPIO进行配置:选上升沿触发,下拉

4.然后在main.c中编写


/* USER CODE BEGIN PV */

int pwm_value = 0;

/* USER CODE END PV */

然后在/* USER CODE BEGIN 4 */和/* USER CODE END 4 */之间写入

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if(GPIO_Pin ==GPIO_PIN_0)
    {
        pwm_value++;
    }
}

最后在main中的while中写入

      pwm_value = 0;
      HAL_Delay(1000);
      printf("pwm_value -> %d Hz" , pwm_value );//user_main_info("pwm_value -> %d Hz" , pwm_value );

可以使用后面的封装好的函数但是(可能会有报错)   

### STM32CubeMX 学习教程和笔记 #### GPIO操作基础 对于初学者而言,了解如何通过STM32CubeMX配置通用输入输出端口(GPIO)是非常重要的。这不仅限于简单的高低电平控制,还包括更复杂的外设交互功能。例如,在GPIO输出方面,可以通过设置LED来创建跑马灯效果[^1];而在输入部分,则能实现外部中断触发以及按键消抖等功能。 #### 定时器应用实例 定时器是嵌入式系统中不可或缺的一部分。利用STM32CubeMX可以轻松完成基本的计数、延时任务,并进一步探索高级特性如PWM信号生成用于模拟呼吸灯光效。此外,还介绍了如何运用定时器中断机制提高程序响应速度与效率。 #### 串行通信接口实践指南 针对USART(Universal Synchronous/Asynchronous Receiver Transmitter),即通用同步异步接收发送器的学习材料也十分详尽。除了讲解标准的数据传输流程外,还有关于`printf()`函数重定向至UART的具体方法介绍。更重要的是,当涉及到大量数据交换场景时,DMA (Direct Memory Access) 技术的应用使得整个过程更加高效稳定。 #### 模拟量处理技术解析 ADC (Analog-to-Digital Converter,模数转换器) 和 DAC (Digital-to-Analog Converter, 数模转换器) 是两个非常实用的功能模块。前者允许设备感知外界连续变化的信息源,后者则负责将内部产生的离散数值映射回物理世界中的电信号形式。两者结合起来可以在不需要额外硬件支持的情况下构建简易测量仪器或控制系统。 #### I2C总线协议入门指导 I2C是一种广泛应用于各种传感器之间的两线制串行通讯方式。通过对EERPOM存储芯片AT24C02的操作练习,读者能够掌握发起读写请求的基本步骤;而后续章节里有关环境监测元件SHT20温度湿度采集的例子更是直观展示了实际项目里的应用场景。 #### 用户代码编写注意事项 值得注意的一点是在使用STM32CubeMX自动生成框架的基础上添加个人逻辑时需格外小心。任何位于特定标记之外编写的语句都可能在下一次更新过程中被覆盖掉。因此建议始终遵循官方推荐的最佳实践,即将新增内容放置于预定义区域内[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值