舵机型号:SM-S4306R
采用周期为20ms的PWM驱动,PWM脉宽在0.5ms-2.5ms之间;
舵机5V工作电压,电流80mA左右,板卡输出3.3V可直接驱动起来;
定时器时钟为40MHz/8=5MHz,使用PTM1的通道1作为PWM的输出通道,对应GPIO为PTA1;
脉宽为0.5ms~1.5ms时正转,值越小,旋转速度越大;
脉宽为1.5ms~2.5ms为反转,值越大,旋转速度越大;
脉宽为1.5ms时停止,实际不确定,例如可能是1510us;
在例程SDK_2.2_FRDM-KW41Z\boards\frdmkw41z\driver_examples\tpm\simple_pwm基础修改;
修改后pin_mux.c文件如下:
- #include "fsl_common.h"
- #include "fsl_port.h"
- #include "pin_mux.h"
- #define PIN6_IDX 6u /*!< Pin number for pin 6 in a port */
- #define PIN7_IDX 7u /*!< Pin number for pin 7 in a port */
- #define PIN1_IDX 1u /*!< Pin number for pin 1 in a port */
- #define SOPT4_TPM1CH1SRC_TPM 00 /*!< TPM1 Channel 1 Input Capture Source Select: TPM1_CH1 signal */
- #define SOPT5_LPUART0RXSRC_LPUART_RX 0x00u /*!< LPUART0 Receive Data Source Select: LPUART_RX pin */
- /*
- * TEXT BELOW IS USED AS SETTING FOR THE PINS TOOL *****************************
- BOARD_InitPins:
- - options: {coreID: singlecore, enableClock: 'true'}
- - pin_list:
- - {pin_num: '42', peripheral: LPUART0, signal: RX, pin_signal: TSI0_CH2/PTC6/LLWU_P14/XTAL_OUT_EN/I2C1_SCL/UART0_RX/TPM2_CH0/BSM_FRAME}
- - {pin_num: '43', peripheral: LPUART0, signal: TX, pin_signal: TSI0_CH3/PTC7/LLWU_P15/SPI0_PCS2/I2C1_SDA/UART0_TX/TPM2_CH1/BSM_DATA}
- - {pin_num: '6', peripheral: TPM2, signal: 'CH, 0', pin_signal: TSI0_CH12/PTA18/LLWU_P6/SPI1_SCK/TPM2_CH0}
- * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR THE PINS TOOL ***
- */
- /*FUNCTION**********************************************************************
- *
- * Function Name : BOARD_InitPins
- * Description : Configures pin routing and optionally pin electrical features.
- *
- *END**************************************************************************/
- void BOARD_InitPins(void) {
- CLOCK_EnableClock(kCLOCK_PortA); /* Port A Clock Gate Control: Clock enabled */
- CLOCK_EnableClock(kCLOCK_PortC); /* Port C Clock Gate Control: Clock enabled */
- PORT_SetPinMux(PORTA, PIN1_IDX, kPORT_MuxAlt5); /* PORTA18 (pin 6) is configured as TPM1_CH1 */
- PORT_SetPinMux(PORTC, PIN6_IDX, kPORT_MuxAlt4); /* PORTC6 (pin 42) is configured as UART0_RX */
- PORT_SetPinMux(PORTC, PIN7_IDX, kPORT_MuxAlt4); /* PORTC7 (pin 43) is configured as UART0_TX */
- SIM->SOPT4 = ((SIM->SOPT4 &
- (~(SIM_SOPT4_TPM1CLKSEL_MASK))) /* Mask bits to zero which are setting */
- | SIM_SOPT4_TPM1CLKSEL(SOPT4_TPM1CH1SRC_TPM) /* TPM1 Channel 1 Input Capture Source Select: TPM1_CH1 signal */
- );
- SIM->SOPT5 = ((SIM->SOPT5 &
- (~(SIM_SOPT5_LPUART0RXSRC_MASK))) /* Mask bits to zero which are setting */
- | SIM_SOPT5_LPUART0RXSRC(SOPT5_LPUART0RXSRC_LPUART_RX) /* LPUART0 Receive Data Source Select: LPUART_RX pin */
- );
- }
- main.c修改后如下:
- #include "fsl_debug_console.h"
- #include "board.h"
- #include "fsl_tpm.h"
- #include "pin_mux.h"
- /*******************************************************************************
- * Definitions
- ******************************************************************************/
- #define BOARD_TPM_BASEADDR TPM1
- #define BOARD_TPM_CHANNEL 1U
- /* Interrupt to enable and flag to read; depends on the TPM channel used */
- #define TPM_CHANNEL_INTERRUPT_ENABLE kTPM_Chnl0InterruptEnable
- #define TPM_CHANNEL_FLAG kTPM_Chnl0Flag
- /* Interrupt number and interrupt handler for the TPM instance used */
- #define TPM_INTERRUPT_NUMBER TPM1_IRQn
- #define TPM_LED_HANDLER TPM1_IRQHandler
- /* Get source clock for TPM driver */
- #define TPM_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_McgFllClk)
- /*******************************************************************************
- * Prototypes
- ******************************************************************************/
- /*!
- * @brief delay a while.
- */
- void delay(void);
- /*******************************************************************************
- * Variables
- ******************************************************************************/
- volatile bool brightnessUp = true; /* Indicate LED is brighter or dimmer */
- volatile uint8_t updatedDutycycle = 10U;
- volatile uint8_t getCharValue = 0U;
- /*******************************************************************************
- * Code
- ******************************************************************************/
- /*!
- * @brief Main function
- */
- int main(void)
- {
- tpm_config_t tpmInfo;
- tpm_chnl_pwm_signal_param_t tpmParam;
- tpm_pwm_level_select_t pwmLevel = kTPM_HighTrue;
- /* Configure tpm params with frequency 24kHZ */
- tpmParam.chnlNumber = (tpm_chnl_t)BOARD_TPM_CHANNEL;
- tpmParam.level = pwmLevel;
- tpmParam.dutyCyclePercent = updatedDutycycle;
- /* Board pin, clock, debug console init */
- BOARD_InitPins();
- BOARD_BootClockRUN();
- BOARD_InitDebugConsole();
- /* Select the clock source for the TPM counter as MCGPLLCLK */
- CLOCK_SetTpmClock(1U);
-
- PRINTF("\r\n CoreSysClk=%d MHz\r\n",CLOCK_GetFreq(kCLOCK_CoreSysClk)/1000000);
- // PRINTF("\r\n PlatClk=%d MHz\r\n",CLOCK_GetFreq(kCLOCK_PlatClk)/1000000);
- // PRINTF("\r\n BusClk=%d MHz\r\n",CLOCK_GetFreq(kCLOCK_BusClk)/1000000);
- // PRINTF("\r\n FlashClk=%d MHz\r\n",CLOCK_GetFreq(kCLOCK_FlashClk)/1000000);
- // PRINTF("\r\n Er32kClk=%d MHz \r\n",CLOCK_GetFreq(kCLOCK_Er32kClk)/1000000);
- // PRINTF("\r\n Osc0ErClk=%d MHz \r\n",CLOCK_GetFreq(kCLOCK_Osc0ErClk)/1000000);
- // PRINTF("\r\n McgInternalRefClk=%d MHz \r\n",CLOCK_GetFreq(kCLOCK_McgInternalRefClk)/1000000);
- PRINTF("\r\n McgFllClk=%d MHz \r\n",CLOCK_GetFreq(kCLOCK_McgFllClk)/1000000);
- // PRINTF("\r\n LpoClk=%d MHz \r\n",CLOCK_GetFreq(kCLOCK_LpoClk)/1000000);
-
- /* Print a note to terminal */
- PRINTF("\r\nTPM example to output center-aligned PWM signal\r\n");
- PRINTF("\r\nIf an LED is connected to the TPM pin, you will see a change in LED brightness if you enter different values");
- PRINTF("\r\nIf no LED is connected to the TPM pin, then probe the signal using an oscilloscope");
- TPM_GetDefaultConfig(&tpmInfo);
- tpmInfo.prescale=kTPM_Prescale_Divide_8;//40MHz/8
- /* Initialize TPM module */
- TPM_Init(BOARD_TPM_BASEADDR, &tpmInfo);
- if(kStatus_Success!=TPM_SetupPwm(BOARD_TPM_BASEADDR, &tpmParam, 1U, kTPM_CenterAlignedPwm, 50, TPM_SOURCE_CLOCK))
- {
- PRINTF("\r\n SetupPwm Error! \r\n");
- }
- TPM_StartTimer(BOARD_TPM_BASEADDR, kTPM_SystemClock);
- while (1)
- {
- do
- {
- PRINTF("\r\nPlease enter a value to update the Duty cycle:\r\n");
- PRINTF("Note: The range of value is 0 to 9.\r\n");
- PRINTF("For example: If enter '5', the duty cycle will be set to 50 percent.\r\n");
- PRINTF("Value:");
- getCharValue = GETCHAR() - 0x30U;
- PRINTF("%d", getCharValue);
- PRINTF("\r\n");
- } while (getCharValue > 9U);
- updatedDutycycle = getCharValue ;//20ms左右的脉冲,高电平0.5ms~1.5ms(updatedDutycycle为2.5~7.5)正转,值越小,旋转速度越大;1.5ms~2.5ms(updatedDutycycle为7.5~12.5)为反转,值越大,旋转速度越大;
- /* Disable channel output before updating the dutycycle */
- // TPM_UpdateChnlEdgeLevelSelect(BOARD_TPM_BASEADDR, (tpm_chnl_t)BOARD_TPM_CHANNEL, 0U);
- /* Update PWM duty cycle */
- TPM_UpdatePwmDutycycle(BOARD_TPM_BASEADDR, (tpm_chnl_t)BOARD_TPM_CHANNEL, kTPM_CenterAlignedPwm,updatedDutycycle);
- /* Start channel output with updated dutycycle */
- // TPM_UpdateChnlEdgeLevelSelect(BOARD_TPM_BASEADDR, (tpm_chnl_t)BOARD_TPM_CHANNEL, pwmLevel);
- PRINTF("The duty cycle was successfully updated!\r\n");
- }
- }
控制舵机还是很精确的:
另外试了下,频率可达到1M:
此内容由EEWORLD论坛网友dql2016原创,如需转载或用于商业用途需征得作者同意并注明出处