主题中讨论的其他器件: MSP430FR5969、 MSP430F6779
工具与软件:
我正在尝试分配 DMAxSA 寄存器的完整20位。 用户手册指定"读取或写入位19-16需要使用扩展指令"。
这已经令人困惑、因为 MSP430FR5XX_6XX DMA 代码示例使用了 __data20_WRITE_LONG ()内在函数、这是使用两个标准 MOV 实现的。 w 指令、这些指令不是扩展指令(CPU430X)的一部分。 当我尝试使用_data20_WRITE_LONG (&DMA0SA、0x10000)向 DMA0SA 分配一个20位值时、我得到的寄存器值为0x0。
在进一步阅读 MSP 文档和 本表单讨论后、我了解到我需要改用__ data16_write_addr ()。
在编译时、此内在函数实际上使用 MOVX。 或 POPX。 一条指令为扩展地址分配指令、现在可以看到它成功分配了完整的20位寄存器。
但是、在我的应用保持运行几天后、仍然会因为 DMA 地址分配操作失败而出现问题。 每10000个 DMA 地址分配一次、位19-16就会被错误地清除。
我已经验证__data16_write_addr ()的两个参数都正确,并且 DMA 通道被禁用,所以问题不在于应用软件本身。 此外、我已经按照编译器用户指南的建议禁用了中断。
将_data16_write_addr 替换为我自己的汇编代码不会改变这种情况。
_asm ( "PUSHM. W #2、R15\n"
"POPX." 0 (R12)");
我可以解决此问题的唯一方法是读回 DMA 寄存器值并在循环中重新分配该值。
#pragma optimize=none
void Dma_WriteAddress(uint32_t destination, uint32_t source)
{
__disable_interrupt();
do
{
__data16_write_addr(static_cast<uint16_t>(destination), source);
}
while(__data16_read_addr(static_cast<uint16_t>(destination)) != source);
__enable_interrupt();
}
当我向该函数添加日志记录时、可以看到分配仅在调用该函数时每5.000到50.000次失败一次。
当然、该解决方案不是最佳解决方案、因此不应该是必需的。 这是否是硬件错误(不在勘误表中)? 我缺少什么吗? 还有人会遇到这个问题吗?
这在硬件版本 C 上的三个 MSP430FR5964 IC 上进行了测试
编译器:IAR MSP430 7.21.1
数据/代码模型:小