最近正在学习arm裸机,所用的
开发板是友善之臂的arm9-s3c2451开发板,发现没有向
STM32开发板那样可以用库函数开发,只能使用寄存器来开发,非常痛苦,在参考了stm32的封装以及前辈的指导下,我对s3c2451的GPIO口进行了初步封装,大大提高的开发效率,适合二次开发。
s3c2451.h
#ifndef _S3C2451_GPIO_H_
#define _S3C2451_GPIO_H_
#include "typedef.h"
typedef struct{
U32 GPCON; //配置端口引脚 输入/输出
U32 GPDAT; //配置高低电平
U32 GPUDP; //上拉 下拉设置
U32 GPSEL; //模式设置
}vola
tile *GPIO_MenMapPtr;//结构体存储,顺序对其即会补齐的,还有顺序很重要要对应地址,相差4
#define GPIOA_BASE_PTR ((GPIO_MenMapPtr)0x56000000) //每个i/o口的起始地址
#define GPIOB_BASE_PTR ((GPIO_MenMapPtr)0x56000010)
#define GPIOC_BASE_PTR ((GPIO_MenMapPtr)0x56000020)
#define GPIOD_BASE_PTR ((GPIO_MenMapPtr)0x56000030)
#define GPIOE_BASE_PTR ((GPIO_MenMapPtr)0x56000040)
#define GPIOF_BASE_PTR ((GPIO_MenMapPtr)0x56000050)
#define GPIOG_BASE_PTR ((GPIO_MenMapPtr)0x56000060)
#define GPIO_PIN0 (1<<0) //各个i/o口的第几个端口
#define GPIO_PIN1 (1<<1)
#define GPIO_PIN2 (1<<2)
#define GPIO_PIN3 (1<<3)
#define GPIO_PIN4 (1<<4)
#define GPIO_PIN5 (1<<5)
#define GPIO_PIN6 (1<<6)
#define GPIO_PIN7 (1<<7)
#define GPIO_PIN8 (1<<8)
#define GPIO_PIN9 (1<<9)
#define GPIO_PIN25 (1<<25)
#define GPIO_PIN26 (1<<26)
typedef enum
{
GPIOA=0,
GPIOB,
GPIOC,
GPIOD,
GPIOE,
GPIOF,
GPIOG
}GPIO_typedef; //枚举的使用方法,默认第一位为零当然自己也可以自己设变量的值
typedef enum
{
BIT_RESET=0, //低电平
BIT_SET //低电平
}BIT_typedef; //高低电平的设置
typedef enum
{
GPIO_MODE_IN=0, //输入模式
GPIO_MODE_OUT, //输出模式
GPIO_MODE_ALT1, //模式1
GPIO_MODE_ALT2 //模式2
}GPIO_MODE_typedef; //模式的选择
typedef enum
{
GPIO_UDP_DISABLE=0, //不使能设置
GPIO_UDP_DOWN, //下拉设置
GPIO_UDP_UP, //上拉设置
GPIO_UDP_NOAVAILABLE
}GPIO_UDP_typedef;
typedef struct
{
U32 pinx;
GPIO_MODE_typedef mode;
GPIO_UDP_typedef udp;
}GPIO_Init_typedef; //定义i/o口初始化结构体
extern void GPIO_INIT(GPIO_typedef portx,GPIO_Init_typedef gpio_init_typedef); //初始化函数
extern void GPIO_write(GPIO_typedef portx,U32 pinx,BIT_typedef bit); //写函数
extern BIT_typedef GPIO_read(GPIO_typedef portx,U32 pinx); //读函数
#endif
各个函数的实现
#include "s3c2451_gpio.h"
GPIO_MenMapPtr const PORT_BASE_PTR[7] = //端口数组,方便写入
{
GPIOA_BASE_PTR,
GPIOB_BASE_PTR,
GPIOC_BASE_PTR,
GPIOD_BASE_PTR,
GPIOE_BASE_PTR,
GPIOF_BASE_PTR,
GPIOG_BASE_PTR
};
void GPIO_INIT(GPIO_typedef portx,GPIO_Init_typedef gpio_init_typedef)
{
int i;
for(i=0;i<32;i++)
{
if((gpio_init_typedef.pinx && (1<
{
if(portx==GPIOA) //A口的工作模式设置
{
if(gpio_init_typedef.mode==GPIO_MODE_OUT) //判断A口是否为输出模式
{
PORT_BASE_PTR[portx]->GPCON &= ~(1<
}
else if(gpio_init_typedef.mode==GPIO_MODE_ALT1) //如果为其它工作模式
{
PORT_BASE_PTR[portx]->GPCON |=(1<
}
}
else //除A口之外的工作模式设置
{
PORT_BASE_PTR[portx]->GPCON &=~(0x3<<(2*i)); //先进行清零操作
PORT_BASE_PTR[portx]->GPCON |=(gpio_init_typedef.mode<<(2*i)); //对A口之外的端口进行模式设置
PORT_BASE_PTR[portx]->GPUDP &=~(0x3<<(2*i)); //进行清零操作
PORT_BASE_PTR[portx]->GPUDP |=(gpio_init_typedef.udp<<(2*i)); //进行UDP的功能模式设置
}
}
}
}
void GPIO_write(GPIO_typedef portx,U32 pinx,BIT_typedef bit)
{
if(bit==BIT_SET) //判断某个PORT口的某个位是否置高
{
PORT_BASE_PTR[portx]->GPDAT |=pinx; //如果是则将该位置为高电平
}
else if(bit == BIT_RESET) //反之则将该位置为低电平
{
PORT_BASE_PTR[portx]->GPDAT &=~pinx;
}
}
BIT_typedef GPIO_read(GPIO_typedef portx,U32 pinx)
{
if((PORT_BASE_PTR[portx]->GPDAT & pinx)==pinx ) //判断针脚是否为置高
{
return BIT_SET; //如果是则返回BIT_SET即1
}
else
{
return BIT_RESET; //如果是则返回BIT_RESET即0
}
}
原作者:luoyeyeye
0