s3c2440 IO口控制寄存器和数据寄存器在s2440.h中的地址分配及流驱动对IO口控制的实现



我们发现在流驱动中的s2440.h中有对IO口寄存器GPACON~GPJCON、GPADAT~GPJDAT 的地址分配 如下:
#define IOP_BASE 0xB1600000 
typedef struct {
unsigned int rGPACON; // 00 怎么确定rGPACON的地址??
unsigned int rGPADAT;
unsigned int rPAD1[2];
   
unsigned int rGPBCON; // 10
unsigned int rGPBDAT;
unsigned int rGPBUP;
unsigned int rPAD2;
   
unsigned int rGPCCON; // 20
unsigned int rGPCDAT;
unsigned int rGPCUP;
unsigned int rPAD3;
   
unsigned int rGPDCON; // 30
unsigned int rGPDDAT;
unsigned int rGPDUP; 
unsigned int rPAD4;
   
unsigned int rGPECON; // 40
unsigned int rGPEDAT;
unsigned int rGPEUP;
unsigned int rPAD5;
   
unsigned int rGPFCON; // 50
unsigned int rGPFDAT;
unsigned int rGPFUP; 
unsigned int rPAD6;
   
unsigned int rGPGCON; // 60
unsigned int rGPGDAT;
unsigned int rGPGUP; 
unsigned int rPAD7;
   
unsigned int rGPHCON; // 70
unsigned int rGPHDAT;
unsigned int rGPHUP; 
unsigned int rPAD8;
   
unsigned int rMISCCR; // 80
unsigned int rDCKCON;
unsigned int rEXTINT0;
unsigned int rEXTINT1;
unsigned int rEXTINT2; // 90
unsigned int rEINTFLT0;
unsigned int rEINTFLT1;
unsigned int rEINTFLT2;
unsigned int rEINTFLT3; // A0
unsigned int rEINTMASK;
unsigned int rEINTPEND;
unsigned int rGSTATUS0; // AC
unsigned int rGSTATUS1; // B0
unsigned int rGSTATUS2; // B4 ;;; SHL
unsigned int rGSTATUS3; // B8
unsigned int rGSTATUS4; // BC

unsigned int rFLTOUT; // C0
unsigned int rDSC0;
unsigned int rDSC1;
unsigned int rMSLCON;

unsigned int rGPJCON; // D0
unsigned int rGPJDAT;
unsigned int rGPJUP;
unsigned int rPAD9;

}IOPreg;  
......
流驱动中的操作
volatile IOPreg  *s2440IOP = (IOPreg *)IOP_BASE;
......
s2440IOP->rGPBCON = (s2440IOP->rGPBCON &~(3 << 10)) | (1<< 10);
 
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<1);

答案如下:
1、#deifine IOP_BASE 0xB1600000,实际物理地址是:0x56000000;一个是物理地址 一个是虚拟地址,没有开启MMU用0x56000000
开启之后用0xB1600000,计算公式为: 虚拟地址=物理>>4位 + 0xac000000。 采用虚拟内存技术有以下三点好处:第一,可以根据用户的需要重新分配内存地址空间;
第二,可以隔离硬件物理地址空间的变化对软件的影响;第三,可以对存储空间引入保护机制。
 
2、 对I/O口的操作是通过对相关寄存器的读/写实现的。要对寄存器进行读/写操作,首先要对寄存器进行定义。结构体中在基址上内存对齐的分配寄存器的地址,
 volatile IOPreg  *s2440IOP = (IOPreg *)IOP_BASE;这条语句是把一个虚拟地址强行转成一个结构体,这个虚拟地址便是基址,所以再回到结构体上,需要了解的是:ARM中的存储都是以4个字节为一个单位的,所以地址都是4的整倍数。一个32位空间就存4字节数据,使用的时候分离或屏蔽其他信息即可。ARM int整也就是32位的,int temp;//32位,char achar;//8位。rGPACON的地址为0xB16000000,rGPADAT的地址为0xB16000004,rPAD1[0]的地址为0xB16000008,rPAD1[1]的地址0xB1600000C,rGPBCON的地址为0xB16000010依次类推。这样有关IO口各个寄存器的地址就这样确定了,只需在驱动程序中往IO口32位的控制寄存器和数据寄存器中写
 
3、s2440IOP->rGPBCON = (s2440IOP->rGPBCON &~(3 << 10)) | (1<< 10);这条语句的意思是,把GPBCON寄存器第10和11位清零,其他位不变,再把第10位置1,这样就把GPB5的状态改成输出了,通过这条语句可以对IO的功能进行定义,比如定义哪个IO口作为输入输出或其他复用功能。同样s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<1);这条语句的意思是把GPBDAT寄存器倒数第二位置零,其他位不变,这样就使得接在GPB1上的IO口置0了,通过这样可以完成对IO口的赋值。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值