目标:C语言实现点亮LED灯

首先是main函数,并不特殊,它是被系统调用来执行的,main函数结束后要返回调用main函数的地址处,那么裸机程序,没有操作系统做这些工作,就要自己写调用main函数的程序了。
软件相关的初始化:
1、设置栈 2、设置main函数返回地址 3、调用main 4、清理工作

所谓设置栈就是将栈指针SP指向某块内存,在S3C2440中这块内存可以是片内SRAM,这样不用初始化内存了,如果指向SDRAM,那么首先要初始化SDRAM。
硬件相关的初始化:
a、关闭看门狗;b、初始化时钟;c、初始化SDRAM等
软件相关初始化和硬件相关初始化结合一起就是启动文件。

下面是用C语言写的代码
这一段代码是汇编语言,作用相当于启动文件,在这里为了简单,在硬件方面初始化只关闭了看门狗,软件方面初始化设置了栈。

crt.S

.text
.global _start
_start:
ldr r0,=0x53000000 @看门狗地址
mov r1,#0x0
str r1,[r0] @写入0,关闭看门狗
ldr sp,=* @设置堆栈,注意不能大于4K bl main
halt_loop:
b halt_loop

分析这段汇编程序,首先初始化硬件相关的,关闭看门狗,然后设置堆栈,在s3c2440不能大于4K,因为s3c2440片内SRAM只有4K,再然后就是调到main函数,用了bl指令,bl有两个功能,一是跳转,二是设置了返回地址,就是bl    main指令的下一条指令b hail_loop,所以在这里就初始化完返回地址了。
下面就实现c语言的main函数。

#define GPFCON  (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054)
int
main()
{
GPFCON = 0x00000100;
GPFDAT = 0x00000000; return ;
}

2、用C语言轮流点亮LED

#define GPFCON  (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054)
#define GPF4_out ( 1 << 4*2 )
#define GPF5_out ( 1 << 5*2 )
#define GPF6_out ( 1 << 6*2 )
void
delay(volatile unsigned long dly)
{
for(;dly > ;dly--);
}
int
main()
{
unsigned i = ; GPFCON = GPF4_out | GPF5_out | GPF6_out;
while()
{
GPFDAT = ( ~( i << ) );
i *=;
if( i == )
{
i = ;
}
delay(); } return ;
}

Makefile

CFLAGS := -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -ffreestanding
led_on.bin:ctr.S main.c
arm-linux-gcc $(CFLAGS) -c -o ctr.o ctr.S
arm-linux-gcc $(CFLAGS) -c -o main.o main.c
arm-linux-ld -Ttext 0x00000000 ctr.o main.o -o led_on.elf
arm-linux-objcopy -O binary -S led_on.elf led_on.bin
arm-linux-objdump -D -m arm led_on.elf>led_on.dis
clean:
rm -f led_on.bin led_on.elf *.o led_on.dis

3、按键操作

#define GPFCON  (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054)
#define GPGCON (*(volatile unsigned long *)0x56000060)
#define GPGDAT (*(volatile unsigned long *)0x56000064) #define GPF4_out ( 1 << 4*2 )
#define GPF5_out ( 1 << 5*2 )
#define GPF6_out ( 1 << 6*2 ) #define GPF4_msk ( 3 << ( 4*2 ) )
#define GPF5_msk ( 3 << ( 5*2 ) )
#define GPF6_msk ( 3 << ( 6*2 ) ) #define GPF0_in ( 0 << 0*2 )
#define GPF2_in ( 0 << 2*2 )
#define GPG3_in ( 0 << 3*2 )
#define GPF0_msk ( 3 << ( 0*2 ) )
#define GPF2_msk ( 3 << ( 2*2 ) )
#define GPG3_msk ( 3 << ( 3*2 ) )
int
main( void )
{
unsigned long ysdat;
GPFCON &= ~( GPF4_msk | GPF5_msk | GPF6_msk );
GPFCON |= GPF4_out |GPF5_out | GPF5_out; GPFCON &= ~( GPF0_msk | GPF2_msk );
GPFCON |= GPF0_in |GPF2_in; GPGCON &= ~( GPG3_msk );
GPGCON |= GPG3_in; while()
{
ysdat = GPFDAT; if( ysdat & ( << ) )
{
GPFDAT |= ( << );
}
else
{
GPFDAT &= ~( << );
} if( ysdat & ( << ) )
{
GPFDAT |= ( << );
}
else
{
GPFDAT &= ~( << );
} ysdat = GPGDAT; if( ysdat & ( << ) )
{
GPFDAT |= ( << );
}
else
{
GPFDAT &= ~( << );
} } return ;
}

Makefile

CFLAGS := -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -ffreestanding
led_on.bin:ctr.S main.c
arm-linux-gcc $(CFLAGS) -c -o ctr.o ctr.S
arm-linux-gcc $(CFLAGS) -c -o main.o main.c
arm-linux-ld -Ttext 0x00000000 ctr.o main.o -o led_on.elf
arm-linux-objcopy -O binary -S led_on.elf led_on.bin
arm-linux-objdump -D -m arm led_on.elf>led_on.dis
clean:
rm -f led_on.bin led_on.elf *.o led_on.dis

通过嵌入式GPIO接口及操作(一)及这篇两个程序的练习,能够掌握对GPIO的操作,这是操作硬件的基本技能。

嵌入式GPIO接口及操作(二)的更多相关文章

  1. 嵌入式GPIO接口及操作(一)

    GPIO意思就是通用输入输出,一些引脚可以通过他们输出高低电平,或者通过它们读入引脚的状态.对GPIO的操作是对所有硬件的操作最基本的技能.一.通过寄存器来操作GPIO引脚,一个引脚可以用于输入.输出 ...

  2. GPIO接口解析【转】

    本文提供了一个linux下访问GPIO的约定的概述. 这些调用使用gpio_* 命名前缀.没有别的调用会使用这个前缀或是相关的__gpio_*前缀. 转自:http://blog.163.com/w5 ...

  3. 《嵌入式系统原理与接口技术》——嵌入式系统接口应用基础

    本文为我负责编写的电子工业出版社出版的<嵌入式系统原理与接口技术>一书第七章部分,这里整理的仍然是修改稿,供需要的同学参考,本书为普通高等教育"十二五"规划教材,电子信 ...

  4. C#中抽象类和接口的区别(二)

    一.抽象类: 抽象类是特殊的类,只是不能被实例化:除此以外,具有类的其他特性:重要的是抽象类可以包括抽象方法,这是普通类所不能的.抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们.另外 ...

  5. 玩转X-CTR100 | STM32F4 l GPIO位带操作

    更多塔克创新资讯欢迎登陆[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ]       STM32F4位带概念,及位带的GPIO操作实践应用. 原理介 ...

  6. Intel Edison —— 控制GPIO接口,网页显示传感器数值

    前言 原创文章,转载引用务必注明链接. 因为是使用Typora(markdown)写好然后复制到论坛的,推荐直接访问我的网站以获得更好地阅读体验. Intel XDK IoT 开发环境很久之前就上手了 ...

  7. {MySQL的库、表的详细操作}一 库操作 二 表操作 三 行操作

    MySQL的库.表的详细操作 MySQL数据库 本节目录 一 库操作 二 表操作 三 行操作 一 库操作 1.创建数据库 1.1 语法 CREATE DATABASE 数据库名 charset utf ...

  8. 第13章 GPIO—位带操作

    第13章     GPIO—位带操作 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fire ...

  9. GPIO—位带操作

    GPIO—位带操作本章参考资料:< STM32F4xx 中文参考手册>存储器和总线构架章节. GPIO 章节,< Cortex®-M4 内核编程手册> 2.2.5 Bit-ba ...

随机推荐

  1. Web API 2 入门——使用Web API与ASP.NET Web窗体(谷歌翻译)

    在这篇文章中 概观 创建Web窗体项目 创建模型和控制器 添加路由信息 添加客户端AJAX 作者:Mike Wasson 虽然ASP.NET Web API与ASP.NET MVC打包在一起,但很容易 ...

  2. laravel where筛选会判断类型吗?

    laravel where筛选会判断类型吗? laravel where筛选会判断类型吗? laravel where筛选会判断类型吗? 这个说会判断不对,说不会判断也不对. 当字符串'1'和数值1是 ...

  3. easyui学习笔记6—基本的Accordion(手风琴)

    手风琴也是web页面中常见的一个控件,常常用在网站后台管理中,这里我们看看easyui中基本的手风琴设置. 1.先看看引用的资源 <meta charset="UTF-8" ...

  4. NODE-环境变量的配置(踩坑总结)

    初学Node.js,从官网下载了node.js的Windows Installer,安装完成后,通过控制台输入node命令,发现提示说“node"不是内部或外部命令,这通常是由于没有设置环境 ...

  5. 推荐一个非常好用的Chrome扩展应用,用于美化Json字符串

    这个Chrome扩展应用的名称叫JSON Viewer Awesome 1.0.6: 安装之后,在Chrome工具栏会出现一个紫色的小图标: 然后可以把任意Json字符串直接贴到Chrome界面里: ...

  6. Task ‘run’ not found in root project

    问题现象: Task 'run' not found in root project 'springframework'. 问题原因: 没有在gradle.build文件中添加如下配置, mainCl ...

  7. Node.js在windows平台的安装

    nodejs官网:https://nodejs.org/en/ 下载安装: node-v8.4.0-x64.msi 检查 path 中是否已经配置nodejs的安装路径,如果没有要配置. node   ...

  8. 哈哈,原来IOC容器的bean是存在DefaultSingletonBeanRegistry的一个Map类型的属性当中。

    经过查看源代码发现IOC容器中的bean实例(不知道是不是所有的bean)是存储在一个DefaultSingletonBeanRegistry类实例的一个Map类型的属性当中. 下面是DefaultS ...

  9. jquery Jbox 插件实现弹出窗口在修改的数据之后,关闭弹出窗口刷新父页面的问题

    http://blog.csdn.net/nsdnresponsibility/article/details/51282797 问题如题: 这里我们在父页面定义一个全局的变量来标识是否需要刷新父页面 ...

  10. import(导入)过期的磁带 -----先留个引子,后期更改补充

    在某些情况下,客户需要恢复已经过期的磁带上的数据, 如果磁带没有被重新使用,数据没有被覆盖掉,可以使用 netbackup 的 import 方法将过期的磁带上的数据 import 到 netback ...