0

我有一个应用程序,它仅在写入寄存器之前设置断点时才有效。特定的 uC 是 Atmel SAMC21,问题似乎出在写入 GCLK 外设时。我正确写入了 GEN 位,然后设置 CHEN 以启用通道。使用断点可以正确启用。如果没有断点,则在通过 Atmel Studio IO 调试窗口观察时不会设置该位。当未设置该位时(因为它没有计时),此特定通道所连接的 CAN 外围设备会挂起,但如果我设置断点然后允许程序继续运行,则工作正常。它们在代码中没有其他位置被设置或检查,并且没有多线程。

违规代码:

// PCHCTRL[26] GCLK_CAN0
GCLK->PCHCTRL[26].bit.GEN = 7;          // Generic clock generator 7
GCLK->PCHCTRL[26].bit.CHEN = 1;         // The peripheral channel is enabled.
GCLK->PCHCTRL[26].bit.WRTLOCK = 0;      // The peripheral channel and the associated generator registers are not locked.

PCHCTRL:

union PCHCTRL {
    uint32_t reg;
    struct bit {
        uint32_t GEN:4;
        uint32_t :2;
        uint32_t CHEN:1;
        uint32_t WRTLOCK:1;
        uint32_t :24;
    } bit;
} PCHCTRL[41];

我尝试在两次写入之间插入延迟,但没有成功。对于此问题的原因,我们非常感谢您提供任何帮助!

4

2 回答 2

0

这几乎可以肯定是因为在继续之前没有等待时钟同步(命中断点会导致足够长的延迟以使其发生,CAN 和其他一些设备默认情况下不会冻结在断点上)。它需要一些类似的东西来等待时钟同步:

// Set GCLK_CAN0 to use GCLK generator 8
PCHCTRL26 |= PCHCTRL_CHEN | PCHCTRL_GEN_8; // Bit 6 is CHEN, GEN[3:0] set to 8 = GCLK generator 8
while ((PCHCTRL26 & PCHCTRL_CHEN) == 0) {  // Wait for sync
    // Spin
}
于 2017-02-17T10:21:12.567 回答
0

对数据表的快速扫描揭示了这一点(强调我的):

17.5.8. 注册访问保护

外设访问控制器 (PAC) 可以选择对所有具有写访问权限的寄存器进行写保护。

注意:可选的写保护由寄存器描述中的“PAC 写保护”属性指示。

当 CPU 在调试模式下停止时,所有写保护都会自动禁用。写保护不适用于通过外部调试器进行的访问。

由此看来,这听起来很像您的启动代码或应用程序的某些其他部分可能将 PAC 设置为写保护 GCLK,在这种情况下,需要一些戳才能在修改周围取消保护它。

否则,还有这个:

17.6.3.1。启用外设时钟

在使能外设时钟之前,必须使能其中一个发生器 (GENCTRLn.GENEN) 并通过设置外设通道控制寄存器 (PCHCTRL.GEN) 中的发生器选择位将其选作外设通道的源。可以选择任何可用的发生器作为每个外设通道的时钟源。

选择发生器后,通过设置外设通道控制寄存器 PCHCTRLm.CHEN = 1 中的通道使​​能位来使能外设时钟。PCHCTRLm.CHEN 位必须与通用时钟域同步。PCHCTRLm.CHEN 将继续读取其先前的状态,直到同步完成。

这表明如果生成器本身没有正确设置和启用,您可能会看到类似的内容。

于 2016-03-13T14:15:12.410 回答