Hi all,
I have a university project. I have code to control servo SG90 by timer. It works, but not accurate. The servo just rotates from 0 to 100 (from the right to the center) , so it is unsuitable for the project. In this code, I want to set 40MHz to synchronize to PWM hardware, which is used to control other servos. Can you help me? This is my code.
Thanks.
#include <stdint.h> #include <stdbool.h> #include "stdlib.h" #include "inc/tm4c123gh6pm.h" #include "inc/hw_memmap.h" #include "inc/hw_uart.h" #include "inc/hw_gpio.h" #include "inc/hw_timer.h" #include "inc/hw_types.h" #include "driverlib/pin_map.h" #include "driverlib/rom.h" #include "driverlib/rom_map.h" #include "driverlib/debug.h" #include "driverlib/systick.h" #include "driverlib/interrupt.h" #include "driverlib/sysctl.h" #include "driverlib/uart.h" #include "driverlib/udma.h" #include "driverlib/gpio.h" #include "driverlib/timer.h" #include <string.h> #define RESOLUTION 10 #define MIN_RANGE 600 #define MAX_RANGE 2400 #define DELAYTIME 300 /* #define FREQ 50 #define PERIOD 40000000/FREQ #define PULSE 40 */ uint32_t pulse, Period; void ServoWrite(int32_t angle) { uint32_t duty; duty = pulse * (( (angle * RESOLUTION) + MIN_RANGE)); TimerMatchSet(TIMER3_BASE, TIMER_A, duty-1); } void delayMS(uint32_t ms) { SysCtlDelay( (SysCtlClockGet()/(3*1000))*ms ) ; } int main(void) { uint32_t dutyCycle; SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); pulse = (SysCtlClockGet() / 1000000 ) ; //the number of pulse per microsecond Period = pulse * 20000; //20ms dutyCycle = pulse * (((90 * RESOLUTION) + MIN_RANGE)); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); GPIOPinConfigure(GPIO_PB2_T3CCP0); GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_2); SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER3); TimerConfigure(TIMER3_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_A_PWM); TimerControlLevel(TIMER3_BASE, TIMER_A, true); TimerPrescaleSet(TIMER3_BASE, TIMER_A, 12); TimerLoadSet(TIMER3_BASE, TIMER_A, Period - 1); TimerMatchSet(TIMER3_BASE, TIMER_A, dutyCycle -1); TimerEnable(TIMER3_BASE, TIMER_A); uint32_t i=0; while(1){ for(i = 1; i < 110; i++) { ServoWrite(i); delayMS(20); } delayMS(1000); for(i = 110-1; i > 0; i--) { ServoWrite(i); delayMS(20); } } }