c语言问题

2025-06-21 06:21:01
推荐回答(1个)
回答1:

首先我们计算mpll_val的值。这里涉及两个操作符<<(左移)和|(异或),都是二进制运算符。具体定义这里就不说了,可以自己查下。

mpll_val = (92<<12)|(1<<4)|(1);

92转换成二进制为01011100,将此数左移12位,也就是后面加12个0,变成01011100000000000000,转换成十进制为2^14+2^15+2^16+2^18 = 376832,

同理,1<<4转换成十进制为16,上面mpll_val  = 376832|16|1,这个其实就相当于

376832+16+1(很简单,知道了异或的规则用二进制计算就知道了)。因此:

mpll_val  = 376849


下面的rMPLLCON的值计算需要理解三个概念:函数,参数,异与操作符

函数指的的就是void ChangeMPllValue(int mdiv,int pdiv,int sdiv);

参数指的是这个函数中定义的三个整型参数,在下面的具体声明中,也是这三个参数:

void ChangeMPllValue(int mdiv,int pdiv,int sdiv)
{
rMPLLCON = (mdiv<<12) | (pdiv<<4) | sdiv;
}

最后实现过程ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);这三个参数分别对应(mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3这三个值。

这里我们只将第一个参数的值(mpll_val>>12)&0xff是多少:

mpll_val我们刚才已经计算为376849,现在mpll_val>>12就是右移,与左移相反,等于我们又将mpll_val打回原形变成了92,那么下面我们计算92&0xff,这里我们需要知道0xff是一个十六进制数。

以0x开始的数据表示16进制,0xff换成十进制为255。
A,B,C,D,E,F这五个字母来分别表示10,11,12,13,14,15。
16进制变十进制:f表示15。第n位的权值为16的n次方,由右到左从0位起。
 0xff = 15*16^1 + 15*16^0 = 255
16进制变二进制再变十进制:
0xff = 1111 1111 = 2^8 - 1 = 255

也就是92&255,用二进制表示就是

  01011100

&11111111

=01011100

因此(mpll_val>>12)&0xff的值就是92,同理可以得出后面两个参数的值。最后代入

rMPLLCON = (mdiv<<12) | (pdiv<<4) | sdiv;(计算得知mdiv = 92,pdiv = 1, sdiv = 1)

最后计算rMPLLCON,你一定以为是376849,但是不是的,结果应该是没办法写入的,因为

#define rMPLLCON    (*(volatile unsigned *)0x4c000004) //MPLL Control

简单来说这句话就是定义rMPLLCON为一个指向固定地址的常量,不是变量,具体参考http://blog.sina.com.cn/s/blog_65861d3f0100xsz0.html

最后,提供一个验证程序,自己调试看看吧:

#include
#include
void ChangeMPllValue(int mdiv,int pdiv,int sdiv);
#define rMPLLCON (*(volatile unsigned *)0x4c000004) //MPLL Control

int main()
{
unsigned int mpll_val =0;
mpll_val = (92<<12)|(1<<4)|(1);
int mdiv = (mpll_val>>12)&0xff;
ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);
getch();
return 0;
}
void ChangeMPllValue(int mdiv,int pdiv,int sdiv)
{
rMPLLCON = (mdiv<<12) | (pdiv<<4) | sdiv;
}