赞
踩
关于合泰HT32F52352多路pwm的控制,困了几天,今天终于得到解决,不得不说合泰的相关资料太少了,并且很多博主分享的可能和我们的芯片型号不同差别还是有点大的,ht32f52352的使用倒和stm32形式上很像,所以在学习过程中,对于一些外设的控制我们同样可以借鉴一下stm32的使用规则,然后进行相关的修改。下面会以PWM产生和捕捉定时器(GPTM) 控制四路舵机进行分享,希望可以帮助到正在学习HT32的小伙伴们。
其他博主的分享
实验效果
ht32多路舵机控制
话规正题
前面已分享了基本定时器的使用,以及定时器的分类,这里就不在重复需要的小伙伴,同样对于舵机的控制在stm32多路舵机控制也有讲,使用方法是一模一样的只是调用函数和传参不同,进行移植还是很通用的,请前往另两篇博文
stm32多路舵机控制
ht32f52352基本定时器的使用
下面先给出GPTM定时器的配置然后进行相应的分析
这是我使用的是GPIOA 4/5/6/7引脚GPTM0进行配置的,很多引脚都可以进行配置 大家根据数据手册进行配置就好了
time.h
#ifndef _TIME_H_
#define _TIME_H_
#include "ht32f5xxxx_bftm.h"
#define HTGPIO_PIN (GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7)
void GPTM_PWM_init();
void Servo_Run(uint16_t angle);
void Servo_Run2(uint16_t angle);
void Servo_Run3(uint16_t angle);
void Servo_Run4(uint16_t angle);
#endif
time.c
从下面初始化函数中 不难看出Ht32GPTM pwm配置的时候和stm32真的很像,只是配置名称不同,所以如果有一定的32基础下面代码还是很容易看懂的
#include "time.h" #include "delay.h" //输出四路PWM波控制后轮两个电机 //arr:自动重装值 //psc:时钟预分频数 //GT0 PA4 PA5 PA6 PA7 //产生一个20ms 定时周期 void GPTM_PWM_init() { TM_TimeBaseInitTypeDef TimeBaseIniture; //结构体 TM_OutputInitTypeDef OutIniture; CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}}; CKCUClock.Bit.PA = 1; //GPIOA时钟打开 CKCUClock.Bit.AFIO = 1; //复用时钟 CKCUClock.Bit.GPTM0 = 1; CKCU_PeripClockConfig(CKCUClock, ENABLE); //时钟使能 AFIO_GPxConfig(GPIO_PA, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, AFIO_MODE_4); //开启复用功能 GPIO_DirectionConfig(HT_GPIOA,HTGPIO_PIN,GPIO_DIR_OUT); TM_ClearFlag(HT_GPTM0, TM_FLAG_UEV); //清除更新中断标志 TM_OutputStructInit(&OutIniture); //填写每个变量的默认值 //定时器时基以及计数方式初始化 TimeBaseIniture.CounterMode = TM_CNT_MODE_UP; //边沿对齐向上模式 TimeBaseIniture.CounterReload = 200-1; //计数重装载计数器 TimeBaseIniture.Prescaler = 4800 -1; //预分频系数 TimeBaseIniture.PSCReloadTime=TM_PSC_RLD_IMMEDIATE; //立即重装载 TM_TimeBaseInit(HT_GPTM0,&TimeBaseIniture); // 0通道输出 PA4 OutIniture.Channel= TM_CH_0; OutIniture.Control= TM_CHCTL_ENABLE; //GPTM通道使能 OutIniture.OutputMode=TM_OM_PWM1 ; //GPTM 通道 PWM1输出模式 PWM2模式翻转 OutIniture.Polarity= TM_CHP_INVERTED; //GPTM 通道极性是低电平或下降沿 // OutIniture.Compare=200; // 这个是配置占空比的 TM_OutputModeConfig(HT_GPTM0,TM_CH_0,TM_OM_PWM1); TM_OutputInit(HT_GPTM0,&OutIniture); // 1通道输出 PA5 OutIniture.Channel=TM_CH_1; OutIniture.Control=TM_CHCTL_ENABLE; //GPTM通道使能 OutIniture.OutputMode=TM_OM_PWM1; //GPTM 通道 PWM1输出模式 PWM2模式翻转 OutIniture.Polarity=TM_CHP_INVERTED; //GPTM 通道极性是低电平或下降沿 //OutIniture.Compare=200; // 这个是配置占空比的 TM_OutputModeConfig(HT_GPTM0,TM_CH_1,TM_OM_PWM1); TM_OutputInit(HT_GPTM0,&OutIniture); // 2通道输出 PA6 OutIniture.Channel=TM_CH_2; OutIniture.Control=TM_CHCTL_ENABLE; //GPTM通道使能 OutIniture.OutputMode=TM_OM_PWM1; //GPTM 通道 PWM1输出模式 PWM2模式翻转 OutIniture.Polarity=TM_CHP_INVERTED; //GPTM 通道极性是低电平或下降沿 //OutIniture.Compare=200; // 这个是配置占空比的 TM_OutputModeConfig(HT_GPTM0,TM_CH_2,TM_OM_PWM1); TM_OutputInit(HT_GPTM0,&OutIniture); // 3通道输出 PA7 OutIniture.Channel=TM_CH_3; OutIniture.Control=TM_CHCTL_ENABLE; //GPTM通道使能 OutIniture.OutputMode=TM_OM_PWM1; //GPTM 通道 PWM1输出模式 PWM2模式翻转 OutIniture.Polarity=TM_CHP_INVERTED; //GPTM 通道极性是低电平或下降沿 // OutIniture.Compare=200; // 这个是配置占空比的 TM_OutputModeConfig(HT_GPTM0,TM_CH_3,TM_OM_PWM1); TM_OutputInit(HT_GPTM0,&OutIniture); TM_IntConfig(HT_GPTM0, TM_INT_CH0CC|TM_INT_CH1CC|TM_INT_CH2CC|TM_INT_CH3CC, ENABLE); //中断 TM_Cmd(HT_GPTM0,ENABLE); //使能计数 } /** * 功能:舵机驱动(可从0~180,每45度旋转一次) * 参数:angle ;舵机旋转度数(相对角度) * 返回值:None */ void Servo_Run(uint16_t angle) { switch(angle) { case 180 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_0,175); break;//对应180度 case 135 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_0,180); break;//对应135度 case 90 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_0,185); break;//对应90度 case 45 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_0,190); break;//对应45度 case 0 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_0,195); break;//对应0度 } } void Servo_Run2(uint16_t angle) { switch(angle) { case 180 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_1,175); break;//对应180度 case 135 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_1,180); break;//对应135度 case 90 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_1,185); break;//对应90度 case 45 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_1,190); break;//对应45度 case 0 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_1,195); break;//对应0度 } } void Servo_Run3(uint16_t angle) { switch(angle) { case 180 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_2,175); break;//对应180度 case 135 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_2,180); break;//对应135度 case 90 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_2,185); break;//对应90度 case 45 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_2,190); break;//对应45度 case 0 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_2,195); break;//对应0度 } } void Servo_Run4(uint16_t angle) { switch(angle) { case 180 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_3,175); break;//对应180度 case 135 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_3,180); break;//对应135度 case 90 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_3,185); break;//对应90度 case 45 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_3,190); break;//对应45度 case 0 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_3,195); break;//对应0度 } }
main.c
#include "ht32.h" #include "ht32_board.h" #include "led.h" #include "delay.h" #include "uart.h" #include "time.h" /******************TH32 定时器GPTM多路舵机控制******************* Author:小殷 Date:2022-4-28 ***************************************************************/ int main() { Led_Init(); USARTx_Init(); GPTM_PWM_init(); Servo_Run(45); printf("---------pwm Test------\n"); while(1) { Servo_Run(0); delay_ms(500); Servo_Run(45); delay_ms(500); Servo_Run2(0); delay_ms(500); Servo_Run2(45); delay_ms(500); Servo_Run3(0); delay_ms(500); Servo_Run3(45); delay_ms(500); Servo_Run4(0); delay_ms(500); Servo_Run4(45); delay_ms(500); } }
所需函数分析
1.首先配置我们所需的时钟、GPIO、端口复用、定时器时钟 CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}}; CKCUClock.Bit.PA = 1; //GPIOA时钟打开 CKCUClock.Bit.AFIO = 1; //复用时 CKCUClock.Bit.GPTM0 = 1; CKCU_PeripClockConfig(CKCUClock, ENABLE); //时钟使能 AFIO_GPxConfig(GPIO_PA, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, AFIO_MODE_4); //开启复用功能 GPIO_DirectionConfig(HT_GPIOA,HTGPIO_PIN,GPIO_DIR_OUT); /************************定时器结构体配置*******************/ typedef struct { TM_CH_Enum Channel; /*!< Channel selection refer to \ref TM_CH_Enum */ TM_OM_Enum OutputMode; /*!< Channel output mode selection refer to \ref TM_OM_Enum */ TM_CHCTL_Enum Control; /*!< CHxO output state refer to \ref TM_CHCTL_Enum */ TM_CHCTL_Enum ControlN; /*!< CHxO output state refer to \ref TM_CHCTL_Enum */ TM_CHP_Enum Polarity; /*!< CHxO polarity refer to \ref TM_CHP_Enum */ TM_CHP_Enum PolarityN; /*!< CHxO polarity refer to \ref TM_CHP_Enum */ MCTM_OIS_Enum IdleState; /*!< CHxO polarity refer to \ref TM_CHP_Enum */ MCTM_OIS_Enum IdleStateN; /*!< CHxO polarity refer to \ref TM_CHP_Enum */ u16 Compare; /*!< Value for CHxCCR register */ u16 AsymmetricCompare; /*!< Value for CHxCCR register */ } TM_OutputInitTypeDef; //配置完成后初始化函数 void TM_TimeBaseInit(HT_TM_TypeDef* TMx, TM_TimeBaseInitTypeDef* TimeBaseInit) /对于定时器的配置我们只需配置下面这几个参数就好,具体模式大家根据自己来就行 //定时器时基以及计数方式初始化 TimeBaseIniture.CounterMode = TM_CNT_MODE_UP; //边沿对齐向上模式 TimeBaseIniture.CounterReload = 200-1; //计数重装载计数器 TimeBaseIniture.Prescaler = 4800 -1; //预分频系数 TimeBaseIniture.PSCReloadTime=TM_PSC_RLD_IMMEDIATE; //立即重装载 TM_TimeBaseInit(HT_GPTM0,&TimeBaseIniture); /***********************输出比较PWM配置结构体*********************/ typedef struct { TM_CH_Enum Channel; /*!< Channel selection refer to \ref TM_CH_Enum */ TM_OM_Enum OutputMode; /*!< Channel output mode selection refer to \ref TM_OM_Enum */ TM_CHCTL_Enum Control; /*!< CHxO output state refer to \ref TM_CHCTL_Enum */ TM_CHCTL_Enum ControlN; /*!< CHxO output state refer to \ref TM_CHCTL_Enum */ TM_CHP_Enum Polarity; /*!< CHxO polarity refer to \ref TM_CHP_Enum */ TM_CHP_Enum PolarityN; /*!< CHxO polarity refer to \ref TM_CHP_Enum */ MCTM_OIS_Enum IdleState; /*!< CHxO polarity refer to \ref TM_CHP_Enum */ MCTM_OIS_Enum IdleStateN; /*!< CHxO polarity refer to \ref TM_CHP_Enum */ u16 Compare; /*!< Value for CHxCCR register */ u16 AsymmetricCompare; /*!< Value for CHxCCR register */ } TM_OutputInitTypeDef; void TM_OutputModeConfig(HT_TM_TypeDef* TMx, TM_CH_Enum Channel, TM_OM_Enum Mod); void TM_OutputInit(HT_TM_TypeDef* TMx, TM_OutputInitTypeDef* OutInit); //同样对于这个结构体的配置我们也只需配置以下参数就可以了 和相关输出初始化函数 OutIniture.Channel= TM_CH_0; OutIniture.Control= TM_CHCTL_ENABLE; //GPTM通道使能 OutIniture.OutputMode=TM_OM_PWM1 ; //GPTM 通道 PWM1输出模式 PWM2模式翻转 OutIniture.Polarity= TM_CHP_INVERTED; //GPTM 通道极性是低电平或下降沿 TM_OutputModeConfig(HT_GPTM0,TM_CH_0,TM_OM_PWM1); TM_OutputInit(HT_GPTM0,&OutIniture); //上面两个结构体配置完成后 记得一定要使能定时器 void TM_IntConfig(HT_TM_TypeDef* TMx, u32 TM_INT, ControlStatus NewState); void TM_Cmd(HT_TM_TypeDef* TMx, ControlStatus NewState);
大家配置的时候一定要仔细检查有没有漏掉的我自己在配置的时候
GPIO_DirectionConfig(HT_GPIOA,HTGPIO_PIN,GPIO_DIR_OUT);
就把GPIO输出的配置给漏掉了 搞了好久才发现这个错误
加油耶
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。