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

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

硬件平台:TQ2440 (S3C2440A)

开发环境:ADS1.2

时      间:2010-12-12

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

1:硬件电路:

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

2:2440的IO的配置

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

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

所以如图我们需要的是输出,故,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: }

转载于:https://www.cnblogs.com/Dreamxi/archive/2010/12/12/1903731.html

TQQ2440第二节:流水灯相关推荐

  1. 蓝桥杯51单片机之利用中断同时控制流水灯、数码管、独立按键、蜂鸣器【单片机开发初学者有趣综合案例】

    文章目录 一.流水灯与数码管 二.独立按键.数码管.流水灯.蜂鸣器 一.流水灯与数码管 流水灯不断左移,通过外部中断0来控制数码管的显示. #include <reg52.h> #defi ...

  2. 51单片机按键控制流水灯

    1.按键的使用 <1>独立按键的原理图 按键所对应的引脚为P3的0.1.2.3引脚口,并且这里总共有四个独立按键,它们公共的一段都接到了GND电源的负极.这样我们就知道按键上电的默认电平为 ...

  3. 基于51单片机《按键控制流水灯》

    1.用4个LED灯发光二极管实现至少四种灯光效果 2.可以通过输入按键在几种灯光之间切换 3.可以通过暂停按键停止彩色灯光效果,使小灯全亮,再次按下按键后继续之前的效果 4.增加自动在几种效果间切换功 ...

  4. STC51入门笔记(郭天祥C语言)---第二节:Keil 软件使用及流水灯设计

    声明:本篇文章只是个人知识盲区.知识弱点.重点部分的归纳总结,望各位大佬不喜勿喷.梳理顺序是按照书籍的实际顺序梳理,转载请注明出处. 作者:sumjess 本章详细介绍单片机程序常用编译软件 Keil ...

  5. 【紫光同创国产FPGA教程】【第二章】LED流水灯实验及仿真

    原创声明: 本原创教程由芯驿电子科技(上海)有限公司(ALINX)创作,版权归本公司所有,如需转载,需授权并注明出处(http://www.alinx.com). 适用于板卡型号: PGL22G/PG ...

  6. 第二节:delay()延时实现LED灯的闪烁。

    第二节:delay()延时实现LED灯的闪烁. 开场白:     上一节鸿哥列出了初学者七大误区,到底什么才是初学者关注的核心?那就是裸机奔跑的程序结构.一个好的程序结构,本身就是一个微型的多任务操作 ...

  7. C51教程 第二个51程序: 跑马灯 流水灯

    keil+proteus 第二个51程序 : 跑马灯 流水灯 这是一个AT89c51单片机教程,我们每次都会提供博文教程以及附带资料下载. 单片机就是一个小型CPU,在电子领域应用广泛,电视.冰箱.洗 ...

  8. 八位流水灯的verilog代码_Arduino入门 第七节-彗星灯 呼吸流水灯

    在前面的课程中,我们学习了流水灯.呼吸灯的实现方法,本期课程我们将把呼吸灯和流水灯"组合"到一起,做一个"呼吸流水灯"的效果.呼吸流水灯,实际上就是" ...

  9. STC51-Keil使用及流水灯设计

    1 Keil 工程建立及常用按钮介绍 1.1 KEIL5添加STC芯片库 首先我们需要这个STC的烧录软件,大家可以从STC官方网站  http://www.stcmcu.com/ 中下载到.     ...

最新文章

  1. python画树叶-使用Python turtle画分形树叶图
  2. boost::mpl模块实现find_if相关的测试程序
  3. smartupload 路径不存在_洞悉复杂金融场景,覆盖完备测试路径
  4. react实战课程_在使用React一年后,我学到的最重要的课程
  5. EasyUI加载树控件自动展开所有目录
  6. MySQL · BUG分析 · Rename table 死锁分析
  7. Linux下安装lingo教程-centos6 64位
  8. ios社交app源码_iOS中的社交媒体集成
  9. 活动策划方案具体流程
  10. oppo android root工具箱,oppo R11(全网通 安卓8.1)手机完美获取root教程,最强root工具,亲测可用!...
  11. Expandable Button
  12. linux查找文件夹命令
  13. 云服务器win10系统初始密码,win10忘记系统密码?教你重置-
  14. 和林格尔新区打造先进算力的“蓄水池”
  15. drcom linux最新版,Drcom-client.org 上线暨新版 PUM v1.0 发布
  16. wordpress改作cms备忘
  17. 暗斑怎么形成的_脸上出现暗斑的原因是什么?暗斑怎么形成的
  18. 详解 PerformanceResourceTiming API,咦,这货真的干!
  19. 苹果电脑macos Monterey 12.5(21G72)dmg原版引导版镜像下载
  20. 京冀41所医院和急救中心成为北京冬奥会定点医院

热门文章

  1. 神器Jinja2,用 Python 快速生成分析报告!
  2. 云表中文件列表的使用
  3. 高通(QCOM.US)一颗820A,撼动汽车芯片市场的开年之战
  4. 割绳子+html5,HTML5 【IE9割绳子】制作教程来袭····
  5. 仙之侠道2玖章各个任务详情_仙之侠道2玖章任务地点 | 手游网游页游攻略大全...
  6. 卡尔曼滤波与组合导航原理_基于RAEKF的GPS/INS紧组合导航方法研究
  7. CF1100D Dasha and Chess
  8. PHP 替换 全角空格
  9. 金 融 量 化 分 析 • 外 篇 • 绘 制 行 情 数 据 数 据 图
  10. webp格式转换成png的方法