栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

合泰单片机 | HT66F3195 | 个人库开发过程 | 【5】GPIO - 基础属性配置

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

合泰单片机 | HT66F3195 | 个人库开发过程 | 【5】GPIO - 基础属性配置

GPIO

属性配置主要有以下几种:

  • 输入输出模式
  • 输出电平高低
  • 上拉电阻
  • 功能复用
  • 电流大小

操作,目前用得比较多的:

  • IO翻转

需要注意一点的是,PA组的引脚有8个,PB和PC组的引脚只有7个,PD组的引脚只有4个。

程序配置

GPIO.h

#ifndef	_GPIO_H_
#define	_GPIO_H_


#define	GPIO_Map_Group			0x01
#define	GPIO_Map_Pin			0x02


typedef enum
{
	GPIOA = 0x01,
	GPIOB = 0x02,
	GPIOC = 0x04,
	GPIOD = 0x08,

}GPIO_Group_T;


typedef enum
{
	Pin0 = 0x01,
	Pin1 = 0x02,
	Pin2 = 0x04,
	Pin3 = 0x08,
	Pin4 = 0x10,
	Pin5 = 0x20,
	Pin6 = 0x40,
	Pin7 = 0x80,

}GPIO_Pin_T;



#define	GPIOA_Get_Status()			_pa
#define	GPIOB_Get_Status()			_pb
#define	GPIOC_Get_Status()			_pc
#define	GPIOD_Get_Status()			_pd




#define	GPIOA_Set_Status			_pa
#define	GPIOB_Set_Status			_pb
#define	GPIOC_Set_Status			_pc
#define	GPIOD_Set_Status			_pd




#define	GPIOA_Set_Control			_pac
#define	GPIOB_Set_Control			_pbc
#define	GPIOC_Set_Control			_pcc
#define	GPIOD_Set_Control			_pdc




#define	GPIOA_Toggle()				_pa = ~_pa
#define	GPIOA_0_Toggle()			_pa0 ^= _pa0
#define	GPIOA_1_Toggle()			_pa1 ^= _pa1
#define	GPIOA_2_Toggle()			_pa2 ^= _pa2
#define	GPIOA_3_Toggle()			_pa3 ^= _pa3
#define	GPIOA_4_Toggle()			_pa4 ^= _pa4
#define	GPIOA_5_Toggle()			_pa5 ^= _pa5
#define	GPIOA_6_Toggle()			_pa6 ^= _pa6
#define	GPIOA_7_Toggle()			_pa7 ^= _pa7

#define	GPIOB_Toggle()				_pb = ~_pb
#define	GPIOB_0_Toggle()			_pb0 ^= _pb0
#define	GPIOB_1_Toggle()			_pb1 ^= _pb1
#define	GPIOB_2_Toggle()			_pb2 ^= _pb2
#define	GPIOB_3_Toggle()			_pb3 ^= _pb3
#define	GPIOB_4_Toggle()			_pb4 ^= _pb4
#define	GPIOB_5_Toggle()			_pb5 ^= _pb5
#define	GPIOB_6_Toggle()			_pb6 ^= _pb6

#define	GPIOC_Toggle()				_pc = ~_pc
#define	GPIOC_0_Toggle()			_pc0 ^= _pc0
#define	GPIOC_1_Toggle()			_pc1 ^= _pc1
#define	GPIOC_2_Toggle()			_pc2 ^= _pc2
#define	GPIOC_3_Toggle()			_pc3 ^= _pc3
#define	GPIOC_4_Toggle()			_pc4 ^= _pc4
#define	GPIOC_5_Toggle()			_pc5 ^= _pc5
#define	GPIOC_6_Toggle()			_pc6 ^= _pc6

#define	GPIOD_Toggle()				_pd = ~_pd
#define	GPIOD_0_Toggle()			_pd0 ^= _pd0
#define	GPIOD_1_Toggle()			_pd1 ^= _pd1
#define	GPIOD_2_Toggle()			_pd2 ^= _pd2
#define	GPIOD_3_Toggle()			_pd3 ^= _pd3




#define	GPIOA_Status(x)				_pa = x
#define	GPIOA_0_Status(x)			_pa0 = x
#define	GPIOA_1_Status(x)			_pa1 = x
#define	GPIOA_2_Status(x)			_pa2 = x
#define	GPIOA_3_Status(x)			_pa3 = x
#define	GPIOA_4_Status(x)			_pa4 = x
#define	GPIOA_5_Status(x)			_pa5 = x
#define	GPIOA_6_Status(x)			_pa6 = x
#define	GPIOA_7_Status(x)			_pa7 = x

#define	GPIOB_Status(x)				_pb = x
#define	GPIOB_0_Status(x)			_pb0 = x
#define	GPIOB_1_Status(x)			_pb1 = x
#define	GPIOB_2_Status(x)			_pb2 = x
#define	GPIOB_3_Status(x)			_pb3 = x
#define	GPIOB_4_Status(x)			_pb4 = x
#define	GPIOB_5_Status(x)			_pb5 = x
#define	GPIOB_6_Status(x)			_pb6 = x

#define	GPIOC_Status(x)				_pc = x
#define	GPIOC_0_Status(x)			_pc0 = x
#define	GPIOC_1_Status(x)			_pc1 = x
#define	GPIOC_2_Status(x)			_pc2 = x
#define	GPIOC_3_Status(x)			_pc3 = x
#define	GPIOC_4_Status(x)			_pc4 = x
#define	GPIOC_5_Status(x)			_pc5 = x
#define	GPIOC_6_Status(x)			_pc6 = x

#define	GPIOD_Status(x)				_pd = x
#define	GPIOD_0_Status(x)			_pd0 = x
#define	GPIOD_1_Status(x)			_pd1 = x
#define	GPIOD_2_Status(x)			_pd2 = x
#define	GPIOD_3_Status(x)			_pd3 = x

typedef enum 
{
	IO_Low = 0,
	IO_High = 1,
	IO_Error = 0xFF,

}GPIO_Status_T;




#define	GPIOA_Control(x)			_pac = x
#define	GPIOA_0_Control(x)			_pac0 = x
#define	GPIOA_1_Control(x)			_pac1 = x
#define	GPIOA_2_Control(x)			_pac2 = x
#define	GPIOA_3_Control(x)			_pac3 = x
#define	GPIOA_4_Control(x)			_pac4 = x
#define	GPIOA_5_Control(x)			_pac5 = x
#define	GPIOA_6_Control(x)			_pac6 = x
#define	GPIOA_7_Control(x)			_pac7 = x

#define	GPIOB_Control(x)			_pbc = x
#define	GPIOB_0_Control(x)			_pbc0 = x
#define	GPIOB_1_Control(x)			_pbc1 = x
#define	GPIOB_2_Control(x)			_pbc2 = x
#define	GPIOB_3_Control(x)			_pbc3 = x
#define	GPIOB_4_Control(x)			_pbc4 = x
#define	GPIOB_5_Control(x)			_pbc5 = x
#define	GPIOB_6_Control(x)			_pbc6 = x

#define	GPIOC_Control(x)			_pcc = x
#define	GPIOC_0_Control(x)			_pcc0 = x
#define	GPIOC_1_Control(x)			_pcc1 = x
#define	GPIOC_2_Control(x)			_pcc2 = x
#define	GPIOC_3_Control(x)			_pcc3 = x
#define	GPIOC_4_Control(x)			_pcc4 = x
#define	GPIOC_5_Control(x)			_pcc5 = x
#define	GPIOC_6_Control(x)			_pcc6 = x

#define	GPIOD_Control(x)			_pdc = x
#define	GPIOD_0_Control(x)			_pdc0 = x
#define	GPIOD_1_Control(x)			_pdc1 = x
#define	GPIOD_2_Control(x)			_pdc2 = x
#define	GPIOD_3_Control(x)			_pdc3 = x

typedef enum
{
	IO_Output = 0,
	IO_Input = 1,
}GPIO_Control_T;




#define	GPIOA_Pullup(x)				_papu = x
#define	GPIOA_0_Pullup(x)			_papu0 = x
#define	GPIOA_1_Pullup(x)			_papu1 = x
#define	GPIOA_2_Pullup(x)			_papu2 = x
#define	GPIOA_3_Pullup(x)			_papu3 = x
#define	GPIOA_4_Pullup(x)			_papu4 = x
#define	GPIOA_5_Pullup(x)			_papu5 = x
#define	GPIOA_6_Pullup(x)			_papu6 = x
#define	GPIOA_7_Pullup(x)			_papu7 = x

#define	GPIOB_Pullup(x)				_pbpu = x
#define	GPIOB_0_Pullup(x)			_pbpu0 = x
#define	GPIOB_1_Pullup(x)			_pbpu1 = x
#define	GPIOB_2_Pullup(x)			_pbpu2 = x
#define	GPIOB_3_Pullup(x)			_pbpu3 = x
#define	GPIOB_4_Pullup(x)			_pbpu4 = x
#define	GPIOB_5_Pullup(x)			_pbpu5 = x
#define	GPIOB_6_Pullup(x)			_pbpu6 = x

#define	GPIOC_Pullup(x)				_pcpu = x
#define	GPIOC_0_Pullup(x)			_pcpu0 = x
#define	GPIOC_1_Pullup(x)			_pcpu1 = x
#define	GPIOC_2_Pullup(x)			_pcpu2 = x
#define	GPIOC_3_Pullup(x)			_pcpu3 = x
#define	GPIOC_4_Pullup(x)			_pcpu4 = x
#define	GPIOC_5_Pullup(x)			_pcpu5 = x
#define	GPIOC_6_Pullup(x)			_pcpu6 = x

#define	GPIOD_Pullup(x)				_pdpu = x
#define	GPIOD_0_Pullup(x)			_pdpu0 = x
#define	GPIOD_1_Pullup(x)			_pdpu1 = x
#define	GPIOD_2_Pullup(x)			_pdpu2 = x
#define	GPIOD_3_Pullup(x)			_pdpu3 = x





#define	GPIOA_0_3_Current(x)		_sledc0 = (_sledc0&(~(REG_2_BIT<<0)))|(x<<0)
#define	GPIOA_4_7_Current(x)		_sledc0 = (_sledc0&(~(REG_2_BIT<<2)))|(x<<2)
#define	GPIOB_0_3_Current(x)		_sledc0 = (_sledc0&(~(REG_2_BIT<<4)))|(x<<4)
#define	GPIOB_4_6_Current(x)		_sledc0 = (_sledc0&(~(REG_2_BIT<<6)))|(x<<6)
#define	GPIOC_0_3_Current(x)		_sledc1 = (_sledc1&(~(REG_2_BIT<<0)))|(x<<0)
#define	GPIOC_4_6_Current(x)		_sledc1 = (_sledc1&(~(REG_2_BIT<<2)))|(x<<2)
#define	GPIOD_0_3_Current(x)		_sledc1 = (_sledc1&(~(REG_2_BIT<<4)))|(x<<4)

typedef enum
{
	IO_Current_Level1 = 0,
	IO_Current_Level2,
	IO_Current_Level3,
	IO_Current_Level4,
}GPIO_Current_T;




#define	GPIOA_0_Mode(x)		_pas0 = (_pas0&(~(REG_2_BIT<<0)))|(x<<0)
#define	GPIOA_1_Mode(x)		_pas0 = (_pas0&(~(REG_2_BIT<<2)))|(x<<2)
#define	GPIOA_2_Mode(x)		_pas0 = (_pas0&(~(REG_2_BIT<<4)))|(x<<4)
#define	GPIOA_3_Mode(x)		_pas0 = (_pas0&(~(REG_2_BIT<<6)))|(x<<6)
#define	GPIOA_4_Mode(x)		_pas1 = (_pas1&(~(REG_2_BIT<<0)))|(x<<0)
#define	GPIOA_5_Mode(x)		_pas1 = (_pas1&(~(REG_2_BIT<<2)))|(x<<2)
#define	GPIOA_6_Mode(x)		_pas1 = (_pas1&(~(REG_2_BIT<<4)))|(x<<4)
#define	GPIOA_7_Mode(x)		_pas1 = (_pas1&(~(REG_2_BIT<<6)))|(x<<6)

#define	GPIOB_0_Mode(x)		_pbs0 = (_pbs0&(~(REG_2_BIT<<0)))|(x<<0)
#define	GPIOB_1_Mode(x)		_pbs0 = (_pbs0&(~(REG_2_BIT<<2)))|(x<<2)
#define	GPIOB_2_Mode(x)		_pbs0 = (_pbs0&(~(REG_2_BIT<<4)))|(x<<4)
#define	GPIOB_3_Mode(x)		_pbs0 = (_pbs0&(~(REG_2_BIT<<6)))|(x<<6)
#define	GPIOB_4_Mode(x)		_pbs1 = (_pbs1&(~(REG_2_BIT<<0)))|(x<<0)
#define	GPIOB_5_Mode(x)		_pbs1 = (_pbs1&(~(REG_2_BIT<<2)))|(x<<2)
#define	GPIOB_6_Mode(x)		_pbs1 = (_pbs1&(~(REG_2_BIT<<4)))|(x<<4)

#define	GPIOC_0_Mode(x)		_pcs0 = (_pcs0&(~(REG_2_BIT<<0)))|(x<<0)
#define	GPIOC_1_Mode(x)		_pcs0 = (_pcs0&(~(REG_2_BIT<<2)))|(x<<2)
#define	GPIOC_2_Mode(x)		_pcs0 = (_pcs0&(~(REG_2_BIT<<4)))|(x<<4)
#define	GPIOC_3_Mode(x)		_pcs0 = (_pcs0&(~(REG_2_BIT<<6)))|(x<<6)
#define	GPIOC_4_Mode(x)		_pcs1 = (_pcs1&(~(REG_2_BIT<<0)))|(x<<0)
#define	GPIOC_5_Mode(x)		_pcs1 = (_pcs1&(~(REG_2_BIT<<2)))|(x<<2)
#define	GPIOC_6_Mode(x)		_pcs1 = (_pcs1&(~(REG_2_BIT<<4)))|(x<<4)

#define	GPIOD_0_Mode(x)		_pds0 = (_pds0&(~(REG_2_BIT<<0)))|(x<<0)
#define	GPIOD_1_Mode(x)		_pds0 = (_pds0&(~(REG_2_BIT<<2)))|(x<<2)
#define	GPIOD_2_Mode(x)		_pds0 = (_pds0&(~(REG_2_BIT<<4)))|(x<<4)
#define	GPIOD_3_Mode(x)		_pds0 = (_pds0&(~(REG_2_BIT<<6)))|(x<<6)

typedef enum
{
	IO_Mode1 = 0,
	IO_Mode2,
	IO_Mode3,
	IO_Mode4,
}GPIO_Mode_T;




#define	GPIOA_Wakeup(x)			_pawu = x
#define	GPIOA_0_Wakeup(x)		_pawu0 = x
#define	GPIOA_1_Wakeup(x)		_pawu1 = x
#define	GPIOA_2_Wakeup(x)		_pawu2 = x
#define	GPIOA_3_Wakeup(x)		_pawu3 = x
#define	GPIOA_4_Wakeup(x)		_pawu4 = x
#define	GPIOA_5_Wakeup(x)		_pawu5 = x
#define	GPIOA_6_Wakeup(x)		_pawu6 = x
#define	GPIOA_7_Wakeup(x)		_pawu7 = x




unsigned char GPIO_Map_Parameter_Check(GPIO_Group_T gpio, GPIO_Pin_T pin);
GPIO_Status_T GPIO_Map_Read(GPIO_Group_T gpio, GPIO_Pin_T pin);
void GPIO_Map_Write(GPIO_Group_T gpio, GPIO_Pin_T pin, GPIO_Status_T io_status);
void GPIO_Map_Control(GPIO_Group_T gpio, GPIO_Pin_T pin, GPIO_Control_T io_status);


#endif

GPIO的这个文件已经重新写过几遍了,但是至今我感觉都没有写好,不知道怎么形容,很难做到可以应付各种开发状况,兼顾代码可读性以及代码运行效率,目前的想法是,如果不能同时兼顾的话,其实可以在同一个文件中用两种写法,如果是对时间效率不高的话,可以采用写法A,配置GPIO各种属性的时候像STM32库那样,有各种参数检查,如果是对时间效率比较高的话比如短时间内要多次翻转IO这种,采用写法B,等同于直接操作寄存器那种,不过是被我多封装了一层宏。

多个GPIO映射关系

如果只是IO口普通应用的话,引用头文件已经可以完成大部分开发工作了。
下面这些代码是我某天突然想到的一种方法,不适合频繁调用,因为只是一些简单的操作要经历各种分支,时间上并不是很划算。
光是从代码上看其实有点抽象,要结合实际案例去理解就一下子能看明白。先把代码贴出来。

传入参数检查,之前也说过了,PB和PC只有7个,PD只有4个引脚,如果输入的参数类似PB7,PC7以及PD4~PD7都是不允许的。

unsigned char GPIO_Map_Parameter_Check(GPIO_Group_T gpio, GPIO_Pin_T pin)
{
	if((gpio == GPIOB)||(gpio == GPIOC))
    {
        if(pin & 0x80)
            return Parameter_Abnormal;
    }
    else if(gpio == GPIOD)
    {
        if(pin & 0xF0)
            return Parameter_Abnormal;
    }
    return Parameter_Normal;
}

多个GPIO状态读取。

GPIO_Status_T GPIO_Map_Read(GPIO_Group_T gpio, GPIO_Pin_T pin)
{
    GPIO_Status_T io_status;

    if(GPIO_Map_Parameter_Check(gpio, pin) == Parameter_Abnormal)
    	return (IO_Error);

    switch(gpio)
    {
        case GPIOA:     io_status = !!(GPIOA_Get_Status() & pin);   break;
        case GPIOB:     io_status = !!(GPIOB_Get_Status() & pin);   break;
        case GPIOC:     io_status = !!(GPIOC_Get_Status() & pin);   break;
        case GPIOD:     io_status = !!(GPIOD_Get_Status() & pin);   break;
        default:        io_status = (IO_Error);                 break;
    }
    return io_status;
}

多个GPIO输出电平配置。

void GPIO_Map_Write(GPIO_Group_T gpio, GPIO_Pin_T pin, GPIO_Status_T io_status)
{
	if(GPIO_Map_Parameter_Check(gpio, pin) == Parameter_Abnormal)
    	return ;

    if(io_status == IO_High)
    {
        switch(gpio)
        {
            case GPIOA:     GPIOA_Set_Status |= pin;        	break;
            case GPIOB:     GPIOB_Set_Status |= pin;        	break;
            case GPIOC:     GPIOC_Set_Status |= pin;        	break;
            case GPIOD:     GPIOD_Set_Status |= pin;        	break;
            default:                         		    		break;
        }
    }
    else if(io_status == IO_Low)
    {
        switch(gpio)
        {
            case GPIOA:     GPIOA_Set_Status &= (~pin);      	break;
            case GPIOB:     GPIOB_Set_Status &= (~pin);      	break;
            case GPIOC:     GPIOC_Set_Status &= (~pin);      	break;
            case GPIOD:     GPIOD_Set_Status &= (~pin);      	break;
            default:                             				break;
        }
    }
    return ;
}

多个GPIO输出输入模式配置。

void GPIO_Map_Control(GPIO_Group_T gpio, GPIO_Pin_T pin, GPIO_Control_T io_status)
{
	if(GPIO_Map_Parameter_Check(gpio, pin) == Parameter_Abnormal)
    	return ;

    if(io_status == IO_Input)
    {
        switch(gpio)
        {
            case GPIOA:     GPIOA_Set_Control |= pin;          	break;
            case GPIOB:     GPIOB_Set_Control |= pin;          	break;
            case GPIOC:     GPIOC_Set_Control |= pin;          	break;
            case GPIOD:     GPIOD_Set_Control |= pin;          	break;
            default:                             			 	break;
        }
    }
    else if(io_status == IO_Output)
    {
        switch(gpio)
        {
            case GPIOA:     GPIOA_Set_Control &= (~pin);    	break;
            case GPIOB:     GPIOB_Set_Control &= (~pin);    	break;
            case GPIOC:     GPIOC_Set_Control &= (~pin);    	break;
            case GPIOD:     GPIOD_Set_Control &= (~pin);    	break;
            default:                              				break;
        }
    }
    return ;
}

因为剩余的GPIO属性也不会经常配置,用头文件另一套写法也可以满足需求,就先这样子写了,后续看看有无特殊的需求或者更好的写法再进行更改。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/913787.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号