简介
SG90控制信号为周期是20ms 的PWM信号,正转高电平时间1-1.5ms,1ms最快,1.5ms停止。只要控制转速和时间就能控制角度。
生成50HZ信号,我采用REFOCLK作为辅助时钟ACLK的信号源。频率为32768HZ。将timerPeriod设置成660即可生成50HZ信号。当dutyCycle等于48时,舵机为最慢正转。
代码
#include "driverlib.h"
#include "stdio.h"
#include <string.h>
#include <stdarg.h>
static int a=0;
static int t=0;
static int b=0;
static int c=0;
static int angle=0;
static int word[];
static int length=0;
static int data;
void duoji(int x)
{
b=(x/5)+1;
Timer_A_startCounter( TIMER_A1_BASE,TIMER_A_UP_MODE);
}
void dj()
{
Timer_A_outputPWMParam paramr = {0};
paramr.clockSource = TIMER_A_CLOCKSOURCE_ACLK ;
paramr.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
paramr.timerPeriod = 660;//20.1ms,49.75HZ
paramr.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1;
paramr.compareOutputMode = TIMER_A_OUTPUTMODE_RESET_SET;
paramr.dutyCycle = a;
Timer_A_outputPWM(TIMER_A0_BASE, ¶mr);
}
void time()
{
GPIO_setAsOutputPin(GPIO_PORT_P1,GPIO_PIN0);
Timer_A_initUpModeParam initContParam = {0};
initContParam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
initContParam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
initContParam.timerPeriod = 30000;
initContParam.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE;
initContParam.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE;
initContParam.timerClear = TIMER_A_DO_CLEAR;
initContParam.startTimer = false;
Timer_A_initUpMode(TIMER_A1_BASE, &initContParam);
Timer_A_clearTimerInterrupt (TIMER_A1_BASE);
}
void uartinit1()
{
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4,GPIO_PIN5);
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P4, GPIO_PIN4);
USCI_A_UART_initParam param1 = {0};
param1.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK;
param1.clockPrescalar = 6;
param1.firstModReg = 13;
param1.secondModReg = 0;
param1.parity = USCI_A_UART_NO_PARITY;
param1.msborLsbFirst = USCI_A_UART_LSB_FIRST;
param1.numberofStopBits = USCI_A_UART_ONE_STOP_BIT;
param1.uartMode = USCI_A_UART_MODE;
param1.overSampling = USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;
if (STATUS_FAIL == USCI_A_UART_init(USCI_A1_BASE, ¶m1)){
return;
}
USCI_A_UART_enable(USCI_A1_BASE);
USCI_A_UART_clearInterrupt(USCI_A1_BASE,USCI_A_UART_RECEIVE_INTERRUPT);
USCI_A_UART_enableInterrupt (USCI_A1_BASE, USCI_A_UART_RECEIVE_INTERRUPT);
}
void UART_printf(uint16_t baseAddress, const char *format,...)
{
uint32_t length;
va_list args;
uint32_t i;
char TxBuffer[128] = {0};
va_start(args, format);
length = vsnprintf((char*)TxBuffer, sizeof(TxBuffer), (char*)format, args);
va_end(args);
for(i = 0; i < length; i++)
USCI_A_UART_transmitData(baseAddress, TxBuffer[i]);
}
int main(void) {
WDT_A_hold(WDT_A_BASE);
UCS_initClockSignal(UCS_ACLK,UCS_REFOCLK_SELECT,UCS_CLOCK_DIVIDER_1);
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1,GPIO_PIN2);
time();
uartinit1();
__bis_SR_register(GIE);
GPIO_setAsOutputPin (GPIO_PORT_P4,GPIO_PIN7 );
GPIO_setOutputLowOnPin (GPIO_PORT_P4, GPIO_PIN7);
while(1)
{
}
return (0);
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=TIMER1_A0_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(TIMER1_A0_VECTOR)))
#endif
void TIMER1_A0_ISR (void)
{
t++;
if(t<b)
{
a=48;
GPIO_setOutputLowOnPin (GPIO_PORT_P4, GPIO_PIN7);
}
else
{
a=0;
GPIO_setOutputHighOnPin (GPIO_PORT_P4, GPIO_PIN7);
t=0;
Timer_A_clear (TIMER_A1_BASE);
Timer_A_stop (TIMER_A1_BASE);
}
dj();
Timer_A_clearTimerInterrupt (TIMER_A1_BASE);
}
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR()
{
GPIO_toggleOutputOnPin (GPIO_PORT_P1, GPIO_PIN0);
data=USCI_A_UART_receiveData (USCI_A1_BASE);
word[length++] = data;
if((word[length-1]==0x0A)&&(word[length-2]==0x0D))
{
if(length==4)
{
angle = word[length-3]-'0' + (word[length-4]-'0')*10;
}
if(length==5)
{
angle = word[length-3]-'0' + (word[length-4]-'0')*10 + (word[length-5]-'0')*100;
}
UART_printf(USCI_A1_BASE, "%d\r\n", angle);
duoji(angle);
length=0;
}
}
效果
当串口每接收到一个角度值,舵机SG90就旋转这个角度值。