请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号:EK-TM4C123GXL 工具/软件:Code Composer Studio
您好!
我一直在从事一个程序、此程序需要读取 PWM 输入信号的占空比并生成一个适当的比例输出信号。 该程序使用定时器0 (分为两个半宽定时器)捕捉 PWM 信号的上升沿和下降沿、并使用定时器1定期更新比例信号。 在调试时、我发现当定时器1未启用时、程序会完美地读取 PWM 信号。 当定时器0和1都被使能时、上升/下降沿的捕捉时间不会按照它们在给定 PWM 信号中的时间进行线性排列。
我粘贴了以下代码。 我是否可以更改任何内容来解决此问题?
#include #include include "inc/tm4c123gh6m.h" #include "inc/hw_gpio.h" #include "inc/hw_types.h" #include "volatile /hw_memmap.h"#include "driverlib/pvert/intrabe.h" #include "driverlib/driver.h"#driveript/driveript.md小时#include "driveript/driveript.id.h"#include "driverlib#driveript.trategot.h"#include "driveript/driveript.in.id.idr.idr.ide"#include "driver.ide"#driveript/drive.tr.ide"#include "drive.tr.ide"#def"driver.ide"#include "drive.ipt/drive"drive.md.ipt.in.ide"#include "drive.in.ide"#drive.tr.ide"#include "drive.ipt.in.ide"#drive.in.idr.ide"#include //如索引 volatile int32_t error = 0; volatile uint32_t index = 0;//跟踪 gait 数据 中的点 volatile int32_t PIDsignal = 0;//更改 goalpwmhigh volatile uint32_t proportional = 50的信号;//来自 PID volatile uint32_t goalpwmhigh = 2048; //占空比值、4096 个易失性 uint32_t goalDuty = 50;//占空比% 易失性 float rawgoalpos = 0; //此块用于 PWMREAD 静态易失性 uint32_t periodStartTime = 0; 静态易失性 uint32_t volatile EndTimePrevious= 0;静态易失性 uint32_t pulseperiod= 0 ;静态易失性 uint32_t volatile Endpulse脉 冲宽度= 0;静态易失性 静态易失性 uint32_t periodWidth = 1; 静态易失性浮点 dutyCycle = 0; 静态易失性 uint32_t 编码值= 0; void timer1ISR (void) { TimerIntClear (Timer1_base、timer_TValue_timeout); rawgoalpos = getKneedData (index); goalpos =(浮 点 =(浮点=) 2.88 (浮点=(浮点=)) 2、浮点=(浮点=(浮点=(浮点=)))-0.5);信号(浮点=(浮点=(浮点=(浮点=))-0.5)-0.5);rg goalpwmhigh = 2048 + PIDsignal; if (goalpwmhigh > 3696) { goalpwmhigh = 3696; } 否则、if (goalpwmhigh < 410) { goalpwmhigh = 410; } goalDuty =(float) 100 *((float) goalpwmhigh/(float) 4096);setalpulsepalpwmhigh = (index = 0);index = 0)+(index = 1000);如果 index = 1000、则+(index = 1000) } void timerARisingISR (void) { // 计算周期宽度 // //清除中断源 TimerIntClear (TIMER0_BASE、TIMER_CAP_EVENT); //在事件触发时间 周期检索时钟计数 StartTime =((TIMER0_BASE、TIMER_A)<< 16); //如果发生了计时器溢出,则在 以下情况下计算周期宽度:(periodStartTime < periodStartTimePreVent){ periodWidth = periodStartTime +(65536 - PeriodStartTimePreVent); } //如果自最后一个事件以来没有计时器溢出 ,则计算周期宽度:{ periodWidth = StartTimeStartTimePreVent; } //计算占空比 dutyCycle =(((periodwidth)((periodwidth)) 编码值=(dutyCycle *1024); UARTprintf ("rising\n"); UARTprintf ("periodStartTime:%u\n"、periodStartTime); UARTprintf ("periodStartTimePrevent:%u\n"、periodStartTimePrevent); //将当前周期开始时间标记为旧 的 periodStartTimePrevent = periodStartTime; } void timerBFallingISR (void) { //清除中断源 TimerIntEndClear (TIMER0_BASE、TIMERCAPB_EVENT);TimerB<16 )、TimereTimerIntTimerIntTimerTimereTimerB (timerTimerTimerTimerB >);(timerTimereTimerTimerTimerTimereTimerTimerTimerTimerTimerTimerB) //如果16位计时器溢出,则在 (pulseEndTime < periodStartTime){ pulsewidth = pulseEnd+(65536 - periodStartTime); } //如果计时器没有溢出 ,则相应地计算脉冲宽度,否则{ pulsewidth = pulseEndTime - startTime; } Uprintf ("Falling\n"); UARTprintf ("%rtpulseTime):%printseTime int main (void) { //将时钟设置为40MHz SysCtlClockSet (SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_16MHz|SYSCTAL_OSC_MAIN); //启用 UART0 SysCtlSysCtlUSPELEnable (SYSCL_UART0); // 启用 SysCtlSysCtlSysPeriph_GPIOPTL (SYSC_GPIOPTL);// 启用 GPIOPTL 外设 和 GPIO 端口 B 和 F SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0); SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB); SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF); //等待 TIMER0模块就绪 while (!CCPt1_PPT7_GPIO6) ; 配置 GPIOPTMCTTimer_P0_PIN_CAPT0_GPIO7 (Timer_PPT0_GPIO7);//为 GPIO6) //将 TimerA 配置为半宽单次触发定时器,将 TimerB 配置为// 半宽边沿捕获计数器。 TimerConfigure (TIMER0_BASE、(TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP | TIMER_CFG_B_CAP_TIME_UP); // TIMER_CLOCK_SYSTEM:使用40MHz 系统时钟 // TIMER_CLOCK TIOSC:使用16MHz 精密内部振荡器作为计时信号 //似乎不是 TIMERC123GMCK_TIME_CLOCK 系统时钟选项 ;TIMERC123GRTINSGC0 (TIMERCLOCK) //为 timerA 和 timerB 设置预分频器值以确保溢出发生的速度比 PWM 周期慢 //计时器频率当前设置为10MHz //出于某种原因,现在无法正常工作,计时器仍以40MHz 运行 //TimerPrescaleSet (TIMER0_BASE、TIMER_Both、4); //将 TimerA 配置为标记上升沿的时间,将 TimerB 配置为标记下降沿的时间 TimerControlEvent (TIMER0_BASE、TIMER_A、TIMER_EVENT_POS_EDGE); TimerControlEvent (TIMER0_BASE、TIMER_B、 Timer_EVENT_NEG_EDGE); //清除两个中断 TimerIntClear (TIMER0_BASE、TIMER_CAPA_EVENT | TIMER_CAPB_EVENT); //寄存器计时器中断服务例程 // TIMERIntRegister (TIMER0_BASE、TIMER_A、* TIMERARisingISR); // TIMER0_BASE、TIMER0_BASE (TIMER0寄存器) * timerBFallingISR); //为两个计时器启用中断,A 检测上升沿,B 检测下降沿 TimerIntEnable (TIMER0_BASE,TIMER_CAPA_EVENT | TIMER_CAPB_EVENT); //为 timerA 和 timerB IntEnable (INT_TIMER0A)启用中断; IntCtl(INT_CAMP_EVENT) ;Timer1 (TIMERB) Timer1 (TSYSRB_启用中断;Timer1) //等待定时器模块1准备就绪 while (!SysCtlPeripheralReady (SYSCTL_Periph_Timer1) ){ // 配置一个全宽定时器,递减计数 TimerConfigure (Timer1_base、timer_CFG_PERIODICRAY); //将定时器1设置为从系统时钟 TimerClockSet (Timer1_base、Timer100Hz)运行;//将 TimerBlockTimerSet (TimerSet (Timer1_base )、TimerTimer100Hz)设置为系统时钟源计时器1;TimerTimer100Hz //注册定时器中断服务例程 TimerIntRegister (Timer1_base、timer_A、* timer1ISR); //清除翻转中断,然后将其启用 TimerIntClear (Timer1_base、timer_TINA_timeout); TimerIntEnable (Timer1_base、timer_TIMA_TIMEOUT); IntEnable (TIMER_TIMER_TIMEOUT); //为 UART GPIOPinConfigure (GPIO_PA0_U0RX)、 GPIOPinConfigure (GPIO_PA1_U0TX)、 GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1)配置 GPIO 引脚; //使用内部16MHz 振荡器作为 UART 时钟源。 UARTClockSourceSet (UART0_BASE、UART_CLOCK_PIOSC); //初始化控制台 I/O 的 UART UARTStdioConfig (0、921600、16000000); GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、GPIO_PIN_3); GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_3、GPIO_PIN_3); IntMasterEnable (); //同步计时器 A 和计时器 B 以在相同的时钟周期启动 TimerSynchronize (TIMER0_BASE、TIMER0A_SYNC | TIMER_0B_SYNC); //启动计时器 TimerTimerTimerEnable (TIMER1) ; while (TIMER1和 NOT_BASE) ;}Timer1 (TIMER1 (while) }