9
« Last post by jlsilicon on Today at 03:22:00 am »
I am looking to drive SG90 Servor Motors - using PWM on Ch32v003 / Sg32v103 .
Any ideas ?
I pulled some Ch32v103 PWM MG996 driving code off of foreign sites.
But it does not give functional examples.
-- End notes are from the site - not me.
/*
- Compiles
*/
/*
*@Note
USART Print debugging routine:
USART1_Tx(PA9).
This example demonstrates using USART1(PA9) as a print debug port output.
*/
#include "debug.h"
///
// CH32V103_MG996R servo driver
// ch32v103 tim_pwmout_init(tim3_ch1);
// CH32V103_MG996R servo driver
// TIM PWM initialization
#define PWM_MODE PWM_MODE2
#define ARR 60000 //60000
#define TIM3_CH4 0x34
#define TIM3_CH3 0x33
#define TIM3_CH2 0x32
#define TIM3_CH1 0x31
#define TIM2_CH3 0x23
#define TIM2_CH4 0x24
#define PWM_MODE1 0
#define PWM_MODE2 1
void TIM_PWMOut_Init(uint8_t type)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
switch(type)
{
case TIM3_CH4:
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE ); //Enable GPIO peripherals and AFIO multiplexing function module clock enable
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOC, &GPIO_InitStructure );
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE );
break;
case TIM3_CH3:
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE ); //Enable GPIO peripherals and AFIO multiplexing function module clock Enable
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOC, &GPIO_InitStructure );
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE );
break;
case TIM3_CH2:
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE ); //Enable GPIO peripherals and AFIO multiplexing function module clock enable
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOC, &GPIO_InitStructure );
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE );
break;
case TIM3_CH1:
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE ); //Enable GPIO peripherals and AFIO multiplexing function module clock enable
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOC, &GPIO_InitStructure );
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE );
break;
case TIM2_CH3:
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE ); //Enable GPIO peripherals and AFIO multiplexing function module clock enable
GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOB , &GPIO_InitStructure );
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE );
break;
case TIM2_CH4:
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE );//Enable GPIO peripherals and AFIO multiplexing function module clock enable
GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOB, &GPIO_InitStructure );
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE );
break;
default:
break;
}
TIM_TimeBaseInitStructure.TIM_Period = ARR; //Specify the period value to be loaded into the active automatic reload register the next time the event is updated.
TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1 ; // PSC; //Specify the prescaler value used to divide the TIM clock.
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
if( type > TIM2_CH4 )
TIM_TimeBaseInit( TIM3, &TIM_TimeBaseInitStructure);
else
TIM_TimeBaseInit( TIM2, &TIM_TimeBaseInitStructure);
#if (PWM_MODE == PWM_MODE1)
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
#elif (PWM_MODE == PWM_MODE2)
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
#endif
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0.5/20.0*ARR; //Specify the pulse value to be loaded into the capture compare register.
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
switch(type)
{
case TIM3_CH4:
TIM_OC4Init( TIM3, &TIM_OCInitStructure );
TIM_CtrlPWMOutputs(TIM3, ENABLE );
TIM_OC4PreloadConfig( TIM3, TIM_OCPreload_Disable );//TIM_OCPreload_Enable TIM_OCPreload_Disable
TIM_ARRPreloadConfig( TIM3, ENABLE );
TIM_Cmd( TIM3, ENABLE );
break;
case TIM3_CH3:
TIM_OC3Init( TIM3, &TIM_OCInitStructure );
TIM_CtrlPWMOutputs(TIM3, ENABLE );
TIM_OC3PreloadConfig( TIM3, TIM_OCPreload_Disable );//TIM_OCPreload_Enable TIM_OCPreload_Disable
TIM_ARRPreloadConfig( TIM3, ENABLE );
TIM_Cmd( TIM3, ENABLE );
//TIM_SetCompare3(TIM3,1600);
break;
case TIM3_CH2:
TIM_OC2Init( TIM3, &TIM_OCInitStructure );
TIM_CtrlPWMOutputs(TIM3, ENABLE );
TIM_OC2PreloadConfig( TIM3, TIM_OCPreload_Disable );//TIM_OCPreload_Enable TIM_OCPreload_Disable
TIM_ARRPreloadConfig( TIM3, ENABLE );
TIM_Cmd( TIM3, ENABLE );
break;
case TIM3_CH1:
TIM_OC1Init( TIM3, &TIM_OCInitStructure );
TIM_CtrlPWMOutputs(TIM3, ENABLE );
TIM_OC1PreloadConfig( TIM3, TIM_OCPreload_Disable );//TIM_OCPreload_Enable TIM_OCPreload_Disable
TIM_ARRPreloadConfig( TIM3, ENABLE );
TIM_Cmd( TIM3, ENABLE );
break;
case TIM2_CH3:
TIM_OC3Init( TIM2, &TIM_OCInitStructure );
TIM_CtrlPWMOutputs(TIM2, ENABLE );
TIM_OC3PreloadConfig( TIM2, TIM_OCPreload_Disable );//TIM_OCPreload_Enable TIM_OCPreload_Disable
TIM_ARRPreloadConfig( TIM2, ENABLE );
TIM_Cmd( TIM2, ENABLE );
break;
case TIM2_CH4:
TIM_OC4Init( TIM2, &TIM_OCInitStructure );
TIM_CtrlPWMOutputs(TIM2, ENABLE );
TIM_OC4PreloadConfig( TIM2, TIM_OCPreload_Disable );//TIM_OCPreload_Enable TIM_OCPreload_Disable
TIM_ARRPreloadConfig( TIM2, ENABLE );
TIM_Cmd( TIM2, ENABLE );
break;
}
}
void Set_PWM_Dutycycle(uint16_t dutycycle,uint8_t type)
{
switch(type)
{
case TIM3_CH4:
TIM_SetCompare4(TIM3,dutycycle); //Set the TIM3 capture comparison 1 register value, which is used to modify the duty cycle
break;
case TIM3_CH3:
TIM_SetCompare3(TIM3,dutycycle); //Set the TIM3 capture Compare 1 register value, used to modify the duty cycle
break;
case TIM3_CH2:
TIM_SetCompare2(TIM3,dutycycle); //Set the TIM3 capture compare 1 register value, used to modify the duty cycle
break;
case TIM3_CH1:
TIM_SetCompare1(TIM3, dutycycle); //Set the TIM3 capture compare 1 register value, used to modify the duty cycle
break;
case TIM2_CH3:
TIM_SetCompare3(TIM2,dutycycle); //Set the TIM3 capture compare 1 register value, used to modify the duty cycle
break ;
case TIM2_CH4:
TIM_SetCompare4(TIM2,dutycycle); //Set the TIM3 capture comparison 1 register value, used to modify the duty cycle
break;
}
}
/*
Introduction The CH32V103 series is a 32-bit general-purpose MCU with the Qingdao
V3A processor as the core. The processor is designed based on the RISC-V open source instruction set. The clock safety mechanism, multi-level power management, and universal DMA controller are integrated on the chip. This series has rich peripheral resources such as 1-channel USB2.0 host/device interface, multi-channel 12-bit ADC conversion module, multi-channel TouchKey, multiple groups of timers, and multiple IIC/USART/SPI interfaces. This tutorial uses timer 1 channel 1 (PA8) to generate PWM through the PA8 pin to control the brightness of the LED light LED1. 1. Introduction to PWM and related functions Pulse width modulation ( PWM ) is an analog control method that uses microprocessors
Qinheng CH32V103 Play and Learn 1-Development Environment and GPIO Project
4-21
However, the library functions it uses are basically the same as STM32, and there is no difference in the core structure. You can quickly get started with library function development through this board and understand some simple concepts, such as GPIO ADC/DAC, watchdog timer interrupt, PWM and other core knowledge points. , it will be easier to convert to STM32 later. CH32V103 C8T6 has not yet received Qin...
RISC-V MCU application tutorial timer interrupt_risk-v systick
4-20
1.5. void TIM _ PWM IConfig ( TIM _TypeDef* TIM x, TIM _IC Init TypeDef* TIM _IC Init Struct) Function: Configure TIM peripherals according to the specified parameters in the TIM structure to measure external PWM signals. Input: TIM x: where x can be 1 to 4 to select the TIM peripheral; TIM _IC Init Struct: points to TIM _IC...
Qinheng CH32V307 usage record: using TIM to output PWM signal
Using TIM to output PWM signals is a commonly used function in microcontrollers. This article will explain the relevant content in CH32V307.
STM32 TIM3 outputs PWM signal to drive MG996R servo (button control)
3-30
timer_pwm_init(PWM3_CH1_C6,50,740);// //D2 gpio_init(D2,GPI,0,IN_PULLUP); // error=0; error_last=0; //
4-8
#include"ch32v10x.h" intw =0; volatileu8 flag=0; voidTIM3_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = {0}; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); ...
05-22
You can drive two MG996R servos by using one PWM output pin , but you need to pay attention to some issues:
1. The maximum operating frequency of each MG996R servo is 50Hz, that is, each cycle is 20ms, so it needs to be within one cycle Complete the PWM signal output of the two servos ;
2. The operating voltage of the MG996R servo is 4.8V~7.2V, so it is necessary to ensure that the supply voltage and current are sufficient to drive the two servos ;
3. If connected on the same pin For multiple servos , a signal distributor (such as a crystal oscillator) needs to be used to distribute the PWM signal to ensure that each servo can receive the correct PWM signal;
4. The appropriate PWM signal should be calculated based on the load characteristics of the servo . PWM duty cycle to ensure the stability and accuracy of the servo movement.
*/
///
/* Global Variable */
/*********************************************************************
* @fn main
*
* @brief Main program.
*
* @return none
*/
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
Delay_Init();
USART_Printf_Init(115200);
printf("SystemClk:%d\r\n", SystemCoreClock);
TIM_PWMOut_Init( TIM3_CH1 );
Set_PWM_Dutycycle( 1000 , TIM3_CH1 );
while(1)
{
}
}
///