以前实际上算的上是基本没有接触过嵌入式方面的东西,只是在以前学习过8位的单片机,可简单的东西哦!然后学过8086,80386的汇编语言编程和c语言以及windows的图形界面程序,所以这个飞凌的ok6410开发板拿到手以后真的觉得很陌生呢!都不知道怎么下手。看了看随板附带的视频和工具,大致有了一个了解。自己用一键烧写工具烧写了wince,linux,android系统,总算是有了一点点成就感了。当然了,不能停留在这个上面啦,本来安装了linux系统以后就可以用交叉编译工具编写c语言程序了,但是觉得没有意思啊,那样不是和pc机上写c语言大同小异了吗?于是我决定还是先写写裸机程序,熟悉一下ARM汇编语言和硬件吧!
第一个程序当然要挑选简单的写哦,熟悉了一下GPIO,会了简单的输入输出,就可以写一个流水灯了呢!那么GPIO是个什么东东呢?记得在pc机上,cpu是不能直接连接外设的哟,要通过相应的设备控制器,为什么要设备控制器呢?设备控制器就是cpu和外设通讯的接口,充当的是翻译员的工作哦,接口上有接口寄存器,cpu通过操作寄存器就可以操作外设了,就可以不用直接向外设的引脚写1和0了,简化了编程的难度哦!GPIO就是ARM上的一个设备控制器,诸如LED、BUZZER、KEYPAD都是连接在GPIO上面的呢!我的第一个程序,就是通过GPIO实现按键驱动LED灯和蜂鸣器。
操作GPIO必须要查看s3c6410的用户手册哦,没有这个可是不行的呢!当然笔者的英语也很差,能看懂的不到50%,但是对于现在来说,能看懂50%就够了哦,以后用到的东西,以后再说吧!@_@
GPIO一共187ge引脚,分为17组,每组的引脚数并不是相同的,LED灯连接在GPM0到GPM3这四个引脚上,这是从哪里看来的呢?是从电路图上哦,而且从电路图上可以看出这个LED灯是低电平亮哦!蜂鸣器呢?它是接在GPF15上哦,而且是高电平响哦,至于KeyPad,六个键分别占用了GPN0到GPN5,地点平有效。
现在我知道了我要操作的设备连在GPIO的哪个引脚上,那么我怎么来操作这些引脚呢?当然是用寄存器啦!去s3c6410的cpu手册中查看GPIO这一章节,就可以知道GPM,GPN,GPF分别的寄存器地址。我用到的寄存器有GPxCON和GPxDAT,首先要用GPxCON来配置引脚的功能,是用作输入、或者是输出。我把GPM0到GPM4配置为输出,把GPF15配置为输出,把GPN0到GPN5配置为输入,现在,就可以开始我们的主流程了哟!
那么还要解决一个很重要的问题,那就是程序的基本结构。到底这个程序怎样组织呢?这里,我用了最简单的方法,那就是cpu反复查询的方法,在一个whie死循环中,cpu不断的检查是否有按键,然后去设置LED灯或者是蜂鸣器。其实这是不可取的呢!因为这样会非常耗费cpu的,那么用什么最好呢?当然是中断啦!可是,第一个程序嘛!就先来个简单的啦!O(∩_∩)O~
首先是一段汇编:
IMPORT main
AREA Init, CODE, READONLY
CODE32
ENTRY
start
b main
END
为什么首先要有一段汇编呢?因为c编译器编出的程序是有一段头部的,在没有操作系统的情况下是不能正常运行的,所以一段汇编,直接跳到main函数处,这样就可以正常运行了哦!
然后是c语言程序啦!
#define rGPMCON (*(volatile unsigned int *)(0x7F008820))
#define rGPMDAT (*(volatile unsigned int *)(0x7F008824))
#define rGPMPUD (*(volatile unsigned int *)(0x7F008828))
#define rGPFCON (*(volatile unsigned int *)(0x7F0080A0))
#define rGPFDAT (*(volatile unsigned int *)(0x7F0080A4))
#define rGPFPUD (*(volatile unsigned int *)(0x7F0080A8))
#define rGPNCON (*(volatile unsigned int *)(0x7F008830))
#define rGPNDAT (*(volatile unsigned int *)(0x7F008834))
#define rGPNPUD (*(volatile unsigned int *)(0x7F008838))
void GPIO_Init(void);
void TestPad(void);
int main(void)
{
GPIO_Init();
TestPad();
}
void GPIO_Init(void)
{
unsigned int tmp;
/* Init Led regs */
tmp &= ~(0xFFFF);
tmp |= 0x1111;
rGPMCON = tmp;
rGPMPUD &= ~0xFF;
rGPMDAT |= 0xF;
/* Init Buzzer regs */
rGPFCON &= ~(0x1 << 31);
rGPFCON |= 0x1 << 30;
rGPFPUD &= ~(0x3 << 30);
rGPFDAT &= ~(0x1 << 15);
/* Init Keypad regs */
rGPNCON &= ~0xFFF;
rGPNPUD &= ~0xFFF;
}
void TestPad(void)
{
unsigned int KeyInput;
while (1)
{
KeyInput = 0;
KeyInput = rGPNDAT;
KeyInput &= 0x3F;
if ( (KeyInput & 1) == 0) /* == 比 & 的优先级要高 */
{
rGPMDAT |= 0xF;
rGPMDAT &= ~0x1;
}
else if ( (KeyInput & 2) == 0)
{
rGPMDAT |= 0xF;
rGPMDAT &= ~0x2;
}
else if ( (KeyInput & 4) == 0)
{
rGPMDAT |= 0xF;
rGPMDAT &= ~0x4;
}
else if ( (KeyInput & 8) == 0)
{
rGPMDAT |= 0xF;
rGPMDAT &= ~0x8;
}
else if ( (KeyInput & 16) == 0)
{
rGPFDAT |= (0x1 << 15);
}
else if ( (KeyInput & 32) == 0)
{
rGPFDAT &= ~(0x1 << 15);
}
}
}
好了,写完了,现在可以通过dnw软件和usb OTG接口将程序下载到RAM中运行了,我用的是JLINK下载,因为这样可以单步调试哦!