原创 如何对一个数的指定的连续几位进行设置

2010-9-3 19:14 1878 5 5 分类: MCU/ 嵌入式

先贴上TQ2440测试程序中的一个函数:


void Clk0_Enable(int clock_sel) 
{ // 0:MPLLin, 1:UPLL, 2:FCLK, 3:HCLK, 4:PCLK, 5:DCLK0
 rMISCCR = rMISCCR&~(7<<4) | (clock_sel<<4);
 rGPHCON = rGPHCON&~(3<<18) | (2<<18);
}


代码详解:


首先,查看rMISCCR变量的定义:


#define rMISCCR    (*(volatile unsigned *)0x56000080) //Miscellaneous control


表示的是一个整型值,该值存放在0x56000080地址处。该地址为s3c2440的寄存器MISCCR(Miscellaneous control Register),查看s3c2440的datasheet,可知该寄存器的[6:4]位表示对clkout0的设置,如下图:


2d0e92c8-20c5-487f-8272-af32b08ca25c.JPG


由此可以看出,上面的函数clk0_enable的作用就是为clkout0选择时钟源。具体选那个时钟源由传递给该函数的参数clock_sel指定。


以上就是该函数的功能。


提炼一下,该函数的作用就是将一个32位的整型数的4-6位设置成函数参数指定的值。那么它是怎么实现的呢?再仔细分析一下。要将该32位数的其他位保持不变,只将4-6这3位设置成指定的值,只需两个步骤:1.将其他位保持不变,4-6位清零。这可通过按位与操作实现。2.将4-6位设置成函数参数指定的值,这可通过按位或操作实现。其中步骤1的对4-6位清零可通过 rMISCCR    &......(31到7位为1)000...(3到0位为1)实现。但是直接写成那种确定数相与的办法使得程序可移植性不好。


函数中rMISCCR&~(7<<4) 操作实现的就是把rMISCCR的4,5,6三位置0,其他位不变,而且程序具有可通用性。例如如果要将rMISCCR的9,10,11位清零,其他位不变,只需改成rMISCCR&~(111<<9)即可。也就是说rMISCCR&~(A<<B)中A指定的是要被置1的连续的位的个数,B指定的是该段连续位的最低位在这个整型数中所处的位置。这种先置1再移位再反转相与的思路值得借鉴。


同理rMISCCR&~(7<<4) | (clock_sel<<4);的后半段实现的就是对被清零的4-6位按函数参数进行设置。


 


 


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
5
关闭 站长推荐上一条 /3 下一条