热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

第一部分:S5PV210_GPIO_LED_1

今天开始从ARM的最简单的部分开始写博客了那就是通过设置GPIO来点亮LED灯。第一步,先看原理图和硬件工作原理由硬件工作原理图我们可以知道,要想LED亮,只需要将GPJ0端

  今天开始从ARM的最简单的部分开始写博客了

  那就是通过设置GPIO来点亮LED灯。

第一步,先看原理图和硬件工作原理

 

由硬件工作原理图我们可以知道,要想LED亮,只需要将GPJ0端设置为低电平,并且为输出状态,就可以了,这里我们只设置前面三个GPJ0端口的。

对应的GPIO是:GPJO_3,GPJO_4,GPJO_5,

第二步,查看数据手册

(1)第一步,看涉及哪些寄存器

  

我们一共看到GPJ0相关的有6个寄存器,相应寄存器的作用是:

GPJ0CON:(地址:0xE0200240)(control)控制寄存器,配置各引脚的工作模式

GPJ0DAT:(地址:0xE0200244)(data)当引脚为输入/输出模式时,寄存器相应位和引脚高低电平一致

GPJ0PUD:(pull up down):控制引脚内部弱上拉,下拉

GPJ0DRV:(driver)配置引脚的驱动能力

GPJ0CONPDN:

GPJ0PUDPDN:

总结:也就是我们只需要写GPJ0CON寄存器和GPJ0DAT寄存器就可以了

(2)看GPJ0CON寄存器

往寄存器写1可以设置为输出模式了。(初始值为0,默认为输入模式)

(2)看GPJ0DAT寄存器

这里有两个问题:为什么设置为低电平和输出状态呢?

1.我们都知道电流是从电压高的流向电压低的时候,LED灯就会亮了,而左边端口是接高电压,所以右边端口就肯定是接低电平了,就设置为0就好了。

 

2.从数据手册我们可以看到:

  当端口被设置为输入模式的时候,我们寄存器GPJ0DAT所对应的位的数据(1或者0)是由GPJ0接口上的状态来决定的(高低电平)(也就是寄存器上的值是由GPJ0接口决定的).也就是端口上是低电平,那么寄存器上的值就是0.端口上是高电平,寄存器上的值就是1了。

  当端口被设置为输出模式的时候,GPJ0接口上的状态就和我们寄存器上的值是一样的(就是GPJ0接口上的状态是由寄存器上的值来决定的)。也就是说我们往寄存器上写0,端口上就是低电平;我们往寄存器上写1,端口上是就是高电平。

这就是我们为什么用输出模式了。往寄存器写0可以设置为低电平了。(初始值为0,默认为低电平)

第三步,写代码

先用汇编代码来写

(1)功能:全部灯亮

1  _start:                        //这里用的是ldr的伪命令,就是不用区分合法立即数还是非法立即数,=就是伪,%#就是真
2     ldr r0, =0xE0200240            //0xE0200240对应的是GPJ0CON寄存器,它就是控制接口的状态的,是输出还是输入
3     ldr r1, =0x11111111            //0x11111111就对应着8个接口的状态,1就表示输出状态,0就表示输入状态,每个接口就有
4     str r1, [r0]                //8个状态,其他状态可以查数据手册就知道了
5 ldr r0, =0x0 //这里的0表示的就是输出了低电平,如果是1的话就输出的是高电平 6 ldr r1, =0xE0200244 //0xE0200244对应的是GPJ0DAT寄存器,它就是用来输出什么的,是输出高电平还是低电平 7 str r0, [r1]

(2)功能:用位操作来实现指定的灯亮

 1 .global _start
 2  _start:                        
 3     ldr r0, =GPJ0CON            
 4     ldr r1, =0x11111111
 5     str r1, [r0]                    
 6     
 7     ldr r0, =(1<<3) | (0<<4) | (1<<5)        //这里就是使用了那个或运算,和左移,它的作用和0x2的作用一样            
 8     ldr r1, =GPJ0DAT                        //在中间加了那个0是为了比较容易看清楚代码的作用
 9     str r0, [r1]
10     
11     b .                                    //和那个b . 的作用是一样的啊

(3)功能:一个延迟函数的写法,及其汇编代码的解释

 1 delay:
 2     ldr r2, =9000000
 3     ldr r3, =0x0
 4     
 5 delay_loop:
 6     sub r2, r2, #1                        //这里就是等价于:sub r2, #1,其实就是r2 = r2 - 1;  
 7     cmp r2, r3                    
 8     bne delay_loop
 9     mov pc, lr                    
10     
11  
12  /*
13  总结:
14  1. bne用法:
15  bne指令: 非零则跳转
16 
17 个人总结:cmp 和bne连用: 先是用cmp进行那个比较,然后将比较的结果与0比较,如果不为0,则跳到bne紧跟着的标记(如bne sleep,则跳到sleep处)。就是说不相等就跳转。
18 
19 2.cmp的用法:
20 cmp是比较指令,cmp的功能相当于减法指令。它不保存结果,只是影响相应的标志位。ZF (Zero Flag):零标志位。
21 它记录相关指令执行后,其结果是否为0
22 其他的指令通过识别这些被影响的标志位来得知比较结果。
23 
24 cmp指令格式:   cmp   操作对象1, 操作对象2
25 
26 计算 操作对象1 - 操作对象2 但不保存结果,只是根据结果修改相应的标志位。
27 也就是说它把标志位修改成了1了。因为不相等就跳转,并且不为零就跳转
28 
29 3.b指令和bl指令的区别:
30 B或BL指令引起处理器转移到“子程序名”处开始执行。两者的不同之处在于BL指令在转移到子程序执行之前,
31 将其下一条指令的地址拷贝到R14(LR,链接寄存器)。由于BL指令保存了下条指令的地址,
32 因此使用指令“MOV PC ,LR”即可实现子程序的返回。而B指令则无法实现子程序的返回,只能实现单纯的跳转。
33 用户在编程的时候,可根据具体应用选用合适的子程序调用语句。
34 
35 b delay :就可以跳转到delay下面的那个程序那里执行了,和bl delay也可以
36 
37  */

用c语言来写

(1)功能:一闪一闪的

 1 #define GPJ0CON  0xE0200240            
 2 #define GPJ0DAT  0xE0200244
 3 
 4 void delay(void);
 5 
 6 //这个函数就用来实现一闪一闪的功能
 7 void led_blink(void)
 8 {
 9     unsigned int *p = (volatile unsigned int *)GPJ0CON;        //强制类型转换
10     unsigned int *p1 = (volatile unsigned int *)GPJ0DAT;
11     
12     *p = 0x11111111;                //把那个接口的模式调为输出模式
13     
14     while(1)            //死循环
15     {
16         //点亮
17         *p1 = (0<<3)|(0<<4)|(0<<5);        
18     
19         //延迟
20         delay();
21     
22         //熄灭
23         *p1 = (1<<3)|(1<<4)|(1<<5);                //这里写成了那个*p = (1<<3)|(1<<4)|(1<<5),出错了
24                                                 //就是把接口关闭了,所以后面就不亮了
25         //延迟
26         delay();
27     }
28 
29 }
30 
31 
32 void delay(void)
33 {
34     volatile unsigned int i = 900000;        //volatile的意思就是让编译器不对这进行那个优化了
35                                             //如果进行了优化,就可能起不到延迟的功能了
36     while(i--);
37 }

参考来源:朱老师物联网大教程


推荐阅读
  • 本文详细介绍了C语言的起源、发展及其标准化过程,涵盖了从早期的BCPL和B语言到现代C语言的演变,并探讨了其在操作系统和跨平台编程中的重要地位。 ... [详细]
  • 在进行QT交叉编译时,可能会遇到与目标架构不匹配的宏定义问题。例如,当为ARM或MIPS架构编译时,需要确保使用正确的宏(如QT_ARCH_ARM或QT_ARCH_MIPS),而不是默认的QT_ARCH_I386。本文将详细介绍如何正确配置编译环境以避免此类错误。 ... [详细]
  • Linux环境下进程间通信:深入解析信号机制
    本文详细探讨了Linux系统中信号的生命周期,从信号生成到处理函数执行完毕的全过程,并介绍了信号编程中的注意事项和常见应用实例。通过分析信号在进程中的注册、注销及处理过程,帮助读者理解如何高效利用信号进行进程间通信。 ... [详细]
  • 本文详细介绍了优化DB2数据库性能的多种方法,涵盖统计信息更新、缓冲池调整、日志缓冲区配置、应用程序堆大小设置、排序堆参数调整、代理程序管理、锁机制优化、活动应用程序限制、页清除程序配置、I/O服务器数量设定以及编入组提交数调整等方面。通过这些技术手段,可以显著提升数据库的运行效率和响应速度。 ... [详细]
  • 深入理解Java字符串池机制
    本文详细解析了Java中的字符串池(String Pool)机制,探讨其工作原理、实现方式及其对性能的影响。通过具体的代码示例和分析,帮助读者更好地理解和应用这一重要特性。 ... [详细]
  • 本文介绍如何从字符串中移除大写、小写、特殊、数字和非数字字符,并提供了多种编程语言的实现示例。 ... [详细]
  • 深入解析Java虚拟机(JVM)架构与原理
    本文旨在为读者提供对Java虚拟机(JVM)的全面理解,涵盖其主要组成部分、工作原理及其在不同平台上的实现。通过详细探讨JVM的结构和内部机制,帮助开发者更好地掌握Java编程的核心技术。 ... [详细]
  • 在编译BSP包过程中,遇到了一个与 'gets' 函数相关的编译错误。该问题通常发生在较新的编译环境中,由于 'gets' 函数已被弃用并视为安全漏洞。本文将详细介绍如何通过修改源代码和配置文件来解决这一问题。 ... [详细]
  • 对于许多初学者而言,遇到总线错误(bus error)或段错误(segmentation fault/core dump)是极其令人困扰的。本文详细探讨了这两种错误的成因、表现形式及解决方法,并提供了实用的调试技巧。 ... [详细]
  • Logback使用小结
    1一定要使用slf4j的jar包,不要使用apachecommons的jar。否则滚动生成文件不生效,不滚动的时候却生效~~importorg.slf ... [详细]
  • [Vue.js 3.0] Guide – Scaling Up – State Management
    [Vue.js 3.0] Guide – Scaling Up – State Management ... [详细]
  • cJinja:C++编写的轻量级HTML模板引擎
    本文介绍了cJinja,这是一个用C++编写的轻量级HTML模板解析库。它利用ejson来处理模板中的数据替换(即上下文),其语法与Django Jinja非常相似,功能强大且易于学习。 ... [详细]
  • 尾花|花萼_相关性Correlations 皮尔逊相关系数(pearson)和斯皮尔曼等级相关系数(spearman)
    尾花|花萼_相关性Correlations 皮尔逊相关系数(pearson)和斯皮尔曼等级相关系数(spearman) ... [详细]
  • QNX 微内核(procnto-instr)的监测版本内置了高级跟踪与分析工具,能够实现实时系统监控。该模块适用于单处理器及多处理器系统。 ... [详细]
  • YB02 防水车载GPS追踪器
    YB02防水车载GPS追踪器由Yuebiz科技有限公司设计生产,适用于车辆防盗、车队管理和实时追踪等多种场合。 ... [详细]
author-avatar
chung
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有