我有一个应用程序,只有在写入寄存器之前设置了断点时才有效。特定的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];
我尝试在两次写入之间插入延迟而没有运气。任何帮助都非常感谢这个问题的原因!
答案 0 :(得分:0)
数据表的快速扫描显示了这一点(强调我的):
17.5.8。注册访问保护
具有写访问权限的所有寄存器都可以选择通过外设访问控制器进行写保护 (PAC)。
注意: 可选的写保护由寄存器中的“PAC写保护”属性指示 描述
当CPU在调试模式下暂停时,将自动禁用所有写保护。写保护 不适用于通过外部调试器访问。
从那以后,它听起来非常像你的启动代码或应用程序的其他部分可能是设置PAC来写保护GCLK,在这种情况下,需要一些戳,以保护它在修改周围
否则,还有这个:
17.6.3.1。启用外设时钟
在启用外设时钟之前,必须启用其中一个发生器(GENCTRLn.GENEN)和 通过设置外设中的发生器选择位,选择外设通道的源 通道控制寄存器(PCHCTRL.GEN)。可以选择任何可用的发生器作为时钟源 每个外围频道。
选择发生器后,通过将通道使能位置1来使能外设时钟 外设通道控制寄存器PCHCTRLm.CHEN = 1.PCHCTRLm.CHEN位必须为 同步到通用时钟域。 PCHCTRLm.CHEN将继续读作其先前的状态 直到同步完成。
如果生成器本身未正确设置和启用,那么建议您可能会看到类似的内容。
答案 1 :(得分: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
}