主题中讨论的其他器件:SEGGER
工具/软件:Code Composer Studio
您好!
我的应用应该通过计算来自线性编码器的脉冲之间经过的时钟节拍量来实现速度测量(在大约50 000Hz 时、1nm 的指示值)。 我这样做的方法是将定时器配置为输入边沿时间模式、在该模式下、定时器会对 CCP1进入的编码器脉冲的每个正边沿做出反应、并将 GPTMTBV 寄存 器的快照值保存到 GPTMTBR 寄存器中、对每个编码器脉冲重复此操作。 与此同时、UDMA 被配置为由定时器中的捕捉事件触发、以将 GPTMTBR 的值传输 到存储器阵列缓冲区、而我已经定义了该缓冲区来保存编码器时序。
我遇到的问题是、我看到在内存缓冲区中、有时会重复相同的整数值两次、就像编码器脉冲在时钟计数一个周期之前进入了两次、而在80MHz 时钟下、这是不可能的。 如果不确切地知道导致这种情况的原因、我就不知道此刻如何准确地处理速度测量。
我感谢我能提供的一切帮助。 以下是代码:
#include
#include
#include
#include
#include "inc/hw_timer.h"
#include "s/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_ints.h"
#include "driverlib/timer.h"
#define "driverlib_intervase/driverh
#define "#define t_intervase/intervase/interverh #define "#define "#define t_intervase/t.interver32.t_intervisor_int_intervase"
(#define #define #define #define #define #define t_int_int_int_intervase/t.intervisor_int_int_interver32.t_intervase"#define #define #define #define #define t.int_int_int_int_intervase.t_intervase/t.int_int_int_int_int_intervase.h)#include "#define #define #define #
//使用此计时器对 z 方向
void
wideTimer5IntClear (void)
{
TimerIntClear (WTIMER 5_base、TIMER_TIMB_DMA)的速度进行采样;
}
void wideTimer5Int (void){
wideTimer5IntClear ();
// wideTimer5Off ();
memset (pui32DestBuffer、0、sizeof (pui32DestBuffer));
uDMAChannelTransferSet (UDMA_CHANGE_I2S0TX | UDMA_PRI_SELECT、UDMA_MODE_BASIC、((void *)(WTIMER 5_base + TIMER_O_TBR))、pui32DestBuffer、DMATransferSize);
uDMAChannelEnable (UDMA_CHANGE_I2S0TX);//重新启动 DMA 传输
}
//*********
//////
启动计时器
//
//***************
//
void wideTimer5Init (void (* pfnHandler)(void)
{
numberOfTickPerIntervall = Int32_MAX;
HWREG (GPIO_PORTD_BASE + GPIO_O_LOCK)= GPIO_LOCK_KEY;
HWREG (GPIO_PORTD_BASE + GPIO_O_CR)|= 0x80;
HWREG (GPIO_PORTD_BASE + GPIO_AFSEL)&&~0x80;
HWREG (GPIO_PORTD_BASE + GPIO_O_DEN)|= 0x80;
HWREG (GPIO_PORTD_BASE + GPIO_O_LOCK)= 0;
SysCtlPeripheralReset (SYSCTL_Periph_WTIME5);
SysCtlPeripheralEnable (SYSCTL_Periph_WTIME5);//为计时器启用外设和引脚
while (!SysCtlPeripheralReady (SYSCTL_Periph_WTIME5))
{
}
// TimerDisable (WTIMEER5_base、timer_both);
GPIOPinConfigure (GPIO_PD7_WTWCCP1);
GPIOPinTypeTimer (GPIO_PORTD_base、GPIO_PIN_7);
wideTimer5Off ();
TimerConfigure (WTIMER 5_base、(TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_ONE_SHOT | TIMER_CFG_B_CAP_TIME_UP));
TimerControlEvent (WTIMER 5_base、TIMER_B、TIMER_EVENT_POS_EDGE);
TimerLoadSet (WTIME5_BASE、TIMER_A、numberOfTickPerIntervall);
TimerLoadSet (WTIMER 5_base、TIMER_B、numberOfTickPerIntervall);
//*********
//配置 DMA 以传输有关编码器节拍时序的数据
SysCtlPeripheralReset (SYSCTL_Periph_UDMA);
SysCtlPeripheralEnable (SYSCTL_Periph_UDMA);
while (!SysCtlPeripheralReady (SYSCTL_Periph_UDMA))
{
}
uDMAEnable();
TimerDMAEventSet (WTIMER5_base、TIMER_DMA_CAPEVENT_B);//设置捕获事件以触发 DMA 请求
uDMAChannelAssign (uDMA_CH29_WTIMEER5B);//以便 DMA 接收来自 wtimer5的数据
uDMAControlBaseSet (pui8DMAControlTable);
uDMAChannelControlSet (UDMA_CHANNEL_I2S0TX、UDMA_SIZE 32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_ARB_1);
uDMAChannelTransferSet (UDMA_CHANGE_I2S0TX | UDMA_PRI_SELECT、UDMA_MODE_BASIC、((void *)(WTIMER 5_base + TIMER_O_TBR))、pui32DestBuffer、DMATransferSize);
//在缓冲区填满时重新开始计数的中断
wideTimer5IntClear ();
TimerIntRegister (WTIMER 5_base、TIMER_B、pfnHandler);
IntPrioritySet (INT_WTIME5B、INT_PRIO_WTIME5);
//启用所有功能
TimerIntEnable (WTIMER 5_base、TIMER_TIMB_DMA);
TimerEnable (WTIMER 5_base、timer_both);
uDMAChannelAssign (uDMA_CH29_WTIMEER5B);//以便 DMA 接收来自 wtimer5的数据
uDMAChannelEnable (uDMA_CHANGE_I2S0TX);
// extern bool uDMAChannelIsEnabled (uint32_t ui32ChannelNum);
}
void
wideTimer5On (void)
{
TimerEnable (WTIMER 5_base、timer_B);
}
void
wideTimer5Off (void)
{
TimerDisable (WTIMER 5_base、timer_B);
}