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);
}
}
}