代码
#include "driverlib.h"
#include "stdio.h"
#include <string.h>
#include <stdarg.h>
static int capz=0;
static int capy=0;
static int error=0;
static int aim=40;
static int allerr=0;
static int previouserr=0;
static int altererr=0;
static int output=0;
static float kp=4.0;
static float ki=0.1;
static float kd=2.0;
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;
}
//Enable UART module for operation
USCI_A_UART_enable(USCI_A1_BASE);
}
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]);
}
void up(int r,int l)
{
GPIO_setAsOutputPin (GPIO_PORT_P6,GPIO_PIN1 );
GPIO_setAsOutputPin (GPIO_PORT_P6,GPIO_PIN2 );
GPIO_setAsOutputPin (GPIO_PORT_P6,GPIO_PIN3 );
GPIO_setAsOutputPin (GPIO_PORT_P6,GPIO_PIN4 );
GPIO_setOutputHighOnPin (GPIO_PORT_P6, GPIO_PIN2);GPIO_setOutputHighOnPin (GPIO_PORT_P6, GPIO_PIN3);
GPIO_setOutputLowOnPin(GPIO_PORT_P6, GPIO_PIN1);GPIO_setOutputLowOnPin(GPIO_PORT_P6, GPIO_PIN4);
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1,GPIO_PIN3);
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1,GPIO_PIN2);
//Generate PWM - Timer runs in Up mode
Timer_A_outputPWMParam paramr = {0};
paramr.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
paramr.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
paramr.timerPeriod = 100;
paramr.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_2;
paramr.compareOutputMode = TIMER_A_OUTPUTMODE_RESET_SET;
paramr.dutyCycle = r;
Timer_A_outputPWM(TIMER_A0_BASE, ¶mr);
//Generate PWM - Timer runs in Up mode
Timer_A_outputPWMParam paraml = {0};
paraml.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
paraml.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
paraml.timerPeriod =100;
paraml.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1;
paraml.compareOutputMode = TIMER_A_OUTPUTMODE_RESET_SET;
paraml.dutyCycle = l;
Timer_A_outputPWM(TIMER_A0_BASE, ¶ml);
}
void time()
{
Timer_A_initContinuousModeParam initContParam = {0};
initContParam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
initContParam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
initContParam.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;
initContParam.timerClear = TIMER_A_DO_CLEAR;
initContParam.startTimer = false;
Timer_A_initContinuousMode(TIMER_A1_BASE, &initContParam);
//Initiaze compare mode
Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE,
TIMER_A_CAPTURECOMPARE_REGISTER_0
);
Timer_A_initCompareModeParam initCompParam = {0};
initCompParam.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_0;
initCompParam.compareInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;
initCompParam.compareOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;
initCompParam.compareValue = 50000;
Timer_A_initCompareMode(TIMER_A1_BASE, &initCompParam);
Timer_A_startCounter( TIMER_A1_BASE,TIMER_A_UP_MODE);
//__bis_SR_register(GIE);
}
void pidcapture()
{
Timer_A_initContinuousModeParam htim = {0};
htim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;
htim.timerClear = TIMER_A_DO_CLEAR;
htim.startTimer = false;
Timer_A_initContinuousMode(TIMER_A2_BASE, &htim);
//捕获右轮
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P2, GPIO_PIN5);
Timer_A_initCaptureModeParam initComParam = {0};
initComParam.captureRegister = TIMER_A_CAPTURECOMPARE_REGISTER_2;
initComParam.captureMode = TIMER_A_CAPTUREMODE_RISING_EDGE;
initComParam.captureInputSelect = TIMER_A_CAPTURE_INPUTSELECT_CCIxA;
initComParam.synchronizeCaptureSource = TIMER_A_CAPTURE_SYNCHRONOUS;
initComParam.captureInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;
initComParam.captureOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;
Timer_A_initCaptureMode(TIMER_A2_BASE, &initComParam);
//捕获左轮
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P2, GPIO_PIN3);
Timer_A_initCaptureModeParam initComParamzuo = {0};
initComParamzuo.captureRegister = TIMER_A_CAPTURECOMPARE_REGISTER_0;
initComParamzuo.captureMode = TIMER_A_CAPTUREMODE_RISING_EDGE;
initComParamzuo.captureInputSelect = TIMER_A_CAPTURE_INPUTSELECT_CCIxA;
initComParamzuo.synchronizeCaptureSource = TIMER_A_CAPTURE_SYNCHRONOUS;
initComParamzuo.captureInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;
initComParamzuo.captureOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;
Timer_A_initCaptureMode(TIMER_A2_BASE, &initComParamzuo);
Timer_A_startCounter( TIMER_A2_BASE,TIMER_A_CONTINUOUS_MODE);
}
int main(void) {
WDT_A_hold(WDT_A_BASE);
time();
uartinit1();
pidcapture();
__bis_SR_register(GIE);
return (0);
}
#pragma vector=TIMER1_A0_VECTOR
__interrupt
void TIMER1_A0_ISR (void)
{
capy=(int)capy;
error=aim-capy;
allerr += error;
altererr = error - previouserr;
previouserr = error;
output = kp*error+ki*allerr+kd*altererr;
if(output>95)output=95;
if(output<15)output=15;
output = (int)output;
up(output,output);
UART_printf(USCI_A1_BASE, "%d,%d,%d\r\n", output,80,capy);
capy=0;
capz=0;
}
#pragma vector=TIMER2_A1_VECTOR//右轮
__interrupt
void TIMER2_A1_ISR(void)
{
switch(TA2IV)
{
case TA2IV_TACCR2:
capy++;
break;
}
}
#pragma vector=TIMER2_A0_VECTOR//左轮
__interrupt
void TIMER2_A0_ISR(void)
{
capz++;
}
效果
每0.05秒捕获的上升沿个数目标值为40,实际值为40.
预计pwm占空比为80,实际占空比为86.
注意事项
开启多少个中断就要写多少个中断服务函数,如果需要执行中断时程序找不到中断服务函数入口地址,会从main函数重新执行,程序会死机。