舵机驱动——STM32F407ZGT6探索者——HAL库

1、材料准备

  开发板:正点原子STM32F407ZGT6探索者

  舵机:SG90

  舵机线材分辨:褐色 / 红色 / 橘黄色 —— GND / VCC / PWM_signal

  与开发板接线:褐色 / 红色 / 橘黄色 —— GND / +5V / PF6(任选的PF6)

2、知识准备

  2.1、舵机需要的信号频率为50HZ,对应周期是 0.02 ,所以 arr 设置为 20000 -1 ,psc 设置为 168-1,原因是这么设置可刚好按如下算出频率是50HZ;

  2.2、定时器工作频率 Ft = 84 MHz ,单位:Mhz,来源:此次任选采用PF6针脚,而PF6可重映射到TIM10_CH1,而TIM10挂载在APB2上,APB2上的定时器时钟频率是168HZ(前提是这块开发板的SYSCLK直接设置到最大频率168MHz)。还想看168的图解来源请直接打开CuceMX或CubeIDE在“时钟树配置栏目”看到。

  2.3、计算方法

  定时器溢出时间计算方法: Tout = ( (arr + 1) * (psc + 1) ) / Ft us.

  周期 = (2 0000 * 168)/ (168 000 000) = 0.02 秒;

  频率 = 1 / 周期 = 50 HZ ;

3、代码块

gtim.h

 #ifndef __GTIM_H
 #define __GTIM_H
 ​
 #include "./SYSTEM/sys/sys.h"
 ​
 /*********************************以下是通用定时器PWM输出实验相关宏定义*************************************/
 ​
 /* TIMX PWM输出定义
  * 这里输出的PWM控制LED0(RED)的亮度 , 或控制别的,如舵机
  * 默认是针对TIM2~TIM5
  * 注意: 通过修改这几个宏定义,可以支持TIM1~TIM8任意一个定时器,任意一个IO口输出PWM
  */
 #define GTIM_TIMX_PWM_CHY_GPIO_PORT         GPIOF
 #define GTIM_TIMX_PWM_CHY_GPIO_PIN         GPIO_PIN_6
 #define GTIM_TIMX_PWM_CHY_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOF_CLK_ENABLE(); }while(0)  /* PF口时钟使能 */
 #define GTIM_TIMX_PWM_CHY_GPIO_AF           GPIO_AF3_TIM10                               /* 端口复用到TIM10,舵机用 */
 ​
 ​
 /* TIMX REMAP设置
  * 因为外设接在例如PF6上, 必须通过开启TIM10的部分重映射功能, 才能将TIM10_CH1输出到PF6上
  */
 #define GTIM_TIMX_PWM                       TIM10                                        /* TIMx */
 #define GTIM_TIMX_PWM_CHY                   TIM_CHANNEL_1                                /* 通道Y, 1<= Y <=4 */
 #define GTIM_TIMX_PWM_CHY_CCRX             TIM10->CCR1                                  /* 通道Y的输出比较寄存器 */
 #define GTIM_TIMX_PWM_CHY_CLK_ENABLE()     do{ __HAL_RCC_TIM10_CLK_ENABLE(); }while(0)  /* TIMx 时钟使能 */
 ​
 /****************************************************************************************************/
 ​
 void gtim_timx_pwm_chy_init(uint16_t arr, uint16_t psc);    /* 通用定时器 PWM初始化函数 */
 ​
 #endif

gtim.c

 #include "./BSP/TIMER/gtim.h"
 ​
 TIM_HandleTypeDef g_timx_pwm_chy_handle;     /* 定时器x句柄 */
 ​
 /**
  * @brief       通用定时器TIM 10 通道 1 PWM输出 初始化函数(使用PWM模式1)
  * @note
  *             通用定时器的时钟来自APB2
  *             通用定时器的时钟为APB2时钟的2倍, 而APB2为84 MHZ, 所以定时器时钟 = 168Mhz
  *             定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
  *             Ft = 定时器工作频率,单位:Mhz
  *
  * @param       arr: 自动重装值
  * @param       psc: 预分频系数
  * @retval     无
  */
 void gtim_timx_pwm_chy_init(uint16_t arr, uint16_t psc)
 {
     TIM_OC_InitTypeDef timx_oc_pwm_chy = {0};                       /* 定时器输出句柄 */
     
     g_timx_pwm_chy_handle.Instance = GTIM_TIMX_PWM;                 /* 定时器10 */
     g_timx_pwm_chy_handle.Init.Prescaler = psc;                     /* 预分频系数 */
     g_timx_pwm_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP;    /* 递增计数模式 */
     g_timx_pwm_chy_handle.Init.Period = arr;                        /* 自动重装载值 */
     HAL_TIM_PWM_Init(&g_timx_pwm_chy_handle);                       /* 初始化PWM */
 ​
     timx_oc_pwm_chy.OCMode = TIM_OCMODE_PWM1;                       /* 模式选择PWM1 */
     timx_oc_pwm_chy.Pulse = 0;                               /* 设置CCR比较值,此值用来确定占空比 */
 ​
     timx_oc_pwm_chy.OCPolarity = TIM_OCPOLARITY_HIGH;                                        /* 输出比较极性为HIGH */
     HAL_TIM_PWM_ConfigChannel(&g_timx_pwm_chy_handle, &timx_oc_pwm_chy, GTIM_TIMX_PWM_CHY); /* 配置TIM10通道1 */
     HAL_TIM_PWM_Start(&g_timx_pwm_chy_handle, GTIM_TIMX_PWM_CHY);                           /* 开启对应PWM通道 */
 }
 ​
 ​
 /**
  * @brief       定时器底层驱动,时钟使能,引脚配置
                 此函数会被HAL_TIM_PWM_Init()调用
  * @param       htim:定时器句柄
  * @retval     无
  */
 void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
 {
     if (htim->Instance == GTIM_TIMX_PWM)     /* htim->Instance定时器基地址 */
    {
         GPIO_InitTypeDef gpio_init_struct;
 
         GTIM_TIMX_PWM_CHY_GPIO_CLK_ENABLE();                            /* 开启通道1的CPIO时钟 */
         GTIM_TIMX_PWM_CHY_CLK_ENABLE();                                 /* 使能定时器时钟 */
 ​
         gpio_init_struct.Pin = GTIM_TIMX_PWM_CHY_GPIO_PIN;              /* 通道1的GPIO口 */
         gpio_init_struct.Mode = GPIO_MODE_AF_PP;                        /* 复用推挽输出 */
         gpio_init_struct.Pull = GPIO_PULLUP;                            /* 上拉 */
         gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;             /* 高速 */
         gpio_init_struct.Alternate = GTIM_TIMX_PWM_CHY_GPIO_AF;         /* IO口REMAP设置, 是否必要查看头文件配置的说明! */
         
  HAL_GPIO_Init(GTIM_TIMX_PWM_CHY_GPIO_PORT, &gpio_init_struct);
    }
 }

main.c

 #include "./SYSTEM/sys/sys.h"
 #include "./SYSTEM/usart/usart.h"
 #include "./SYSTEM/delay/delay.h"
 #include "./BSP/LED/led.h"
 #include "./BSP/TIMER/gtim.h"
 ​
 extern TIM_HandleTypeDef g_timx_pwm_chy_handle; /* 定时器x句柄 */
 ​
 int main(void)
 {                                                
 ​
     uint16_t pwm_val = 0; /* pwm value ,动态调节占空比时用到*/
     
     HAL_Init();                                 /* 初始化HAL库,必选 */
     sys_stm32_clock_init(336, 8, 2, 7);         /* 设置时钟,168Mhz,必选 */
     delay_init(168);                            /* 延时初始化,必选 */
     usart_init(115200);                         /* 串口初始化为115200,可选*/
     led_init();                                 /* 初始化 LED ,可选*/
 ​
     gtim_timx_pwm_chy_init(20000- 1, 168 - 1);  //20000*168/168000000=0.02s
     
  delay_ms(10);
  LED0(0); /* 上电后程序运行提示 */
  delay_ms(10);
 
     while (1)
    {
  pwm_val =1500;       /* 1500对应约90度,前提是将指针拨到与机身长边平行 */
         __HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, GTIM_TIMX_PWM_CHY, pwm_val);  /* 修改比较值控制占空比 */ delay_ms(1000);
 
  pwm_val = 500;      
         __HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, GTIM_TIMX_PWM_CHY, pwm_val);  /* 修改比较值控制占空比 */
  delay_ms(1000);
 
  pwm_val = 1500;      
         __HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, GTIM_TIMX_PWM_CHY, pwm_val);  /* 修改比较值控制占空比 */
  delay_ms(1000);
 
  pwm_val = 2500;      
         __HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, GTIM_TIMX_PWM_CHY, pwm_val);  /* 修改比较值控制占空比 */
  delay_ms(1000);
    }
 }

4、注释:

此块代码可以直接拿去用,也可以按照需求改 main.c 里 while(1) 里面的语句完成自定义控制。

看完请点赞,小手一点,水逆退散!!!

舵机驱动——STM32F407ZGT6探索者——HAL库的更多相关文章

  1. 【GMT43智能液晶模块】基于HAL库的SDRAM和LCD驱动例程(MDK工程&CubeMX工程)

    说明: 1.该工程基于HAL库实现动态存储器SDRAM驱动以及液晶控制器LCD驱动. 2.工程通过STM32CubeMX(Version 4.22.0)配置生成,可直接打开进行配置. 3.KEIL M ...

  2. 【安富莱】V6,V5开发板用户手册,重在BSP驱动包设计方法,HAL库的框架学习,授人以渔(2019-11-04)

    说明: 1.本教程重在BSP驱动包设计方法和HAL库的框架学习,并将HAL库里面的各种弯弯绕捋顺,从而方便我们的程序设计. 2.本次工程延续以往的代码风格,从底层BSP驱动包到应用代码,变量命名,文件 ...

  3. 【安富莱】STM32H7用户手册发布,重在BSP驱动包设计方法,HAL库的框架学习,授人以渔,更新至63章(2019-07-21)

    说明: 1.本教程重在BSP驱动包设计方法和HAL库的框架学习,并将HAL库里面的各种弯弯绕捋顺,从而方便我们的程序设计. 2.由于是基于HAL库的文档,所以不限制H7系列,其它F1,F2,F3,F4 ...

  4. 【春节歌曲回味 | STM32小音乐盒 】PWM+定时器驱动无源蜂鸣器(STM32 HAL库)

    l  STM32通过PWM与定时器方式控制无源蜂鸣器鸣响 l  STM32小音乐盒,歌曲进度条图形显示与百分比显示,歌曲切换 l  编程使用STM32 HAL库 l  IIC OLED界面编程,动画实 ...

  5. 【HAL库每天一例】freemodbus移植

    例程下载:资料包括程序.相关说明资料以及软件使用截图 百度云盘:https://pan.baidu.com/s/1slN8rIt 密码:u6m1 360云盘:https://yunpan.cn/OcP ...

  6. 【STM32H7教程】第12章 STM32H7的HAL库框架设计学习

    完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第12章       STM32H7的HAL库框架设计学 ...

  7. HAL库延时、SYCCNT与SYSTICK

    HAL库驱动中,由于某些外设的驱动需要使用超时判断(比如I2C.SPI.SDIO等),需要精确延时(精度为1ms),使用的是SysTick,但是在操作系统里面,我们需要使用SysTick来提供系统时基 ...

  8. STM32 软件模拟 IIC 代码,标准库、HAL库可用

    #ifndef _IIC_H #define _IIC_H #include "stdio.h" #include "stm32f1xx_hal.h" /* 定 ...

  9. 【STM32H7教程】第32章 STM32H7的TIM定时器基础知识和HAL库API

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第32章       STM32H7的TIM定时器基础知识和H ...

  10. 【STM32H7教程】第29章 STM32H7的USART串口基础知识和HAL库API

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第29章       STM32H7的USART串口基础知识和 ...

随机推荐

  1. github上传文件报错failed to push some refs解决

    报错内容,不能推送文件到github上 error: failed to push some refs to github地址 原因是github项目与本地文件夹一些关键文件的确实,比如.git,re ...

  2. JAVA小白找工作必备建议

    如果您是一名刚入门的JAVA小白,正在寻求工作机会,那么恭喜您来对地方!本文将为您提供一些建议,帮助您在求职过程中更好地展现自己的优势和准备迎接新的挑战. 1.基础知识打牢 在找工作前,务必确保您对J ...

  3. 【MAUI Blazor踩坑日记】2.关于Windows上的相机问题

    前言 本系列文章,默认你已经踏上了MAUI Blazor的贼船,并且对MAUI Blazor有了一些了解,知道MAUI是什么,知道Blazor是什么. 不会教你怎么写MAUI Blazor的项目,只是 ...

  4. AI识别检验报告 -PaddleNLP UIE-X 在医疗领域的实战

    目录 UIE-X在医疗领域的实战 1.项目背景 2.案例简介 3.环境准备 数据转换 5.模型微调 6.模型评估 7.Taskflow一键部署 UIE-X在医疗领域的实战 PaddleNLP全新发布U ...

  5. 如何用 Java 写一个 Java 虚拟机

    项目链接 https://github.com/FranzHaidnor/haidnorJVM haidnorJVM 使用 Java17 编写的 Java 虚拟机 意义 纸上得来终觉浅,绝知此事要躬行 ...

  6. Redis从入门到放弃(5):事务

    1.事务的定义 Redis的事务提供了一种"将多个命令打包, 然后一次性.按顺序地执行"的机制. redis事务的主要作用就是串联多个命令防止别的命令插队. 但是,事务并不具有传统 ...

  7. Java 生态需要新鲜的血液、需要狂飙的刺激。Solon v2.4.1 发布

    Solon 是什么开源项目? 一个,Java 新的生态型应用开发框架.它从零开始构建,有自己的标准规范与开放生态(历时五年,已有全球第二级别的生态规模).与其他框架相比,它解决了两个重要的痛点:启动慢 ...

  8. 搭建rsyncd服务

    前言 rsync常用来做文件传输和同步.本文示例中客户端通过rsync同步服务端的/home/tmp目录到本地(不是将客户端的文件同步到服务端). 环境信息 IP 系统版本 rsync版本 说明 19 ...

  9. Oracle表的导出、导入

    有些情况下,需要单独导出某些表,用或者分析数据. 下面记录Oracle表的导出导入方法 1. 表的导出 ./exp $username/$passwd@$ORACLE_SID file=/$file_ ...

  10. 群晖DS218+部署PostgreSQL(docker)

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 起因是懒 最近在开发中要用到PostgreSQL数据库 ...