s3c6410开发板LED驱动程序设计详细…
2 下面来看看tiny6410关于LED的原理图如图(1)所示:
图1 LED原理图
3 LED实例,代码如下所示:(代码摘自\光盘4\实验代码\3-3-1\src\main.c)
main.c
- #include "def.h"
- #include "gpio.h"
- #define LED1_ON ~(1<<4)
- #define LED2_ON ~(1<<5)
- #define LED3_ON ~(1<<6)
- #define LED4_ON ~(1<<7)
- #define LED1_OFF (1<<4)
- #define LED2_OFF (1<<5)
- #define LED3_OFF (1<<6)
- #define LED4_OFF (1<<7)
- #define LEDALL_OFF (0xf<<4)
- //GPIO
- #define GPIO_BASE (0x7F008000)
- //oGPIO_REGS类型在 gpio.h 中定义
- #define GPIO (( volatile oGPIO_REGS *)GPIO_BASE)
- //函数声明
- void delay(int times);
- void LedPortInit(void);
- void LedRun(void);
- int main(void)
- {
- LedPortInit();
- LedRun();
- }
- void delay(int times)
- {
- int i;
- for(;times>0;times--)
- for(i=0;i<3000;i++);
- }
- void LedPortInit(void)
- {
- u32 uConValue;
- uConValue = GPIO->rGPIOKCON0;
- uConValue &= ~(0xffff<<16);
- uConValue |= 0x1111<<16;
- GPIO->rGPIOKCON0 = uConValue;
- }
- void LedRun(void)
- {
- GPIO->rGPIOKDAT |= LEDALL_OFF;
- while(1)
- {
- GPIO->rGPIOKDAT &= LED1_ON;
- delay(1000);
- GPIO->rGPIOKDAT |= LEDALL_OFF;
- GPIO->rGPIOKDAT &= LED2_ON;
- delay(1000);
- GPIO->rGPIOKDAT |= LEDALL_OFF;
- GPIO->rGPIOKDAT &= LED3_ON;
- delay(1000);
- GPIO->rGPIOKDAT |= LEDALL_OFF;
- GPIO->rGPIOKDAT &= LED4_ON;
- delay(1000);
- GPIO->rGPIOKDAT |= LEDALL_OFF;
- }
- }
4 程序代码分析:
首先来看一下宏定义部分:#define GPIO_BASE (0x7F008000)
,此处定义了GPIO所有相关寄存器的初始地址,由芯片手册S3C6410X.pdf,第308页可以得到此地址。以下为手册截图。由下图2可以看出,GPIO相关寄存器的初始地址即为GPACON的地址0x7F008000。
图2 GPIO的内存映射地址
了解#define
GPIO ((
volatile oGPIO_REGS
*)GPIO_BASE)之前我们先来看看oGPIO_REGS的定义(代码摘自\光盘4\实验代码\3-3-1\src\peripheral\gpio.h)
gpio.h
- #ifndef __GPIO_H__
- #define __GPIO_H__
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include "def.h"
- typedef struct tag_GPIO_REGS
- {
- u32 rGPIOACON; //0x7F008000
- u32 rGPIOADAT;
- u32 rGPIOAPUD;
- u32 rGPIOACONSLP;
- u32 rGPIOAPUDSLP;
- u32 reserved1[3];
- u32 rGPIOBCON; //0x7F008020
- u32 rGPIOBDAT;
- u32 rGPIOBPUD;
- u32 rGPIOBCONSLP;
- u32 rGPIOBPUDSLP;
- u32 reserved2[3];
- u32 rGPIOCCON; //0x7F008040
- u32 rGPIOCDAT;
- u32 rGPIOCPUD;
- u32 rGPIOCCONSLP;
- u32 rGPIOCPUDSLP;
- u32 reserved3[3];
- u32 rGPIODCON; //0x7F008060
- u32 rGPIODDAT;
- u32 rGPIODPUD;
- u32 rGPIODCONSLP;
- u32 rGPIODPUDSLP;
- u32 reserved4[3];
- u32 rGPIOECON; //0x7F008080
- u32 rGPIOEDAT;
- u32 rGPIOEPUD;
- u32 rGPIOECONSLP;
- u32 rGPIOEPUDSLP;
- u32 reserved5[3];
- u32 rGPIOFCON; //0x7F0080A0
- u32 rGPIOFDAT;
- u32 rGPIOFPUD;
- u32 rGPIOFCONSLP;
- u32 rGPIOFPUDSLP;
- u32 reserved6[3];
- u32 rGPIOGCON; //0x7F0080C0
- u32 rGPIOGDAT;
- u32 rGPIOGPUD;
- u32 rGPIOGCONSLP;
- u32 rGPIOGPUDSLP;
- u32 reserved7[3];
- u32 rGPIOHCON0; //0x7F0080E0
- u32 rGPIOHCON1;
- u32 rGPIOHDAT;
- u32 rGPIOHPUD;
- u32 rGPIOHCONSLP;
- u32 rGPIOHPUDSLP;
- u32 reserved8[2];
- u32 rGPIOICON; //0x7F008100
- u32 rGPIOIDAT;
- u32 rGPIOIPUD;
- u32 rGPIOICONSLP;
- u32 rGPIOIPUDSLP;
- u32 reserved9[3];
- u32 rGPIOJCON; //0x7F008120
- u32 rGPIOJDAT;
- u32 rGPIOJPUD;
- u32 rGPIOJCONSLP;
- u32 rGPIOJPUDSLP;
- u32 reserved10[3];
- u32 rGPIOOCON; //0x7F008140
- u32 rGPIOODAT;
- u32 rGPIOOPUD;
- u32 rGPIOOCONSLP;
- u32 rGPIOOPUDSLP;
- u32 reserved11[3];
- u32 rGPIOPCON; //0x7F008160
- u32 rGPIOPDAT;
- u32 rGPIOPPUD;
- u32 rGPIOPCONSLP;
- u32 rGPIOPPUDSLP;
- u32 reserved12[3];
- u32 rGPIOQCON; //0x7F008180
- u32 rGPIOQDAT;
- u32 rGPIOQPUD;
- u32 rGPIOQCONSLP;
- u32 rGPIOQPUDSLP;
- u32 reserved13[3];
- u32 rSPCON; //0x7F0081A0
- u32 reserved14[3];
- u32 rMEM0CONSTOP; //0x7F0081B0
- u32 rMEM1CONSTOP; //0x7F0081B4
- u32 reserved15[2];
- u32 rMEM0CONSLP0; //0x7F0081C0
- u32 rMEM0CONSLP1; //0x7F0081C4
- u32 rMEM1CONSLP; //0x7F0081C8
- u32 reserved;
- u32 rMEM0DRVCON; //0x7F0081D0
- u32 rMEM1DRVCON; //0x7F0081D4
- u32 reserved16[10];
- u32 rEINT12CON; //0x7f008200
- u32 rEINT34CON; //0x7f008204
- u32 rEINT56CON; //0x7f008208
- u32 rEINT78CON; //0x7f00820C
- u32 rEINT9CON; //0x7f008210
- u32 reserved17[3];
- u32 rEINT12FLTCON; //0x7f008220
- u32 rEINT34FLTCON; //0x7f008224
- u32 rEINT56FLTCON; //0x7f008228
- u32 rEINT78FLTCON; //0x7f00822C
- u32 rEINT9FLTCON; //0x7f008230
- u32 reserved18[3];
- u32 rEINT12MASK; //0x7f008240
- u32 rEINT34MASK; //0x7f008244
- u32 rEINT56MASK; //0x7f008248
- u32 rEINT78MASK; //0x7f00824C
- u32 rEINT9MASK; //0x7f008250
- u32 reserved19[3];
- u32 rEINT12PEND; //0x7f008260
- u32 rEINT34PEND; //0x7f008264
- u32 rEINT56PEND; //0x7f008268
- u32 rEINT78PEND; //0x7f00826C
- u32 rEINT9PEND; //0x7f008270
- u32 reserved20[3];
- u32 rPRIORITY; //0x7f008280
- u32 rSERVICE; //0x7f008284
- u32 rSERVICEPEND; //0x7f008288
- u32 reserved21;
- u32 reserved22[348];
- u32 rGPIOKCON0; //0x7f008800
- u32 rGPIOKCON1; //0x7f008804
- u32 rGPIOKDAT; //0x7f008808
- u32 rGPIOKPUD; //0x7f00880c
- u32 rGPIOLCON0; //0x7f008810
- u32 rGPIOLCON1; //0x7f008814
- u32 rGPIOLDAT; //0x7f008818
- u32 rGPIOLPUD; //0x7f00881c
- u32 rGPIOMCON; //0x7f008820
- u32 rGPIOMDAT; //0x7f008824
- u32 rGPIOMPUD; //0x7f008828
- u32 reserved23;
- u32 rGPIONCON; //0x7f008830
- u32 rGPIONDAT; //0x7f008834
- u32 rGPIONPUD; //0x7f008838
- u32 reserved24;
- u32 reserved25[16];
- u32 rSPCONSLP; //0x7f008880
- u32 reserved26[31];
- u32 rEINT0CON0; //0x7f008900
- u32 rEINT0CON1; //0x7f008904
- u32 reserved27[2];
- u32 rEINT0FLTCON0; //0x7f008910
- u32 rEINT0FLTCON1; //0x7f008914
- u32 rEINT0FLTCON2; //0x7f008918
- u32 rEINT0FLTCON3; //0x7f00891c
- u32 rEINT0MASK; //0x7f008920
- u32 rEINT0PEND; //0x7f008924
- u32 reserved28[2];
- u32 rSLPEN; //0x7f008930
- }
- oGPIO_REGS;
- #ifdef __cplusplus
- }
- #endif
- #endif //__GPIO_H__
由此可以看出oGPIO_REGS为一结构体,(( volatile oGPIO_REGS
*)GPIO_BASE)为指向此结构体的指针,该指针即GPIO指向的初始地址为GPIO_BASE(0x7F008000),通过使用此指针,可以遍历到从GPIO_BASE地址(0x7F008000)开始到0x7F008930地址处的所有寄存器。注意:上面结构体中所有元素,类型都是u32类型的,刚好四个字节,同时,由图2可知,如GPACON和GPADAT等寄存器地址都相差4,对于这段连续地址,如若中间没有对应某个寄存器,则用某些u32类型的数组填充,如u32
reserved1[3]等等。
下面开始看main.c中的main函数,main函数主要完成两个步骤,(1)LED初始化(LedPortInit()),(2)点亮LED(LedRun()).
LED初始化:
GPK总共有16个引脚,而每个引脚需要GPIO控制寄存器(GP*CON)使用4位来控制IO管脚的功能,即4*16=64位来控制所有GPK组的16个引脚。所以需要GPK使用了两个控制寄存器,GPKCON0和GPKCON1,从图1所示,我们使用的是GPK4,GPK5,GPK6,GPK7来控制LED灯的点亮与熄灭,所以此处我们只需使用GPKCON0来将GPK4,GPK5,GPK6,GPK7设置成输出功能。如图3所示,GPKCON寄存器配置如下:
图3 GPKCON寄存器配置图
配置代码如下:
1 .
u32 uConValue;
2 .
uConValue = GPIO->rGPIOKCON0;
3 .
uConValue &=
~(0xffff<<16);
0000 0000 0000 0000 1111 1111 1111 1111
4 .
uConValue |= 0x1111<<16;
5 .
GPIO->rGPIOKCON0 = uConValue;
首先我们要知道,在控制某个管脚的时候,我们不能去改变其它不使用管脚的状态,第二行获得GPKCON此时的状态将其赋给uConValue,第三行用于将GPKCON的高16位清零,低16位不变;第四行用于将GPKCON的高16为变为0001
0001 0001
0001(即GPK4,GPK5,GPK6,GPK7管脚都设置为输出模式),低16为仍然不变。最后将此值赋回到GPKCON寄存器当中。至此,完成整个LED的初始化工作。
点亮LED:注意GPKDAT为16位寄存器,虽然由gpio.h中看到rGPIOKDAT为32位,只是相当于我们忽略了其中的高16位,因为数据是从低地址往高地址处依次存放的。
GPIO->rGPIOKDAT |=
LEDALL_OFF;
//4个灯全灭
while(1)
{
GPIO->rGPIOKDAT &=
LED1_ON; //GPK4管脚的灯亮
delay(1000);
GPIO->rGPIOKDAT |=
LEDALL_OFF; //GPK4管脚的灯灭
GPIO->rGPIOKDAT &=
LED2_ON;
//GPK5管脚的灯亮
delay(1000);
GPIO->rGPIOKDAT |=
LEDALL_OFF; //GPK4管脚的灯灭
GPIO->rGPIOKDAT &=
LED3_ON;
//GPK6管脚的灯亮
delay(1000);
GPIO->rGPIOKDAT |= LEDALL_OFF; //GPK4管脚的灯灭
GPIO->rGPIOKDAT &=
LED4_ON; //GPK7管脚的灯亮
delay(1000);
GPIO->rGPIOKDAT |= LEDALL_OFF;
//GPK4管脚的灯灭
}
首先通过如下宏定义来表明LED的亮与灭。
#define LED1_ON
~(1<<4)
执行步骤:1<<4 -> ~(1<<4)
,对应步骤为:0000 0000 0000 0001->0000 0000 0001
0000->1111 1111 1110
1111
#define LED2_ON
~(1<<5)
#define LED3_ON
~(1<<6)
#define LED4_ON
~(1<<7)
#define LED1_OFF
(1<<4)
执行步骤:1<<4 对应步骤为:0000
0000 0000 0001->0000 0000 0001 0000
#define LED2_OFF
(1<<5)
#define LED3_OFF
(1<<6)
#define LED4_OFF
(1<<7)
#define LEDALL_OFF
(0xf<<4)
执行步骤:0xf<<4, 对应步骤为:0000 0000 0000 1111->0000 0000 1111 0000
下面完成整个程序的运行步骤:
1 打开rvds
新建一个空的arm可执行镜像LED:
在E:\tiny6410下自动多出一个LED目录
目录下自动创建了如下一些文件及文件夹:
将src目录和6410_scatter.txt拖入LED目录下:
将src下的代码直接拖入rvds:
得到如下添加代码后的工程,并打开main函数。
开始配置工程:
1 在汇编过程中选择处理器型号ARM1176JZF-S
2 在编译中选择处理器型号ARM1176JZF-S
3 在链接过程中选择scattered,文件选择scattered.txt
保存后,编译程序,出现如下错误:
解决方法:在配置框中的汇编的预处理中做如下设置:
然后点击Add,将VIC_MODE预处理值设为1:
保存后重新编译,编译通过,在Debug目录下会多出一个LED.axf文件,此文件为要运行在开发板的文件。
现在开始通过JLINK来调试开发板。首先链接开发板与jlink线。
将开发板上的S2拨到Nand
Flash启动那一侧,开启开发板电源,在超级终端上快速按下回车键,让U-Boot停留在功能选单上,不要让它进入Linux系统,如下图所示:
在XP里,点击开始菜单,选择程序->SEGGER->J-Link ARM
V4.10i->J-Link GDB Server,启动画面如下所示:
上图表明jlink已经正确链接上了。
然后需要配置AXD Debugge,让它使用J-Link来调试,通过以下方法启动AXD Debugger
启动AXD Debugger后,在AXD
Debugger主界面上打开主菜单的Options -> Configure
Target,在弹出的Choose Target对话框中,点击Add,
将会弹出文件选择对话框,在文件打开对话框中,定位到J-Link的安装目录(默认是E:\Program
Files\SEGGER\JLinkARM_V410i),在目录中选择JLinkRDI.dll打开即可,如下图所示:
可能AXD会提示找不到JLinkARM.DLL,如下图所示:
解决方法是:先不理会这个对话框,打开我的电脑,再次定位到J-Link的安装目录(默认是E:\Program
Files\SEGGER\JLinkARM_V410i),将其中的JLinkARM.DLL文件拷贝到RVDS的安装目录下的Bin目录下(默认是C:\Program
Files\ARM\ADSv1_2\Bin),再在上面的对话框上点击“确定”即可。
下面通过File->Load image,载入LED.axf文件,进行调试。
s3c6410开发板LED驱动程序设计详细…的更多相关文章
- 搭建S3C6410开发板的测试环境
因为ARM架构的开发板可基于X86架构的PC在CPU指令以及二进制上都有所不同,而且如果linux驱动需要访问硬件,这些硬件很难在PC上模拟,所以就需要我们在带有这些硬件的开发板上进行调试和测试. ...
- 第五章 搭建S3C6410开发板的测试环境
在PC上可以开发Linux驱动,重新编译成ARM架构的Linux驱动模块,但最后还是要在开发板上进行测试.目前最流行的是基于三星S3C6410 ARM11架构的开发板,很多厂商在其基础上进行了扩展,开 ...
- 第五章——搭建S3C6410开发板的测试环境
搭建S3C6410开发板的测试环境 通过本章的学习学会了如何在开发板上安装Android.开发板是学习和开发嵌入式技术的主要硬件设备,想要顺利的通过linux驱动访问硬件,是不能在PC板上模拟的,需要 ...
- S3C6410开发板开发环境的搭建
本节主要介绍了S3C6410开发板及OK6410开发板.OK6410开发板是基于ARM11处理器的S3C6410,采用“核心版+底板”结构 主要步骤如下:. OK6410开发板自带一个串口,PC也需要 ...
- 第五章 搭建S3C6410开发板测试环境
开发板是开发和学习嵌入式技术的主要设备.在这章中介绍了S3C6410开发板,它是三星公司推出的一款低功耗.高性价比的RISC处理器.安装串口调试工具:minicom.它的安装步骤:第1步:检测当前系统 ...
- linux 3.4.103 内核移植到 S3C6410 开发板 移植失败 (问题总结,日本再战!)
linux 3.4.103 内核移植到 S3C6410 开发板 这个星期差点儿就搭在这里面了,一開始感觉非常不值得,移植这样的浪费时间的事情.想立刻搞定,然后安安静静看书 & coding. ...
- Beaglebone Black开发板安装驱动
Beaglebone Black开发板安装驱动 Beaglebone Black开发板安装驱动,在使用Beaglebone Black开发板子做任何事情之前首先需要安装驱动.下面的内容就了展示在Win ...
- 搭建测试环境——针对S3C6410开发板
(一)前言 目前市面上的开发板型号和种类很多,但目前最流行的是基于三星S3C6410 ARM11架构的开发板.国内很多厂商在S3C6410 ARM11架构的开发板的基础上进行了扩展,开发了扩展板,本博 ...
- 迅为4412开发板Linux驱动教程/硬件知识及原理图的使用
视频教程下载地址:http://pan.baidu.com/s/1pJwxUfL 嵌入式研发流程介绍 • PCB研发流程介绍 – 方案,原理图(网表) – layoutproject师(gerber文 ...
随机推荐
- 解决 jsonP 安全问题
jsonp安全性防范,分为以下几点: 1.防止callback参数意外截断js代码,特殊字符单引号双引号,换行符均存在风险 2.防止callback参数恶意添加标签(如script),造成XSS漏洞 ...
- matlab中double和im2double
uint8的图像里 im2double其实就是double(I/255); 像素值被标准化到0-1. 16位图像以此类推.
- 3.了解linux系统以及搭建学习环境
目录: 1.linux的前世今生. 2.企业如何选择linux系统? 3.如何在虚拟机上安装linux系统?搭建学习环境. 1.linux的前世今生. 1).起源:先是贝尔实验室的Unix系统,因为各 ...
- Linux下shell命令 1
1 [root@hadoop-namenode-1 iebd] cd /filename/filename 跳转至filename文件夹 2 [root@hadoop-namenode-1 ...
- BZOJ - 1941 Hide and Seek (kd树)
题目链接 kd树模板题,求二维空间上的最远点/最近点. 对所有点建立kd树,分别查询每个点即可.单次查询期望时间复杂度$O(logn)$ #include<bits/stdc++.h> u ...
- python库之threading
This module constructs higher-level threading interfaces on top of the lower level python库之_threadmo ...
- Spring IOC容器的初始化-(三)BeanDefinition的注册
---恢复内容开始--- 前言 在上一篇中有一处代码是BeanDefiniton注册的入口,我们回顾一下. 1.BeanDefiniton在IOC容器注册 首先我们回顾两点,1. 发起注册的地方:2. ...
- 在Toad中导入导出数据
一.导出数据 右键点击所要导出的表名,选择“Export Date” 二.导入数据 一.右键点击表名,选择“import date” 二.下一步 三.下一步 四.下一步 在oracl ...
- 集群/分布式环境下,Session处理策略
前言 在搭建完集群环境后,不得不考虑的一个问题就是用户访问产生的session如何处理.如果不做任何处理的话,用户将出现频繁登录的现象.比如集中中存在A.B两台服务器,用户在第一次访问网站是,Ngin ...
- css学习笔记之图像
图像与文本的对齐方式: vertical-align:text-top;表示的意思是图像的顶部和同一行的文本对齐,但文本不会超出图片的上边线. vertical-align:middle;表示的意思是 ...