s3c6410开发板LED驱动程序设计详细…
2 下面来看看tiny6410关于LED的原理图如图(1)所示:
3 LED实例,代码如下所示:(代码摘自\光盘4\实验代码\3-3-1\src\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( inttimes); -
void
LedPortInit( void); -
void
LedRun( void); -
-
-
int
main( void) -
{
-
LedPortInit(); -
LedRun(); -
}
-
-
-
void
delay( inttimes) -
{
-
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 程序代码分析:
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__
下面开始看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寄存器配置如下:
配置代码如下:
1
2
3
4
5
点亮LED:注意GPKDAT为16位寄存器,虽然由gpio.h中看到rGPIOKDAT为32位,只是相当于我们忽略了其中的高16位,因为数据是从低地址往高地址处依次存放的。
GPIO->rGPIOKDAT |=
LEDALL_OFF;
首先通过如下宏定义来表明LED的亮与灭。
#define LED1_ON
#define LED2_ON
#define LED3_ON
#define LED4_ON
#define LED1_OFF
#define LED2_OFF
#define LED3_OFF
#define LED4_OFF
#define LEDALL_OFF
(0xf<<4)
下面完成整个程序的运行步骤:
1 打开rvds
在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系统,如下图所示:
上图表明jlink已经正确链接上了。
然后需要配置AXD Debugge,让它使用J-Link来调试,通过以下方法启动AXD Debugger
启动AXD Debugger后,在AXD
Debugger主界面上打开主菜单的Options
可能AXD会提示找不到JLinkARM.DLL,如下图所示:
解决方法是:先不理会这个对话框,打开我的电脑,再次定位到J-Link的安装目录(默认是E:\Program Files\SEGGER\JLinkARM_V410i),将其中的JLinkARM.DLL文件拷贝到RVDS的安装目录下的Bin目录下(默认是C:\Program Files\ARM\ADSv1_2\Bin),再在上面的对话框上点击“确定”即可。
下面通过File->Load