主题 : 尝试写NanoPi2的.h文件 复制链接 | 浏览器收藏 | 打印
级别: 论坛版主
UID: 103400
精华: 0
发帖: 434
金钱: 2235 两
威望: 447 点
贡献值: 0 点
综合积分: 868 分
注册时间: 2014-04-24
最后登录: 2016-10-10
楼主  发表于: 2015-11-30 11:20

 尝试写NanoPi2的.h文件

以下全文转载自:http://weibo.com/p/1001603913811479380545  


尝试写NanoPi2的.h文件


上一篇微博讲解了51单片机的宏定义文件reg52.h。


这篇微博来讲述如何写NanoPi2的.h文件。

NanoPi2使用的是三星S5P4418处理器那么我们先找到S5P4418的数据手册。

友善之臂维基链接http://wiki.friendlyarm.com/wiki/index.php/NanoPi_2

在网页尾部的Resource可以下载到S5P4418_Users_Manual_Preliminary_Ver.0.10.pdf。

先来看一下51单片机如何控制GPIO,先来控制P0口的第一个pin不断输出高低电平。

#include “reg52.h”

void main(void)

{

    while(1)

   {

       P0 |= 0x01;//置P0.0为高电平

       P0 &= ~ (0x1);//置P0.0为低电平

    }

}

P0是在reg52.h文件中定义寄存器。

sfr P0 = 0x80;

在ARM中就不能用sfr来定义GPIO口的寄存器了,需要用define。

http://zhidao.baidu.com/link?url=SNAhipla-QBFpAhsD8BGC-lrQkFQO3gtO1Xmm9Yd3ZJ-E0U_7WWSPVEtH_EhTEVGJrDssZmK-R48ydQpwu1ztK

先看一段S5P4418的.h和.c文件控制GPIO高低电平的程序


gpio.h文件

#defineGPIOBOUT (*(volatile unsigned *)0xc001b000)  //GPIOE引脚输出电平设置

#define GPIOBOUTENB(*(volatile unsigned *)0xc001b004) //GPIOE引脚IO模式选择

#define GPIOBALTFN0(*(volatile unsigned *)0xc001b020) //GPIOE(0-15)引脚功能选择




main.c文件

#include"gpio.h"

void delay(unsigned int t)

{

    while(t--);


}

void main(void)

{

   /*初始化GPIOB*/

   GPIOBALTFN0 &= ~(0x3<<24);//清位

   GPIOBALTFN0 |= (0x2<<24);//置位,管脚为GPIO功能


   GPIOBOUTENB |= (0x1<<12);//设置GPIOB12为输出模式

   GPIOBOUT |= (0x1<<12);//先置GPIOB12为高电平

   /*初始化完毕*/

   while(1)

   {

       GPIOBOUT |= (0x1<<12);//高电平

       delay(2000000);

       GPIOBOUT &= ~(0x1<<12);//低电平

       delay(2000000);

    }

}




先看main.c

由于51是8位单片机,所以它的P0寄存器是8位的。

这里说一下S5P4418内部的寄存器全都是32位的。

8位的时候用两位十六进制数很好去计算对应位上的值。例如,只有第3位是1,那么对应的十六进制数就是0x08。32位数让我们一个个去算太麻烦,那么就可以采用左移的方式来对寄存器进行赋值。

GPIOBOUT是一个32位寄存器,对应32个管脚。给某位写1,对应管脚就会输出高电平,写0,对应管脚就会输出低电平。


某位置1,我们采用或运算的方式,0x1和1是一样的,(1<<12)就是将1左移12位,在12位处置1。(这样写能直接看出是给第几位置1)

GPIOBOUT |= (1<<12);//就是给12位置1




某位置0,我们采用与运算的方式,~(1<<12),还是这样写,只不过在前面加一个取反符号,就是将0左移12位,在12位处置0。

GPIOBOUT &= ~(1<<12);//就是给12位置0


是不是和51单片机程序一样呢。P0 |= (1<<3);//3位置1。区别在于S5P4418在使用IO口之前需要进行设置。下面是设置步骤

_1_设置端口复用功能

S5P4418内部有很多功能接口(PWM,SPI,HDMI等),外部有很多引脚,这些引脚可以作为普通GPIO,也可以作为内部功能接口的映射。这就是端口复用。

在使用端口引脚作为GPIO时需要设置为GPIO模式,通过GPIOxALTFN0和GPIOxALTFN1寄存器来设置。

_2_设置端口输入输出模式

在51单片机里不需要考虑设置任何东西就可以直接读写IO口。而S5P4418需要设置是输出模式还是输入模式。如需改变,需要重新设置。

通过GPIOxOUTENB来设置对应管脚的输入输出模式。对应位,置0是输入模式,置1是输出模式。

_3_端口的默认电平

这一步没必要加上,也有必要。根据电路连接结构,设置默认电平为高或低。


看完main.c,再来看gpio.h

从数据手册中找到对应寄存器的地址,按照如下形式写好就行了。

#define 寄存器名称 (*(volatile unsigned *)32位地址)


下面学习一下如何看数据手册中寄存器的定义

S5P4418的GPIO有ABCDE五个组。只要和GPIO相关的寄存器都分ABCDE五组。

在手册中他是以基址和变址来写的。

GPIOCOUT的地址就是(0xc001c000 + 0x000)  

分开写的目的也是方便看

再看GPIOxOUTENB

GPIOBOUTENB的地址就是(0xc001b000+0x004)


这还算简单,一看就懂。再来看一下这个。

这到底是几个地址呢?


图中有6个地址

UART0CLKENB地址为(0xC00A0000 + 0x9000)


UART1CLKENB地址为(0xC00A0000 + 0x8000)


UART2CLKENB地址为(0xC00A0000 + 0xA000)


UART3CLKENB地址为(0xC00A0000 + 0xB000)


UART4CLKENB地址为(0xC0060000 + 0xE000)


UART5CLKENB地址为(0xC0080000 + 0x4000)


到这里,应该会写S5P4418的.h文件了吧。

关于.h文件里的#ifndef和#endif 自行百度其作用

自己写了几个,当然可以去工程文件中去找各种.h

献上自己写的一个gpio.h


#ifndef _GPIO_H_

#define _GPIO_H_


/* 以下为寄存器的定义 */

/* GPIOxOUT 32位 */

#define GPIOAOUT (*(volatile unsigned *)0xC001A000)

#define GPIOBOUT (*(volatile unsigned *)0xC001B000)

#define GPIOCOUT (*(volatile unsigned *)0xC001C000)

#define GPIODOUT (*(volatile unsigned *)0xC001D000)

#define GPIOEOUT(*(volatile unsigned *)0xC001E000)


/* GPIOxOUTENB 32位 */

#define GPIOAOUTENB(*(volatile unsigned *)(0xC001A000 + 0x4))

#define GPIOBOUTENB (*(volatile unsigned *)(0xC001B000 + 0x4))

#define GPIOCOUTENB (*(volatile unsigned *)(0xC001C000 + 0x4))

#define GPIODOUTENB (*(volatile unsigned *)(0xC001D000 + 0x4))

#define GPIOEOUTENB (*(volatile unsigned *)(0xC001E000 + 0x4))


/* GPIOxDETMODE0 2位 */

#define GPIOADETMODE0 (*(volatile unsigned *)(0xC001A000 + 0x8))

#define GPIOBDETMODE0 (*(volatile unsigned *)(0xC001B000 + 0x8))

#define GPIOCDETMODE0 (*(volatile unsigned *)(0xC001C000 + 0x8))

#define GPIODDETMODE0 (*(volatile unsigned *)(0xC001D000 + 0x8))

#define GPIOEDETMODE0 (*(volatile unsigned *)(0xC001E000 + 0x8))


/* GPIOxDETMODE1 2位 */

#define GPIOADETMODE1 (*(volatile unsigned *)(0xC001A000 + 0xC))

#define GPIOBDETMODE1 (*(volatile unsigned *)(0xC001B000 + 0xC))

#define GPIOCDETMODE1 (*(volatile unsigned *)(0xC001C000 + 0xC))

#define GPIODDETMODE1 (*(volatile unsigned *)(0xC001D000 + 0xC))

#define GPIOEDETMODE1 (*(volatile unsigned *)(0xC001E000 + 0xC))


/* GPIOxINTENB 32位 */

#define GPIOAINTENB (*(volatile unsigned *)(0xC001A000 + 0x10))

#define GPIOBINTENB (*(volatile unsigned *)(0xC001B000 + 0x10))

#define GPIOCINTENB (*(volatile unsigned *)(0xC001C000 + 0x10))

#define GPIODINTENB (*(volatile unsigned *)(0xC001D000 + 0x10))

#define GPIOEINTENB (*(volatile unsigned *)(0xC001E000 + 0x10))


/* GPIOxDET 32位 */

#define GPIOADET (*(volatile unsigned *)(0xC001A000 + 0x14))

#define GPIOBDET (*(volatile unsigned *)(0xC001B000 + 0x14))

#define GPIOCDET (*(volatile unsigned *)(0xC001C000 + 0x14))

#define GPIODDET (*(volatile unsigned *)(0xC001D000 + 0x14))

#define GPIOEDET (*(volatile unsigned *)(0xC001E000 + 0x14))


/* GPIOxPAD 32位 */

#define GPIOAPAD (*(volatile unsigned *)(0xC001A000 + 0x18))

#define GPIOBPAD (*(volatile unsigned *)(0xC001B000 + 0x18))

#define GPIOCPAD (*(volatile unsigned *)(0xC001C000 + 0x18))

#define GPIODPAD (*(volatile unsigned *)(0xC001D000 + 0x18))

#define GPIOEPAD (*(volatile unsigned *)(0xC001E000 + 0x18))


/* GPIOxALTFN0 2位 */

#define GPIOAALTFN0 (*(volatile unsigned *)(0xC001A000 + 0x20))

#define GPIOBALTFN0 (*(volatile unsigned *)(0xC001B000 + 0x20))

#define GPIOCALTFN0 (*(volatile unsigned *)(0xC001C000 + 0x20))

#define GPIODALTFN0 (*(volatile unsigned *)(0xC001D000 + 0x20))

#define GPIOEALTFN0 (*(volatile unsigned *)(0xC001E000 + 0x20))


/* GPIOxALTFN1 2位 */

#define GPIOAALTFN1 (*(volatile unsigned *)(0xC001A000 + 0x24))

#define GPIOBALTFN1 (*(volatile unsigned *)(0xC001B000 + 0x24))

#define GPIOCALTFN1 (*(volatile unsigned *)(0xC001C000 + 0x24))

#define GPIODALTFN1 (*(volatile unsigned *)(0xC001D000 + 0x24))

#define GPIOEALTFN1 (*(volatile unsigned *)(0xC001E000 + 0x24))

/* GPIOxDETMODEEX 1位 */

#define GPIOADETMODEEX (*(volatile unsigned *)(0xC001A000 + 0x28))

#define GPIOBDETMODEEX (*(volatile unsigned *)(0xC001B000 + 0x28))

#define GPIOCDETMODEEX (*(volatile unsigned *)(0xC001C000 + 0x28))

#define GPIODDETMODEEX (*(volatile unsigned *)(0xC001D000 + 0x28))

#define GPIOEDETMODEEX (*(volatile unsigned *)(0xC001E000 + 0x28))




/* GPIOxDETENB 32位 */

#define GPIOADETENB (*(volatile unsigned *)(0xC001A000 + 0x3C))

#define GPIOBDETENB (*(volatile unsigned *)(0xC001B000 + 0x3C))

#define GPIOCDETENB (*(volatile unsigned *)(0xC001C000 + 0x3C))

#define GPIODDETENB (*(volatile unsigned *)(0xC001D000 + 0x3C))

#define GPIOEDETENB (*(volatile unsigned *)(0xC001E000 + 0x3C))




/* GPIOx_SLEW 32位 */

#define GPIOA_SLEW (*(volatile unsigned *)(0xC001A000 + 0x40))

#define GPIOB_SLEW (*(volatile unsigned *)(0xC001B000 + 0x40))

#define GPIOC_SLEW (*(volatile unsigned *)(0xC001C000 + 0x40))

#define GPIOD_SLEW (*(volatile unsigned *)(0xC001D000 + 0x40))

#define GPIOE_SLEW (*(volatile unsigned *)(0xC001E000 + 0x40))




/* GPIOx_SLEW_DISABLE_DEFAULT 32位 */

#define GPIOA_SLEW_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001A000 + 0x44))

#define GPIOB_SLEW_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001B000 + 0x44))

#define GPIOC_SLEW_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001C000 + 0x44))

#define GPIOD_SLEW_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001D000 + 0x44))

#define GPIOE_SLEW_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001E000 + 0x44))




/* GPIOx_DRV1 32位 */

#define GPIOA_DRV1 (*(volatile unsigned *)(0xC001A000 + 0x48))

#define GPIOB_DRV1 (*(volatile unsigned *)(0xC001B000 + 0x48))

#define GPIOC_DRV1(*(volatile unsigned *)(0xC001C000 + 0x48))

#define GPIOD_DRV1 (*(volatile unsigned *)(0xC001D000 + 0x48))

#define GPIOE_DRV1 (*(volatile unsigned *)(0xC001E000 + 0x48))




/* GPIOx_DRV1_DISABLE_DEFAULT 32位 */

#define GPIOA_DRV1_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001A000 + 0x4C))

#define GPIOB_DRV1_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001B000 + 0x4C))

#define GPIOC_DRV1_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001C000 + 0x4C))

#define GPIOD_DRV1_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001D000 + 0x4C))

#define GPIOE_DRV1_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001E000 + 0x4C))




/* GPIOx_DRV0 32位 */

#define GPIOA_DRV0 (*(volatile unsigned *)(0xC001A000 + 0x50))

#define GPIOB_DRV0 (*(volatile unsigned *)(0xC001B000 + 0x50))

#define GPIOC_DRV0 (*(volatile unsigned *)(0xC001C000 + 0x50))

#define GPIOD_DRV0 (*(volatile unsigned *)(0xC001D000 + 0x50))

#define GPIOE_DRV0 (*(volatile unsigned *)(0xC001E000 + 0x50))




/* GPIOx_DRV0_DISABLE_DEFAULT 32位 */

#define GPIOA_DRV0_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001A000 + 0x54))

#define GPIOB_DRV0_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001B000 + 0x54))

#define GPIOC_DRV0_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001C000 + 0x54))

#define GPIOD_DRV0_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001D000 + 0x54))

#define GPIOE_DRV0_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001E000 + 0x54))




/* GPIOx_PULLSEL 32位 */

#define GPIOA_PULLSEL (*(volatile unsigned *)(0xC001A000 + 0x58))

#define GPIOB_PULLSEL (*(volatile unsigned *)(0xC001B000 + 0x58))

#define GPIOC_PULLSEL (*(volatile unsigned *)(0xC001C000 + 0x58))

#define GPIOD_PULLSEL (*(volatile unsigned *)(0xC001D000 + 0x58))

#define GPIOE_PULLSEL (*(volatile unsigned *)(0xC001E000 + 0x58))




/* GPIOx_PULLSEL_DISABLE_DEFAULT 32位 */

#define GPIOA_PULLSEL_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001A000 + 0x5C))

#define GPIOB_PULLSEL_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001B000 + 0x5C))

#define GPIOC_PULLSEL_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001C000 + 0x5C))

#define GPIOD_PULLSEL_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001D000 + 0x5C))

#define GPIOE_PULLSEL_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001E000 + 0x5C))




/* GPIOx_PULLENB 32位 */

#define GPIOA_PULLENB (*(volatile unsigned *)(0xC001A000 + 0x60))

#define GPIOB_PULLENB (*(volatile unsigned *)(0xC001B000 + 0x60))

#define GPIOC_PULLENB (*(volatile unsigned *)(0xC001C000 + 0x60))

#define GPIOD_PULLENB (*(volatile unsigned *)(0xC001D000 + 0x60))

#define GPIOE_PULLENB (*(volatile unsigned *)(0xC001E000 + 0x60))




/* GPIOx_PULLENB_DISABLE_DEFAULT 32位 */

#define GPIOA_PULLENB_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001A000 + 0x64))

#define GPIOB_PULLENB_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001B000 + 0x64))

#define GPIOC_PULLENB_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001C000 + 0x64))

#define GPIOD_PULLENB_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001D000 + 0x64))

#define GPIOE_PULLENB_DISABLE_DEFAULT (*(volatile unsigned *)(0xC001E000 + 0x64))



#endif