zoukankan      html  css  js  c++  java
  • TQQ2440第二节:流水灯

    我是从学单片机才开始接触嵌入式,所以我一直都感觉还是从硬件在到上面的驱动,这样的而学习流程让我更加容易懂的一些,但是上班了发现公司没让我那样,一开始就给我一大批的代码,让我一段时间很消沉,不过现在也差不多熬过来了,但是回首这段时间,发现自己阅读那些令人费解的代码的能力有所提升把,但是现在自己还是打算从硬件到驱动好好的学习个彻底,上面启动代码没什么好说的,接着程序已经跳转到了c语言的入口Main函数这里了,接下来就会觉得很熟悉了(我也还是建议和我一样菜鸟的先不看那段启动代码,曾经在学校哪个启动代码让我费了很多的时间,想起来真的好不值,把其他的都会了,在回头看也就差不多了),好了开始正文了。

    —————————————————————————————————————————————

    硬件平台:TQ2440 (S3C2440A)

    开发环境:ADS1.2

    时      间:2010-12-12

    —————————————————————————————————————————————

    1:硬件电路:

    image

    可以看见是GPB5-8对应的LED1-4;所以相应的只要对相应的IO口进行操作就没有问题了;

    2:2440的IO的配置

    image

    这里是2440的IO口的引脚,需要注意的是,除了GPA之外,其他的都有INPUT和OUTPUT功能,这一点我们后面配置自己相关函数的时候会看到。

    所以我们只需要把GPB配置为IO口就好了。

    image

    所以如图我们需要的是输出,故,GPBCON=(0x01<<10);这样就把GPB5配置wie输出了,同理配置其他的管脚。

    3: 相关代码的实现

       1: #define    GPBCON        (*(volatile unsigned long *)0x56000010)
       2: #define    GPBDAT        (*(volatile unsigned long *)0x56000014)
       3: #define    GPB5_out    (1<<(5*2))
       4: #define    GPB6_out    (1<<(6*2))
       5: #define    GPB7_out    (1<<(7*2))
       6: #define    GPB8_out    (1<<(8*2))
       7: void  wait(unsigned long dly)
       8: {
       9:     for(; dly > 0; dly--);
      10: }
      11: /*这个LED_Test1函数是直接copy韦东山的那本书里的代码,感觉这个简单就不用写,之所以写这个是为了验证后面自己的写法*/
      12: void LED_Test1(void)
      13: {
      14:     unsigned long i = 0;
      15:     GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out;
      16:     
      17:     GPBDAT = (~(i<<5));         // 根据i的值,点亮LED1-4
      18:     if(++i == 16)
      19:         i = 0;
      20:     wait(30000);
      21: }
      22: void Main(void)
      23: {
      24:     
      25:     while(1)
      26:     {
      27:         LED_Test1();
      28:         LED_Test();
      29:     }
      30: }

    我因为在公司做驱动,感觉他门里面的代码的写法很不错,所以自己也打算改变一下写法,直接实现一个函数,对那组IO口的那个管脚配置和操作。

       1: #define IO_CON_BASE 0x56000000
       2: #define IO_DAT_BASE 0x56000004
       3: void GPIO_CONF_SET(unsigned int group,unsigned int index,unsigned int type)
       4: {
       5:     unsigned int *p_add=NULL;
       6:     unsigned int addr = IO_CON_BASE + (group*0x10);
       7:     unsigned int io_reg = type<<(index<<1);
       8:     p_add=(unsigned int *)(addr); 
       9:     *p_add=*p_add&~(0x3<<(index<<1));
      10:     *p_add=*p_add|io_reg;
      11: }
      12: void GPIO_OUT_PUT(unsigned int group,unsigned int index,unsigned int outval)
      13: {
      14:     unsigned int *p_add=NULL;
      15:     unsigned int addr = IO_DAT_BASE + (group*0x10);
      16:     unsigned int io_reg = outval<<index;
      17:     p_add=(volatile unsigned int *)(addr); 
      18:     *p_add=*p_add&~(0x1<<index);
      19:     *p_add=*p_add|io_reg;
      20: }
      21: void  wait(unsigned long dly)
      22: {
      23:     for(; dly > 0; dly--);
      24: }
      25: void LED_Test(void)
      26: {
      27:     //-------------5.6.7.8 conf OutPut
      28:     GPIO_CONF_SET(1,5,1);
      29:     GPIO_CONF_SET(1,6,1);
      30:     GPIO_CONF_SET(1,7,1);
      31:     GPIO_CONF_SET(1,8,1);
      32:     //-------------LED flash
      33:         GPIO_OUT_PUT(1,5,1);
      34:         wait(30000);
      35:         GPIO_OUT_PUT(1,6,1);
      36:         wait(30000);
      37:         GPIO_OUT_PUT(1,7,1);
      38:         wait(30000);
      39:         GPIO_OUT_PUT(1,8,1);
      40:         wait(30000);
      41:         GPIO_OUT_PUT(1,5,0);
      42:         wait(30000);
      43:         GPIO_OUT_PUT(1,6,0);
      44:         wait(30000);
      45:         GPIO_OUT_PUT(1,7,0);
      46:         wait(30000);
      47:         GPIO_OUT_PUT(1,8,0);
      48:         wait(30000);
      49: }

    上面我把他改为p_add=*(unsigned int *)(addr);然后 p_add=p_add&~(0x3<<(index<<1));这样程序却跑不起来,不知道为什么,希望高手能解答一下。

    觉得这样还不是很完美所以想把他直接定义为宏定义,这样直接拷贝到其他的文件开头就能用了。免得还得去声明和定义函数;

    改造之后如下:

       1: #define IO_CON_BASE 0x56000000
       2: #define IO_DAT_BASE 0x56000004
       3: /*
       4: GPIO_CFG_SET说明:   group--表示是那组IO(注意没有GPA)
       5:                     index--表示这组中的那个引脚   
       6:                     type --表示是配置为输入还是输出等其他功能
       7: */
       8: #define GPIO_CFG_SET(group,index,type) do{\
       9:                         (*(volatile unsigned int*)(IO_CON_BASE+group*0x10))&=~(0x3<<index<<1);\
      10:                         (*(volatile unsigned int*)(IO_CON_BASE+group*0x10))|=(type<<index<<1);\
      11:                         }while(0)
      12:                         
      13: /*
      14: GPIO_DAT_SET说明:   group--表示是那组IO(注意没有GPA)
      15:                     index--表示这组中的那个引脚   
      16:                     val  --表示对此引脚写入的数据
      17: */
      18: #define GPIO_DAT_SET(group,index,val) do{\
      19:                         (*(volatile unsigned int*)(IO_DAT_BASE+group*0x10))&=~(0x1<<index);\
      20:                         (*(volatile unsigned int*)(IO_DAT_BASE+group*0x10))|=(val<<index);\
      21:                         }while(0)
      22: /*
      23: 因为GPA的控制寄存器,每个引脚只只占用一位,所以为了能统一这里,就没有把
      24: GPA加进来,而后面的GPB-GPJ的控制寄存器每个引脚对应2位
      25: */                        
      26: enum{GPB=1,GPC,GPD,GPE,GPF,GPG,GPH,GPI,GPJ};
      27: /*
      28: 从GPB开始由于用两位表示此引脚的功能所以有四种可能
      29: 0代表INPUT,1代表OUTPUT,2代表第三功能,3代表第四功能
      30: */
      31: enum{INPUT=0,OUTPUT,THI_FUNC,FOR_FUNC};
      32: /*
      33: 定义高低电平
      34: */
      35: enum{LOW=0,HIG};
      36: void  wait(unsigned long dly)
      37: {
      38:     for(; dly > 0; dly--);
      39: }
      40: void LED_Test(void)
      41: {
      42:     //-------------5.6.7.8 conf OutPut
      43:     GPIO_CFG_SET(GPB,5,OUTPUT);
      44:     GPIO_CFG_SET(GPB,6,OUTPUT);
      45:     GPIO_CFG_SET(GPB,7,OUTPUT);
      46:     GPIO_CFG_SET(GPB,8,OUTPUT);
      47:     //-------------LED flash
      48:     GPIO_DAT_SET(GPB,5,HIG);
      49:     wait(30000);
      50:     GPIO_DAT_SET(GPB,6,HIG);
      51:     wait(30000);
      52:     GPIO_DAT_SET(GPB,7,HIG);
      53:     wait(30000);
      54:     GPIO_DAT_SET(GPB,8,HIG);
      55:     wait(30000);
      56:     GPIO_DAT_SET(GPB,5,LOW);
      57:     wait(30000);
      58:     GPIO_DAT_SET(GPB,6,LOW);
      59:     wait(30000);
      60:     GPIO_DAT_SET(GPB,7,LOW);
      61:     wait(30000);
      62:     GPIO_DAT_SET(GPB,8,LOW);
      63:     wait(30000);    
      64: }
  • 相关阅读:
    java第19次
    Unity3D常用的生命周期函数
    Unity3D结合ZXing生成中间带图标的二维码并保存
    Unity查看当前内存使用情况(针对移动端开发)
    Unity 获取鼠标悬停位置下的UI或3D物体对象
    【Unity3D】获取鼠标在三维空间(世界坐标系)的位置
    【Unity3D—C#】按下任意按键,返回按键的名称 以及 KeyCode键码详解
    Unity UGUI获取鼠标在屏幕的准确点击位置
    ML-Agent:通过TF#使用训练完成的模型数据
    对《ml-agent:Win10下环境安装》更新
  • 原文地址:https://www.cnblogs.com/Dreamxi/p/1903731.html
Copyright © 2011-2022 走看看