首页 > 其他分享 >舵机驱动——STM32F407ZGT6探索者——HAL库

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

时间:2023-11-02 21:47:16浏览次数:39  
标签:PWM HAL STM32F407ZGT6 探索者 timx GTIM chy pwm TIMX

舵机驱动——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、注释:

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

  4.2、PF6 与  “ATK MODULE” 处插 “ WIFI模块——正点原子ATK ESP 01 ” 占用冲突,请务必取下WIFI模块再拷贝代码运行或者非要用WiFi模块那就不用PF6改用其他带定时器pwm输出的引脚。

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

标签:PWM,HAL,STM32F407ZGT6,探索者,timx,GTIM,chy,pwm,TIMX
From: https://www.cnblogs.com/salty-pineapple/p/17806387.html

相关文章

  • ScreenBar Halo:程序员的视觉守护者
    前言:在最近的一段时间内,我每天都沉浸在代码的世界中,然而,这样的密集工作导致我的眼睛开始感到不适。经过深思熟虑,我决定去医院进行一次全面的检查。医生严肃地告诉我,我需要适当休息,并减少长时间盯着电脑屏幕的行为。作为一位IT程序员,我要挣钱生活!必须每天进行的代码编写工作,我该如何......
  • DataWhale DAY8 结课竞赛
    DataWhaleDAY8结课竞赛今天是结课竞赛,当游记写了。其实题目本身没什么好写的,都是一些基础题。唯一有意思的是使用python进行的简化。以前做那道字符串的题还比较繁琐,这次利用打包好的功能可以直接秒。顺便感慨自己的码力下降了不少,老是在一些小地方写错。最后的结果是T2WA......
  • STM32基于HAL库流水灯实验
    一、搭建STM32的开发环境(一)安装jdk由于STM32CubeMX是Java实现的,需要安装jdk环境。jdk官网下载链接:https://www.oracle.com/java/technologies/javase-downloads.html(二)安装STM32CubeMX1.下载地址:https://www.st.com/en/development-tools/stm32cubemx.html2.安装过程1.以管理员身......
  • GLNexus进行joint calling时的"half-calls"(如./0, ./1)问题
    目录关于GLNexus由于重叠变异产生的half-callsGATKjointcalling对于half-calls的处理建议处理关于GLNexusGLnexus是由DNAnexus开发,用于可扩展的gVCF合并和联合变异(jointcalling)要求群体测序项目,GL即genotypelikelihood之意。GATK作为变异检测金标准软件,缺点在于速度很慢。尽管......
  • diffusion扩散模型\datawhale组队学习——v3先运行一半(下)
    微调:好像是用新数据训练旧模型的管道。微调的参数有:图形大小:image_size数据批次:batch_size为减轻显卡压力,将数据批次再切分为2(n)倍,num_epochs相对应的,权重更新频率也乘2(n)倍,grad_accumulation_steps总感觉对模型影响不大捏?难道是为了加大图形质量和效果,就相应地延长训练时......
  • DataWhale DAY6 循环
    DataWhaleDAY6循环今天学习循环方面的知识。语法部分:https://www.cnblogs.com/hewo/p/17635277.html感觉python的for是真的像自然语言。range:​range(stop)#[0,stop)range(start,stop)#[start,stop)range(start,stop,step)#+=step关于while和for(其......
  • 关于STM32F407ZGT6的USB损坏后使用ST-Link和USART1实现串口功能
    开发板:STM32F407ZGT6;目标:想使用软件“串口调试助手”情况:开发板上的USB_UART口所在器件损坏或者直接没有;解决办法:查看该开发板的原理图,可得:串口1的RX接TXD,串口1的TX接RXD,那么按如下步骤操作:1、现在使用USB转TTL模块,将串口1的RX接USB转TTL模块的TXD,将串口1的TX接USB转TTL模块的R......
  • Hall定理(霍尔定理)证明及推广
    引言网络上有许多Hall定理的证明,但是对于Hall定理的几个推广的介绍却少之又少,因此本文来简单介绍一下注:为了使这篇文章看起来简单易懂,本文将不会使用图论语言,会图论的朋友们可以自行翻译为图论语言。背景:在遥远的地方有一个神奇国家,这个国家有n个男生和m个女生(n  m)。每个男......
  • diffusion扩散模型\datawhale组队学习——v3先运行一半
    今天我们一起学习如何对模型微调和引导。微调,用原模型,跑新数据,得到新输出。引导,引导生成过程,改变输出结果。 作者之前用过sd模型,不同的采样方法在不同的采样步数下有不同的效果。首先采样步数并非越高越好或越低越好,有一个最佳使用区间,其次,不同采样方法有自己不同的最佳采样......
  • DataWhale DAY5 条件语句
    DataWhaleDAY5条件语句本次学习python中的条件语句。语法博客:https://www.cnblogs.com/hewo/p/17635277.html注意点位:1.减少炫技般的使用特殊方法的判断,从理解方面简化你的代码,对于python,没有必要时不用使用奇技淫巧优化。对于true/false和0/1:​ 首先,bool是int的......