s3c6410裸机程序(1)

时间:2021-08-31 02:30:00

  嘿嘿,今天在博客园注册了新用户,来记录我的嵌入式学习流程,把自己的心得体会,教训经验,全部写出来,一来可以加深自己的印象,二来写出来让博客园中的高手看到,也可以给我批评指正哦 。@_@

  以前实际上算的上是基本没有接触过嵌入式方面的东西,只是在以前学习过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,地点平有效。

  s3c6410裸机程序(1)      s3c6410裸机程序(1)s3c6410裸机程序(1)s3c6410裸机程序(1)

  现在我知道了我要操作的设备连在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下载,因为这样可以单步调试哦!

  今天就到此为止了,等把中断写好了在更新博客。