以下全文转载自:
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