请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号: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)
}