对于寄存器的设置,尤其是移位赋值的想法

        v_ADCregs->rADCCON=((1<<14)//AD预分频使能
            |(prescaler<<6)//分频因子设为49
            |(1<<3)//通道为AIN1
            |(0<<2)//Normal操作模式
            |(0<<1)//AD转换不能从读操作开始
            );

上面这段程序就是典型的移位赋值寄存器的操作。

下面的图是其对应的寄存器datasheet:

由上可见[13:6]这8个bit用来设置分频因子的,程序中用了49<<6这一句来进行设置,而49转为二进制是110001,只有6bit,而更为关键的是[13:6]这8bit的初始状态是0xFF,可参见上图,那么,采用49<<6对这8个bit赋值后应该会变成11110001,这就成了241了,不是49了!

所以我想,是不是这种移位赋值的方法只适用于初始状态为0的bit或bit组,如果初始状态不为零,恐怕不能直接用这种方法赋值,而需要将其先赋零后再采用这种方法赋值。


还有另外一种赋值寄存器的方法,就是直接赋值,比如一个16bit的寄存器,可以直接=0xf13c(随便写的,没有具体意义),但我觉得这种方法不适用于上面图中的ADCCON寄存器,为什么这么说?因为它的[15]位是表示AD转换状态的,是只读的(Read-only),我们不能赋,最后一位[0]是手动控制AD开始用的,我们不想目前不想赋,而用直接赋值的话不管写什么值总会影响到这两位。

不能用直接赋值,可以用另外一种移位赋值,就是“与非赋值法”,分析一下上面的程序,其实我们想要的结果无非是下面这样:

bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
X 1 0 0 1 1 0 0 0 1 0 0 1 0 0 X

X表示暂时忽略不管,先将需要取零的位赋值:

ADCCON &= ~((3<<12)|(7<<7)|(3<<4)|(3<<1));

再对其中需要取1的位赋值:

ADCCON |= ((1<<14)|(3<<10)|(1<<6)|(1<<3));

这样既得到了预期的效果,又没有影响到其他的位。

新手的胡思乱想,不当之处,还望高人指点。

原文地址:https://www.cnblogs.com/wuqi1003/p/2768219.html