This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/TM4C123GH6PM:当由捕捉事件触发时、UDMA 从 GPTMTBR 寄存器传输两次相同的值

Guru**** 2481465 points
Other Parts Discussed in Thread: SEGGER

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/704185/ccs-tm4c123gh6pm-udma-transfers-same-value-twice-from-the-gptmtbr-register-when-triggered-by-capture-event

器件型号:TM4C123GH6PM
主题中讨论的其他器件: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);
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我的公司使用类似(预期的现代磁性编码器)的编码器。    您是否可以识别您的身份-以防我们也这样做-库存它?

    BTW -您的帖子内容很好-呈现得很好-尽管我“必须”接受问题... 有些  "索赔和/或报告"。   (您确实请求了-"您可以获得的所有帮助!")

    我的主要问题:

    • 您的编码器(可能/可能)来自"HEIDENHAin" (LC 系列)、该编码器可能会将"step"解析 为1nm。   (0.001µm)  您可以确认吗?
    • 您写道:"将  GPTMTBV 寄存器的快照值写入  GPTMTBR 寄存器。"   我认为这是完全错误的-'BR'寄存器是同步捕获'Edge Time Counter Value'的寄存器。 与您的信号上升沿同步!   相反-在我看来、"BV"寄存器是"自由运行"-您允许它(通过改写)替换(正确)"BR"寄存器!   边沿定时器功能已经自动检测过程-将检测到的边沿置入寄存器'BR'。   然后、您的工作是读取并存储寄存器"BR"而不是覆盖 -包含自由运行的"BV"寄存器中的内容...
    • 如果我的分析(上面)证明是正确的(从我阅读的《MCU 手册》-和简单的“极好”-图11-4,第715页),那么您的工作会减少到,“读取和存储'BR'值-在(非常)下一个正信号边沿到达(预期)之前!
    • 连续捕获的"BR"寄存器值之间的"delta"值-记录正边沿到达之间经过的时间-可用于帮助您计算"线性速度"。
    • 您注意到一个80MHz 系统时钟-但"边沿时间"不会对"边沿检测?"施加"四分频"限制   (来自内存-这是2个时钟稳定性-在(两个)上升沿和下降沿上强制执行-产生这样的4分频-这会使边沿检测降低至20MHz (最大值)时钟 速率!)
    • 现在、您会注意  到线性编码器提供的~50kHz 脉冲速率。   (实际上)情况(看起来非常低)-以及所有线性跨度/移动- 在(两个)方向-以及"尤其是"在"高速"加速过程中?    ~现代的"运动控制系统"以"精确的旅行"为傲、采用 M ü r (几百) MS!"   如果我的(信封背面)计算值正确-编码器报告: '1nm Travel in 20µS ' -延伸至'1mm  Potential Travel -需要20秒!'   这(实际上)是否是您的系统的目标?    (需要注意的是、即使是一只慢的3脚海龟、也可以(轻松)"赢得这样的比赛!")    (和-'垂直'-可能会转换为'冰川'。)

    我是否可以建议您使用"kiss"、这将寻求"分步"、目的是 通过系统和(逻辑)顺序 测试/验证逐步确认代码和器件成功。   (即一次一个定义明确的小(可测量)测试步骤!)

    在调查过程中使用 µDMA -这是您的早期-肯定/实质上 违反了 kiss!    (大大增加了您的诊断工作)   

    • 相反-您能否不触发示波器来捕获编码器脉冲的短序列(也许只有4个)-然后比较/对比示波器的“边沿捕获”...  与您的非 µDMA μ A (更简单) MCU (小型)缓冲器'BR'寄存器捕获和存储?)    (务必防止"BV"过度写入"BR"!)
    • 当(以及如果)此类"双来源"结果 收敛时(然后才)、 测量精度就会变得"更加自信"!  
    • 我怀疑您的"问题"可能包括(超出)-"边沿计时器捕获的值的"重复"...

    再说一次-如果您识别编码器-我们对其进行库存(我们有许多来自(HEIDENHAIN、RLS 等)-我们可能能够"复制您的测试..."   (尽管 远远大于-线性运动位移...)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我确实请求了我能得到的所有帮助、我感谢您的参与!

    我的编码器是分辨率为1nm 的 Renishew Atom 线性编码器。  

    2、我想我们的意思是相同的、我的意思是定时器自动捕获信号上升沿的时间。 我还了解到、这次在 BR 中捕获的计时器是 在上升沿时刻 BV 寄存器的快照。

    这也是我的分析、但可能 UDMA 一次过大。 无论采用哪种方式、我最终都需要 UDMA、因为每次我获得编码器脉冲时都不能有中断。 但是、在最终实施之前、我假设需要像您所说的那样对捕获事件进行更严格的验证。

    这就是我计算速度的方式。

    5和6。 其目的是以50、000 Nm/s 的速度进行传输、我知道这种速度非常慢。 这就是为什么我没有看到时钟太慢、以至于脉冲以如此低的速度进入。 值得一提的是、我们正在测量其速度的马车在轴承上浮动、并且在马车未受到任何有意的外部力量的影响时、记录了速度、当然、除了房间的振动。  

    我倾向于同意、问题可能超出 BR 值的重复范围、但确实有人怀疑 BR 和 UDMA 为目的缓冲区中的两个后续元素提供相同的值。  

    无论采用哪种方法、我都将尝试比较一种捕获 BR 寄存 器的较简单的非 UDMA 方法与使用内置 QEIVelocityGet 的实现方案。

     

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您-始终很好地代表花费的时间/精力收到(部分)回应(正面或负面)。   (代表海报)

    在我看来、您再次"拒绝 kiss"、这次倾向于采用"更复杂的多步骤 QEI 模块"。   

    您建议的 µDMA 和 QEI 模块'的使用是正确的-再次强调-它们添加了新的元素-(可能)使您的目标变得复杂、延迟-甚至与您的目标相一致。    (我"从头开始构建"、然后选择了一家技术公司"公开" 、"承诺亲吻!"    (今天——最常——我们被要求“将”那些“重新命名”——因为“太多了——太快了!”    (然而、这种"有缺陷/不完美的愿望"-让  我们的门保持打开...)

    请允许我再次指出-您的"运用我的建议"的巨大力量 、 "结果融合!"    (示波器电容器-与 MCU"BR"商店(不是 BV)- 如我的初始帖子所示)

    一种"经 kiss 批准"的测试方法是让您(目前)将编码器替换为"可控脉冲发生器"、并使用该方法驱动计时器的输入。    (确保您的信号符合所有 MCU 规格)  通过 种基于 kiss (即远超)的方法、可能会增加编码器的复杂性/未知因素(可快速轻松地消除这些因素)。

    " 生成此类"编码器更换/模拟信号"的极其"快速/简单"的方法-通过(另一个) MCU 计时器-订购进入 PWM 模式(设置为逐渐提高的"测试"频率-同时保持50%占空比)、然后"将该(新)计时器输出互连到您的原始计时器输入..."   (从而启用已知输入信号到达速率-并删除(任何)编码器"不规则!")     (这解释 了...  为什么我会“花大价钱!”)

    由于 您的应用具有"极端环境性质"、因此  最好(到目前为止)介绍"首先正确测试和确认您的 MCU 实施情况-然后仅在验证成功后(然后、仅在那时)-介绍(精密和复杂)编码器"。    (我只知道您 仍然 (被吸引)选择"一体式"方法-但此处详述的方法-而是"已知且经实践证明有效!")    (虽然“收集”了许多关键/关键的“数据点”(通过“一体机”进行了鬼影) ...  因此,立即拒绝是不明智的!)

    (BTW - Renishew 收购了50%的 RLS - IT (可能)证明对 RLS 磁编码器"比较/对比"很有用(可能更可靠) -同样...)   

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、再说一次、

    我认为、使用更可靠的源模拟编码器脉冲的想法是一个好主意、但是我之前已经验证过编码器、但这是值得测试的。  

    到目前为止、我已经进行了移除 uDMA 的测试、每次我获得编码器脉冲时都会生成一个中断、以存储用于速度计算的 BR 值。 我仍然看到了获得两个随后的 BR 值完全相同的趋势。 遗憾的是、我没有看到 QEI 模块和 BR 值生成的速度的收敛、但这可能是预料之中的、因为我们在这两种方法之间获得了非常不同的采样周期。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    建议使用"Scope"来捕获和存储这些"编码器边缘事件" 、但由于"什么原因?"、我们拒绝了该建议

    这是 "捕获的编码器边缘到达"和您记录的"仅限 BR" MCU 商店的"融合"、我相信(原谅)这将带来更大的价值!   (当与(较少直接/通知)"QEI 与 BR 值"形成对比时。)

    "以前验证过编码器"-提供(少量)诊断帮助-现在和现在。  (即对这种(过去)"验证"的方法没有深入了解。)
    我们相信、"遵循所提供的说明"(现在已多次)将会快速 、最好地"解决您的问题"。

    我已经尽可能地回答了您的请求-请允许我注意、您列出的"好主意"实际上是-"一种实践良好/经过实践检验且"久经考验"的成功方法!"   (显然应该这样解决 我的问题。)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 CB1、

    我在"JTAG 锁定"论坛中搜索了一些有关 TM4C 板的研究、因此您的帖子几乎涵盖了我发现的与该主题相关的每一个主题。 我只想感谢您通过提供从多年经验中汲取的宝贵信息来解释和帮助他人的所有努力。 我想看你们的几篇帖子、但是...o/这是我能做的最好的。 有了 Segger 的 J-Link 和 Kiss、未来的任何项目都将顺利进行。 谢谢你。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我的朋友-哇!  (我的支票(如之前承诺的那样-“在邮件中”)...  一定要来——比 预期的要早!)
    (罕见)但非常感激的发帖-当然有、"证明此类付款合理!"    (现在-员工和我(真的)必须销售一些东西...)

    能(总是)期待顺利的航行-一个更合理的结果 ... “更频繁的航行”-“较少频繁进入”“已知和可避免”的死胡同!   (鼠疫-抗议者(R9、R10)-有人?)    与您的(提到的) J-link 和非凡的"kiss"一起-请考虑专业 IDE "IAR"-可免费下载。   请注意、'J-link & IAR'-支持所有供应商的 ARM MCU!   (免费的 IAR 限制为32KB -这(令人惊讶)证明了优势这鼓励- kiss!   ( 一次一场小规模、可衡量的战斗... 我可以销售-还是什么?)

    感谢您的客气话- "毫无理由/无法解释"的"类似"的放逐使我(实质上)退出了本论坛。   为了纪念美国 我回到了(放逐)现场的独立日(以及工作人员的疲惫/假期),但 只是短暂的一段时间……

    祝你一切顺利、再次感谢。   (请尽快支付现金-并赚取收入!...)