智能车学习(二)—— GPIO学习

一、概述

     使用的是蓝宇的底层,主要有初始化管脚,设置管脚状态,反转管脚状态等。

二、代码重述:

1、头文件gpio.h

#ifndef GPIO_H       //防止重复定义(gpio_H  开头)
#define GPIO_H

#include "common.h"   //包含公共要素头文件

/*
 * 定义管脚方向
 */
typedef enum GPIO_CFG
{
    //这里的值不能改!!!
    GPI         = 0,                                //定义管脚输入方向      GPIOx_PDDRn里,0表示输入,1表示输出
    GPO         = 1,                                //定义管脚输出方向
} GPIO_CFG;

#define HIGH  1u
#define LOW   0u

// 端口号地址偏移量宏定义
#define PORTA    0
#define PORTB    1
#define PORTC    2
#define PORTD    3
#define PORTE    4

//===========================================================================
//函数名称:gpio_init
//函数返回:无
//参数说明:port:端口号+引脚号(gpio_cfg.h中宏定义,格式为PTXY,eg:PTA0) by BlueMountain 2015/10/8
//  
//         dir:引脚方向(0=输入,1=输出)
//         state:引脚初始状态(0=低电平,1=高电平)
//功能概要:初始化端口指定引脚作为GPIO引脚的功能,并定义为输入或输出,若是输出,
//         还指定初始状态是低电平或高电平
//===========================================================================
void gpio_init(PTxn port, uint8_t dir, uint8_t state);



//============================================================================
//函数名称:gpio_set
//函数返回:无
//参数说明:port:端口号+引脚号(gpio_cfg.h中宏定义,格式为PTXY,eg:PTA0) by BlueMountain 2015/10/8

//         pin:引脚号(0~31,实际取值由芯片的物理引脚决定)
//         state:引脚初始状态(0=低电平,1=高电平)
//功能概要:设定引脚状态为低电平或高电平
//============================================================================
void gpio_set(PTxn port, uint8_t state);



//===========================================================================
//函数名称:gpio_get
//函数返回:指定引脚的状态(1或0)
//参数说明:port:端口号+引脚号(gpio_cfg.h中宏定义,格式为PTXY,eg:PTA0) by BlueMountain 2015/10/8
//         pin:引脚号(0~31,实际取值由芯片的物理引脚决定)
//功能概要:获取指定引脚的状态(1或0)
//===========================================================================
uint8_t gpio_get(PTxn port1);



//===========================================================================
//函数名称:gpio_reverse
//函数返回:无
//参数说明:port:端口号+引脚号(gpio_cfg.h中宏定义,格式为PTXY,eg:PTA0) by BlueMountain 2015/10/8
//          pin:引脚号(0~31,实际取值由芯片的物理引脚决定)
//功能概要:反转指定引脚输出状态。
//===========================================================================
void gpio_reverse(PTxn port1);


#endif     //防止重复定义(gpio_H  结尾)

2、gpio.c

#include "gpio.h"   //包含本构件头文件

//注意这边有两个枚举
//各端口基地址放入常数数据组PORT_ARR[0]~PORT_ARR[4]中
const PORT_MemMapPtr PORT_ARR[]={PORTA_BASE_PTR,PORTB_BASE_PTR,
                               PORTC_BASE_PTR,PORTD_BASE_PTR,PORTE_BASE_PTR};
//GPIO口基地址放入常数数据组GPIO_ARR[0]~GPIO_ARR[4]中
const GPIO_MemMapPtr GPIO_ARR[]={PTA_BASE_PTR,PTB_BASE_PTR,
                                PTC_BASE_PTR,PTD_BASE_PTR,PTE_BASE_PTR};

//===========================================================================
//函数名称:gpio_init
//函数返回:无
//参数说明:port:端口号+引脚号(gpio_cfg.h中宏定义,格式为PTXY,eg:PTA0) by BlueMountain 2015/10/8
//  
//         dir:引脚方向(0=输入,1=输出)
//         state:引脚初始状态(0=低电平,1=高电平)
//功能概要:初始化端口指定引脚作为GPIO引脚的功能,并定义为输入或输出,若是输出,
//         还指定初始状态是低电平或高电平
//===========================================================================
void gpio_init(PTxn port, uint8_t dir, uint8_t state)
{

        //局部变量声明
    uint8_t portl;
   uint8_t pin ;
   PORT_MemMapPtr port_ptr;    //声明port_ptr为PORT结构体类型指针
    GPIO_MemMapPtr gpio_ptr;    //声明gpio_ptr为GPIO结构体类型指针
    portl = port/32 ; //port1=0、1、2、3、4
   pin = port%32 ;   //pin A口1-2 4-5 12-17  B口0-3 8-11 16-19 C口0-13 16-17
                           //  D口0-7 E口0-5 20-25 29-31
    //根据带入参数port,给局部变量port_ptr、gpio_ptr赋值(获得两个基地址)
    port_ptr = PORT_ARR[portl];  //获得PORT模块相应口基地址
    gpio_ptr = GPIO_ARR[portl];  //获得GPIO模块相应口基地址

    //因为管脚有复用功能 根据带入参数pin,指定该引脚功能为GPIO功能(即令引脚控制寄存器的MUX=0b001)
       port_ptr->PCR[pin] = PORT_PCR_MUX(1);

    //根据带入参数dir,决定引脚为输出还是输入
    if (1 == dir)   //希望为输出
       {
         BSET(pin,gpio_ptr->PDDR);     //数据方向寄存器的pin位=1,定义为输出
         gpio_set(port, state);   //调用gpio_set函数,设定引脚初始状态
       }
    else {        //希望为输入
        BCLR(pin,gpio_ptr->PDDR);  //数据方向寄存器的pin位=0,定义为输入
        gpio_set(port, state);   //调用gpio_set函数,设定引脚初始状态
    }
}

//============================================================================
//函数名称:gpio_set
//函数返回:无
//参数说明:port:端口号+引脚号(gpio_cfg.h中宏定义,格式为PTXY,eg:PTA0) by BlueMountain 2015/10/8
//         state:引脚初始状态(0=低电平,1=高电平)
//功能概要:设定引脚状态为低电平或高电平
//============================================================================
void gpio_set(PTxn port1, uint8_t state)
{
    //局部变量声明
    GPIO_MemMapPtr gpio_ptr;    //声明port_ptr为GPIO结构体类型指针
    uint8_t port;
    uint8_t pin ;
    port = port1/32 ;
    pin = port1%32 ;

    //根据带入参数port,给局部变量gpio_ptr赋值(GPIO基地址)
    gpio_ptr = GPIO_ARR[port];

    //根据带入参数state,决定引脚为输出1还是0
    if (1==state) {BSET(pin,gpio_ptr->PDOR);} else {BCLR(pin,gpio_ptr->PDOR);}
}

//===========================================================================
//函数名称:gpio_get
//函数返回:指定引脚的状态(1或0)
//参数说明:port:端口号+引脚号(gpio_cfg.h中宏定义,格式为PTXY,eg:PTA0) by BlueMountain 2015/10/8
//         pin:引脚号(0~31,实际取值由芯片的物理引脚决定)
//功能概要:获取指定引脚的状态(1或0)
//===========================================================================
uint8_t gpio_get(PTxn port1)
{
    //局部变量声明
    GPIO_MemMapPtr gpio_ptr;    //声明port_ptr为GPIO结构体类型指针(首地址)
    uint8_t port;
   uint8_t pin ;
   port = port1/32 ;
   pin = port1%32 ;

    //根据带入参数port,给局部变量port_ptr赋值(GPIO基地址)
    gpio_ptr = GPIO_ARR[port];

    //返回引脚的状态
    return ((BGET(pin,gpio_ptr->PDIR))>=1 ? 1:0);
}

//===========================================================================
//函数名称:gpio_reverse
//函数返回:无
//参数说明:port:端口号+引脚号(gpio_cfg.h中宏定义,格式为PTXY,eg:PTA0) by BlueMountain 2015/10/8
//          pin:引脚号(0~31,实际取值由芯片的物理引脚决定)
//功能概要:反转指定引脚输出状态。
//===========================================================================
void gpio_reverse(PTxn port1)
{
    //局部变量声明
    GPIO_MemMapPtr gpio_ptr;    //声明port_ptr为GPIO结构体类型指针(首地址)
    uint8_t port;
   uint8_t pin ;
   uint8_t state ;
   port = port1/32 ;
   pin = port1%32 ;

        //反转指定引脚输出状态
    //根据带入参数port,给局部变量port_ptr赋值(GPIO基地址)
    gpio_ptr = GPIO_ARR[port];
   state = ((BGET(pin,gpio_ptr->PDIR))>=1 ? 1:0) ;
  //    BSET(pin,gpio_ptr->PTOR);
   if (0==state) {BSET(pin,gpio_ptr->PDOR);} else {BCLR(pin,gpio_ptr->PDOR);}

}

三、学习的思考

     就目前看到的gpio的设置是不全面的,少了上拉,下拉等等的输入状态的设置,无法使用中断,所以在后续的学习应该可以找到。代码的话,可以直接进行调用。

原文地址:https://www.cnblogs.com/BlueMountain-HaggenDazs/p/4861940.html