主题 : 关于驱动程序中寄存器设置的疑惑,求指点 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 62351
精华: 0
发帖: 16
金钱: 80 两
威望: 16 点
综合积分: 32 分
注册时间: 2012-01-26
最后登录: 2013-06-20
楼主  发表于: 2012-11-13 15:57

 关于驱动程序中寄存器设置的疑惑,求指点

通常在驱动程序中会有一些寄存器的初始设置,一种方法是直接赋值,比如一个16bit的寄存器可以直接赋值0x1f3c,很简单,不过具体实现功能要自己一位一位去研究。
还有一种方法是移位赋值,比如s3c2440的ADCCON寄存器,共有16bit,根据不同功能赋值,
比如
复制代码
  1.     v_ADCregs->rADCCON=((1<<14)//AD预分频使能
  2.         |(prescaler<<6)//分频因子设为49
  3.         |(0<<3)//通道为AIN0
  4.         |(0<<2)//Normal操作模式
  5.         |(0<<1)//AD转换不能从读操作开始
  6.         );

不过我最近读数据手册产生了一个疑惑,大家看上面的代码,他是想将ADC分频设为49,而ADCCON的[13]~[6]位是用来设置分频因子的,就是说有8bit来设置分频因子,而49的二进制是100111,只有6bit啊,而且而且,最关键的是,大家有没有看到,ADCCON[13]~ADCCON[6]这八位的初始状态是0xff(datasheet上面标注了),那么用49<<6这样的方法按理说就会使刚才提到的那8bit变为11100111,这显然不能将预分频设置为49嘛?难道是我理解错了?具体的过程到底是怎样的?我现在很糊涂……
[ 此帖被wuqi1003在2012-11-13 16:04重新编辑 ]
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
1楼  发表于: 2012-11-13 19:26
49的二进制是110001, 写入寄存器的时候可以看成00110001, 即最高两个bit填0
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 62351
精华: 0
发帖: 16
金钱: 80 两
威望: 16 点
综合积分: 32 分
注册时间: 2012-01-26
最后登录: 2013-06-20
2楼  发表于: 2012-12-09 11:14
引用第1楼kasim于2012-11-13 19:26发表的  :
49的二进制是110001, 写入寄存器的时候可以看成00110001, 即最高两个bit填0


版主我这个问题我还是不懂,过去很多天了,您还能回忆一下吗?
49的二进制是110001,写入的时候看成00110001,但是它是进行“或”操作啊,那么0对应的位置会保持不变啊,
就是说原本那8bit经过reset之后获得reset_value,变成1111,1111,然后与00110001进行“或”运算,最后的结果还是1111,1111。不过我前几天研究boot代码,发现datasheet里面写的reset_value是芯片上电或者复位时的值,但是开发板在上电或者复位后会进入初始化程序,是不是在初始化程序中把设置分频的那8bit全部置零了呢,如果是这样的话那么用49进行移位后再进行“或运算”是可以实现分频达到49的,这样理解对吧?
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
3楼  发表于: 2012-12-09 12:08

 回 2楼(wuqi1003) 的帖子

但是它是进行“或”操作啊,那么0对应的位置会保持不变啊,

"或"操作是在写入寄存器之前的,写入寄存器的是“或”的结果。也就是说,"或"的结果在哪个bit上是0,写入寄存器的时候就在对应bit上写0。
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 62351
精华: 0
发帖: 16
金钱: 80 两
威望: 16 点
综合积分: 32 分
注册时间: 2012-01-26
最后登录: 2013-06-20
4楼  发表于: 2012-12-09 12:23

 Re:回 2楼(wuqi1003) 的帖子

引用第3楼kasim于2012-12-09 12:08发表的 回 2楼(wuqi1003) 的帖子 :

"或"操作是在写入寄存器之前的,写入寄存器的是“或”的结果。也就是说,"或"的结果在哪个bit上是0,写入寄存器的时候就在对应bit上写0。


版主,他这种移位设置寄存器的过程是不是这样,您看我分析的对不对:每条都是32位,所以先将1移位14,得到0b00000000000000000010000000000000,然后49移位6,得到0b00000000000000000000010011100000,然后三个零移位得到的都是0b00000000000000000000000000000000,最后三个数相或,得到0b00000000000000000010010011100000.将这个数赋给寄存器,是这样的吗?他这个寄存器由于不足32位,会自动截断,是吧?
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
5楼  发表于: 2012-12-09 12:42

 回 4楼(wuqi1003) 的帖子

你为什么不把代码改写成
复制代码
  1. u32 value = ((1<<14)//AD预分频使能
  2.         |(prescaler<<6)//分频因子设为49
  3.         |(0<<3)//通道为AIN0
  4.         |(0<<2)//Normal操作模式
  5.         |(0<<1)//AD转换不能从读操作开始
  6.         );
  7. printk("Wrting 0x%08x to ADCCON\n", value);
  8. v_ADCregs->rADCCON= value;
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 62351
精华: 0
发帖: 16
金钱: 80 两
威望: 16 点
综合积分: 32 分
注册时间: 2012-01-26
最后登录: 2013-06-20
6楼  发表于: 2012-12-09 12:52

 Re:回 4楼(wuqi1003) 的帖子

引用第5楼kasim于2012-12-09 12:42发表的 回 4楼(wuqi1003) 的帖子 :
你为什么不把代码改写成
[code]
u32 value = ((1<<14)//AD预分频使能
簀(prescaler<<6)//分频因子设为49
簀(0<<3)//通道为AIN0
.......


我是照着例程改的,版主您主要帮我看看我那个分析过程对不?那个寄存器是16位的,但是指令应该还是按照32位来计算吧?