2440裸机学习之——LED灯的控制

 s3c2440有130个I/O口,GPA,GPB...GPJ通过设置寄存器来确定其功能。
   GPxCON寄存器:
   选择引脚的功能,GPBCON-GPJCON每两位控制一根引脚: 00表示输入,01表示输出,10表示特殊功能,11保留不用。
   GPACON特殊,每一位控制一根引脚,共23根,某位为0时,为输出引脚,当某位1时,相应引脚为地址线或用于地址控制, 此时GPADTA无用。
     一般的,GPACON设为全1,以便访问外部存储器件。
   GPxDAT寄存器:
   当引脚为输入时,读其对应位可知电平状态是高还是低。
   当引脚为输出时, 写寄存器对应位则引脚输出高电平或低电平。
   GPxUP寄存器:
   某位为1时,相应引脚无内部上拉电阻,为0时,相应引脚使用内部上拉电阻 。
   这里只讨论GPIO口的使用,其余的做成子函数,直接调用,可暂时不深究。

 

#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"

/* 延迟函数*/
void delay(U32 count)
{
U32 i,j;
for(i=count;i>0;i--)
{
   for(j=0;j<10000;j++);
}
}


int Main(int argc,char **argv) //main函数
{

U8 key;
U32 mpll_val=0;
  
mpll_val = (92<<12)|(1<<4)|(1);

ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);   //设置主时钟频率405MHZ
ChangeClockDivider(key, 12);      //设置时钟驱动频率的函数  
   
     MMU_DisableICache();    //对内存管理单元MMU的设置
     MMU_DisableDCache();

//呵呵,第一次 看到Arm是不是很晕,先不管他以上是我照搬过来的。  

//以下是GPB配制寄存器和数据寄存器


     rGPBCON=0x155555;   
//控制GPBCON全部为01,即输出

   
     
     while(1)
     {
   /*rGPBDAT = (0x0e<<5);    //00001110左移5位,LED1亮
      delay(120);
      rGPBDAT = (0x0d<<5);    //00001101左移5位,LED2亮
      delay(120);
      rGPBDAT = (0x0b<<5);    //00001011左移5位,LED3亮
      delay(120);
      rGPBDAT = (0x07<<5);    //00000111左移5位,LED4亮
      delay(120);
*/
     //从LED1到LED4依次亮
     rGPBDAT=(0x0e<<5);
     delay(120);
     rGPBDAT<<=1;
     delay(120);
     rGPBDAT<<=1;
     delay(120);
     rGPBDAT<<=1;
     //从LED4到LED1依次亮
     rGPBDAT=0x0e0;
     delay(120);
     rGPBDAT>>=1;
     delay(120);
     rGPBDAT>>=1;
     delay(120);
     rGPBDAT>>=1;
     delay(120);
     //两边灯往中间亮
     rGPBDAT=0x0c0;
     delay(120);
     rGPBDAT=0x120;
     delay(120);
     //全亮全灭两次
     rGPBDAT=0x0;
     delay(60);
     rGPBDAT=0x1e0;
     delay(60);
     rGPBDAT=0x0;
     delay(60);
     rGPBDAT=0x1e0;
     delay(60);
     //蜂鸣器响
     rGPBDAT=0x0f;
     delay(120);
     }
}

以上是我编写的例子,以下是摘自互联网

 

===========性感的分隔线============

KEY+LED测试

/*
LED IO控制,数据,上拉寄存器
*/
#define GPBCON (*(volatile unsigned *)0x56000010)
#define GPBDAT (*(volatile unsigned *)0x56000014)
#define GPBUP (*(volatile unsigned *)0x56000018)

/*
KEY IO控制,数据,上拉寄存器
*/
#define GPGCON (*(volatile unsigned *)0x56000060)
#define GPGDAT (*(volatile unsigned *)0x56000064)
#define GPGUP (*(volatile unsigned *)0x56000068)

寄存器地址,可参考2440的datasheet

/*
LED1-4对应的GPB5,GPB6,GPB7,GPB8


*/
#define GPB5_out (1<<(5*2))     //LED1
#define GPB6_out (1<<(6*2))     //LED2
#define GPB7_out (1<<(7*2))     //LED3
#define GPB8_out (1<<(8*2))     //LED4

LED,将十进制1左移多少位,对着datasheet从高位向底位自己手写一次,就明白了,刚开始我也不明白为什么用这样方式。

/*
K1-K6对应GPG0,GPG3,GPG5,GPG6,GPG7,GPG11
*/
#define GPG11_in ~(3<<(11*2))   //key6
#define GPG7_in ~(3<<(7*2))    //key5
#define GPG6_in ~(3<<(6*2))    //key4
#define GPG5_in ~(3<<(5*2))    //key3
#define GPG3_in ~(3<<(3*2))    //key2
#define GPG0_in ~(3<<(0*2))    //key1
int main()
{
/*用作读取KEY状态值*/
unsigned long dwDat=0;
/*LED1~LED4对应的4根引脚设为输出*/
GPBCON=GPB5_out | GPB6_out | GPB7_out | GPB8_out; //将输出的引脚在配置寄存器中设为01
/*KEY1-KEY6对应的6根引脚设为输入*/
GPGCON=GPG11_in & GPG7_in & GPG6_in & GPG5_in & GPG3_in & GPG0_in;//讲输入的引脚在配置寄存器中设为00
/*关闭KEY和LED的引脚上拉*/
GPBUP=0xFFFFFFFF;
GPGUP=0xFFFFFFFF;



while(1)
{
   GPBDAT=0xFFFFFFFF;
   dwDat=GPGDAT;                  //读取KEY引脚状态
   if(dwDat & (1<<11))            //key6是否按下 按下时,电压拉入地,为低电平,状态0
   {
    GPBDAT |=(1<<5);            //熄灭LED1
   }else{
    GPBDAT &=~(1<<5);           //点亮LED1
   }
  
   if(dwDat & (1<<7))             //判断KEY5是否按下
   {
    GPBDAT |=(1<<6);            //熄灭LED2
   }else{
    GPBDAT &=~(1<<6);           //点亮LED2
   }
  
   if(dwDat & (1<<6))            //key4
   {
    GPBDAT |=(1<<7);
   }else{
    GPBDAT &=~(1<<7);
   }
  
   if(dwDat & (1<<5))             //key3
   {
    GPBDAT |=(1<<8);
   }else{
    GPBDAT &=~(1<<8);
   }
  
   if(dwDat & (1<<3))              //key2
   {
    GPBDAT |=(1<<5) | (1<<6);
   }else{
    GPBDAT &=~((1<<5) | (1<<6));
   }
  
   if(dwDat & (1<<0))                  //key1
   {
    GPBDAT |=(1<<7) | (1<<8);
   }else{
    GPBDAT &= ~((1<<7) | (1<<8));
   }
   
}
return 0;
}

你可能感兴趣的:(c,IO,互联网,测试,存储,delay)