tag 标签: pcor

相关博文
  • 热度 20
    2013-8-13 17:09
    1866 次阅读|
    0 个评论
    关于 FREESCALE 的 DEMO 中 PSOR与PCOR 操作的常见错误   在 freescale kinetis 提供的 sample code 中, 以及遍及各种论坛中, 常见对 GPIO register 中的 PSOR 与 PCOR 操作, 存在着 |= 的操作错误. 考虑到 toggle 一个 led 灯, 几乎是每一位入门选手的第一课. 遇到这种甚至是 Freescale 官方发布的代码错误(它并非致命, 逻辑上也有效), 想必对相关寄存器的理解, 会产生相当的困扰. 在 Allen 的 Coding 过程中, 这个 bug 也被 Allen 注意到, 并随手校正, 但是我们发现, 在 Freescale 的官方论坛中, 这个错误被工程师仔细提出, 并认为无法容忍. 参考: https://community.freescale.com/thread/309384 我们惊讶于国外 Engineer 是如此较真的同时, 也陷入一种思索中``` 工程世界, 要求明确清晰, 不容含糊过关.  这就是一个工程师对人对己的一份专业执着吗?   1. 在 Freescale 提供的 sample 中, 我们常常见到这样的例子(来自于最基础的 blinky sample),     /*      * Initialize the Red LED (PTB18)      */     {         /* Turn on clock to PortB module */         SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK;         /* Set the PTB18 pin multiplexer to GPIO mode */         PORTB_PCR18 = PORT_PCR_MUX(1);         /* Set the initial output state to high */          GPIOB_PSOR |= RED_SHIFT;         /* Set the pins direction to output */         GPIOB_PDDR |= RED_SHIFT;     }     /*      * Initialize the Green LED (PTB19)      */     {         /* Turn on clock to PortB module */         SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK;         /* Set the PTB19 pin multiplexer to GPIO mode */         PORTB_PCR19 = PORT_PCR_MUX(1);         /* Set the initial output state to high */          GPIOB_PSOR |= GREEN_SHIFT;         /* Set the pins direction to output */         GPIOB_PDDR |= GREEN_SHIFT;     } 请注意被我们用粗体标记的代码, 这里是设置相应 RED LED, 以及 GREEN LED 输出高电平, 也就是熄灭 LED 的动作. 我们假设(如果有错误请告诉我), 这里的 |= 的用法是错误的, 尽管它逻辑上不影响熄灭 LED 的效果, 我们这里应该改为 = 表达方式:   GPIOB_PSOR = RED_SHIFT; 其理由来自于"开发者圣经"( Reference Manual), 请看 PSOR与PCOR 的解释: 明确的, 对于 PSOR 与 PCOR register, 只有相关bit 为逻辑1时, 相关bit 有效, 分别执行为 1, 0(对于上述两个 register). 而任何为 0 的 bit, 都不会产生任何改变.   这意味着, 无关原始 PSOR 与 PCOR 的初始值为何, 使用 =, 当无关bit 为0时, 将不会造成在 out 状态上的任何变化, 或者最终影响到 PDOR 相关 IO 输出值的任何变化.   也就是说, 尽管 |= 执行了我们需求的逻辑操作, 但是 |= 浪费了 "codeword" 与 "machine cycle", 并可能带来不可预知的 "side effects".   故我们编程时, 对待 PSOR, PCOR register, 应使用 = 操作.   我们相信, 这种 |= 的误用, 是否深层次反应 Coder 并未曾仔细阅读 RM, 甚至尽管代码片段来自于 Freescale sample code 发布的官方团队.   对我们可能出现的理解错误, 如经发现请立即纠正我.     事实上, 对于 ARM7 如 NXP LPC serial, 我们可以观察到同样功能的 register , IOSET 与 IOCLR, 我们的印象中, 未曾在 nxp 的代码中, 读到这种 |= 的错误用法.   Allen Zhan 于深圳福田 发表于 EETC