合泰HT32F52352(GPTM)多路PWM控制
关于合泰HT32F52352多路pwm的控制,困了几天,今天终于得到解决,不得不说合泰的相关资料太少了,并且很多博主分享的可能和我们的芯片型号不同差别还是有点大的,ht32f52352的使用倒和stm32形式上很像,所以在学习过程中,对于一些外设的控制我们同样可以借鉴一下stm32的使用规则,然后进行相关的修改。下面会以PWM产生和捕捉定时器(GPTM) 控制四路舵机进行分享,希望可以帮助到正在学习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"
void GPTM_PWM_init()
{
TM_TimeBaseInitTypeDef TimeBaseIniture;
TM_OutputInitTypeDef OutIniture;
CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}};
CKCUClock.Bit.PA = 1;
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);
OutIniture.Channel= TM_CH_0;
OutIniture.Control= TM_CHCTL_ENABLE;
OutIniture.OutputMode=TM_OM_PWM1 ;
OutIniture.Polarity= TM_CHP_INVERTED;
TM_OutputModeConfig(HT_GPTM0,TM_CH_0,TM_OM_PWM1);
TM_OutputInit(HT_GPTM0,&OutIniture);
OutIniture.Channel=TM_CH_1;
OutIniture.Control=TM_CHCTL_ENABLE;
OutIniture.OutputMode=TM_OM_PWM1;
OutIniture.Polarity=TM_CHP_INVERTED;
TM_OutputModeConfig(HT_GPTM0,TM_CH_1,TM_OM_PWM1);
TM_OutputInit(HT_GPTM0,&OutIniture);
OutIniture.Channel=TM_CH_2;
OutIniture.Control=TM_CHCTL_ENABLE;
OutIniture.OutputMode=TM_OM_PWM1;
OutIniture.Polarity=TM_CHP_INVERTED;
TM_OutputModeConfig(HT_GPTM0,TM_CH_2,TM_OM_PWM1);
TM_OutputInit(HT_GPTM0,&OutIniture);
OutIniture.Channel=TM_CH_3;
OutIniture.Control=TM_CHCTL_ENABLE;
OutIniture.OutputMode=TM_OM_PWM1;
OutIniture.Polarity=TM_CHP_INVERTED;
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);
}
void Servo_Run(uint16_t angle)
{
switch(angle)
{
case 180 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_0,175); break;
case 135 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_0,180); break;
case 90 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_0,185); break;
case 45 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_0,190); break;
case 0 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_0,195); break;
}
}
void Servo_Run2(uint16_t angle)
{
switch(angle)
{
case 180 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_1,175); break;
case 135 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_1,180); break;
case 90 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_1,185); break;
case 45 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_1,190); break;
case 0 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_1,195); break;
}
}
void Servo_Run3(uint16_t angle)
{
switch(angle)
{
case 180 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_2,175); break;
case 135 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_2,180); break;
case 90 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_2,185); break;
case 45 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_2,190); break;
case 0 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_2,195); break;
}
}
void Servo_Run4(uint16_t angle)
{
switch(angle)
{
case 180 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_3,175); break;
case 135 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_3,180); break;
case 90 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_3,185); break;
case 45 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_3,190); break;
case 0 :TM_SetCaptureCompare(HT_GPTM0,TM_CH_3,195); break;
}
}
main.c
#include "ht32.h"
#include "ht32_board.h"
#include "led.h"
#include "delay.h"
#include "uart.h"
#include "time.h"
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;
CKCUClock.Bit.AFIO = 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;
TM_OM_Enum OutputMode;
TM_CHCTL_Enum Control;
TM_CHCTL_Enum ControlN;
TM_CHP_Enum Polarity;
TM_CHP_Enum PolarityN;
MCTM_OIS_Enum IdleState;
MCTM_OIS_Enum IdleStateN;
u16 Compare;
u16 AsymmetricCompare;
} 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);
typedef struct
{
TM_CH_Enum Channel;
TM_OM_Enum OutputMode;
TM_CHCTL_Enum Control;
TM_CHCTL_Enum ControlN;
TM_CHP_Enum Polarity;
TM_CHP_Enum PolarityN;
MCTM_OIS_Enum IdleState;
MCTM_OIS_Enum IdleStateN;
u16 Compare;
u16 AsymmetricCompare;
} 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;
OutIniture.OutputMode=TM_OM_PWM1 ;
OutIniture.Polarity= TM_CHP_INVERTED;
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输出的配置给漏掉了 搞了好久才发现这个错误
加油耶
|