IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 9.嵌入式控制器(Embedded Controller,EC)学习 GPIO开发流程 -> 正文阅读

[嵌入式]9.嵌入式控制器(Embedded Controller,EC)学习 GPIO开发流程


IT8502中各个引脚的描述见下表所示:

在嵌入式控制器EC的IT8502主控芯片中,通过芯片的数据手册可以得知,总共有10组GPIO,其中有7组GPIO中分别包含8个引脚,其他3组引脚分别包含4、7和6个引脚(在GPG[6,2:0]有4个引脚,GPH[6:0]中有7个引脚,在GPJ[5:0]中有6个引脚),引脚总数为73(8*7+7+6)。

接下来介绍GPIO中各个相关寄存器的作用和配置。

寄存器对应地址:

/* Spec.7.5.3 General Purpose I/O Port (GPIO)*/
#define GCR             (*(XBYTE *)0x1600)

#define GPIOA           (*(XBYTE *)0x1601)
#define GPIOB           (*(XBYTE *)0x1602)
#define GPIOC           (*(XBYTE *)0x1603)
#define GPIOD           (*(XBYTE *)0x1604)
#define GPIOE           (*(XBYTE *)0x1605)
#define GPIOF           (*(XBYTE *)0x1606)
#define GPIOG           (*(XBYTE *)0x1607)
#define GPIOH           (*(XBYTE *)0x1608)
#define GPIOI           (*(XBYTE *)0x1609)
#define GPIOJ           (*(XBYTE *)0x160A)
#define GPIOK           (*(XBYTE *)0x160B)
#define GPIOL           (*(XBYTE *)0x160C)
#define GPIOM           (*(XBYTE *)0x160D)

1.General Control Register (GCR),通用控制寄存器,地址0x160

这个寄存器只需要配置GCR[2-1],用于配置LPC复位使能与否,一般默认配置为失能LPC复位,即&GCR=0x06;

2.GPDRA—GPDRJ端口数据寄存器组(共10组)

配置该寄存器可以直接对输出引脚输出对应的高低电平,例如后面的代码中&GPIOA=0xF7,0xF7=0b11110111,意思是在GPIOA这组的8个引脚的第三个引脚输出低电平(如果配置为输出模式),其他七个引脚输出高电平(如果配置为输出模式)。其他几组GPIO原理相同。

3.Port Control n Registers (GPCRn, n = A0-I7),端口控制寄存器

在IT8502芯片中,有73个可用的GPIO,每个GPIO端口都有一个对应的端口控制寄存器用来配置端口的工作方式。

以GPCRAn为例来介绍GPCR的用法,大部分引脚的默认工作方式是GPI模式,也就是输入模式。

Bit7、Bit6用于配置端口引脚的模式,共三种,如下所示:

  • 00b,端口配置为复用功能
  • 01b,端口配置为输出模式
  • 10b,端口配置为输入模式

Bit5,Bit4,Bit3用于配置端口引脚的驱动能力

  • 000b,4mA驱动电流
  • 001b,8mA驱动电流
  • 010b,8mA驱动电流
  • 011b,12mA驱动电流
  • 110b,16mA驱动电流
  • 111b,16mA驱动电流

Bit2用于配置端口引脚的上拉,高电平使能

Bit1用于配置端口引脚的下拉,高电平使能

端口控制寄存器配置示例代码

/*-----------------------------------------------------------------------------
 * Parameter Definition
 *---------------------------------------------------------------------------*/
#define PALT            0x00
#define INPUT           0x80
#define OUTPUT          0x40
#define PULL_UP         0x04
#define PULL_DN         0x02
#define Driving4mA      0x00    //4mA
#define Driving8mA      0x10    //8mA
#define Driving12mA     0x18    //12mA
#define MaxDriving      0x38    //16mA

4.GPIO端口编程指导

编程步骤

  1. 配置各个端口相关寄存器的初始值(配置asInitGPIOReg)
  2. 使用各个端口相关寄存器的初始值配置GPIO端口的工作方式(Reset_Initialization()—》Init_GPIO())
  3. 在主循环中操作相关端口

端口初始化

InitGPIOReg数据结构,该数据结构用于保存端口初始化相关寄存器初始值的保存。

/*-----------------------------------------------------------------------------
 * Data Structure
 *---------------------------------------------------------------------------*/
typedef struct InitGPIOReg
{
    XBYTE   *reg;
    BYTE    value;
} sInitGPIOReg;

使用InitGPIOReg数据结构初始化所有端口默认工作模式

//-----------------------------------------------------------------------------
// External ram GPIO Registers
// Parameter: INPUT,OUTPUT,PALT,PULL_UP,PULL_DN
//-----------------------------------------------------------------------------
const sInitGPIOReg code asInitGPIOReg[] =
{
    { &GCR,             0x06            },  //

    { &GPIOA,           0xF7            },  // Port A Data port Init

    { &GPIO_A0_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_A1_CTRL,    INPUT           },
    { &GPIO_A2_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_A3_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_A4_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_A5_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_A6_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_A7_CTRL,    OUTPUT+PULL_UP  },

    { &GPIOB,           0xF8            },  // Port B Data port Init

    { &GPIO_B0_CTRL,    INPUT           },
    { &GPIO_B1_CTRL,    INPUT           },
    { &GPIO_B2_CTRL,    OUTPUT          },
    { &GPIO_B3_CTRL,    PALT+PULL_UP    },
    { &GPIO_B4_CTRL,    PALT+PULL_UP    },
    { &GPIO_B5_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_B6_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_B7_CTRL,    OUTPUT+PULL_UP  },

    { &GPIOC,           0x00            },  // Port C Data port Init

    { &GPIO_C0_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_C1_CTRL,    PALT+PULL_UP    },
    { &GPIO_C2_CTRL,    PALT+PULL_UP    },
    { &GPIO_C3_CTRL,    PALT+PULL_UP    },
    { &GPIO_C4_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_C5_CTRL,    OUTPUT          },
    { &GPIO_C6_CTRL,    INPUT+PULL_UP   },
    { &GPIO_C7_CTRL,    INPUT+PULL_UP   },

    { &GPIOD,           0x5C            },  // Port D Data port Init

    { &GPIO_D0_CTRL,    INPUT           },
    { &GPIO_D1_CTRL,    INPUT+PULL_UP   },
    { &GPIO_D2_CTRL,    INPUT+PULL_UP   },
    { &GPIO_D3_CTRL,    OUTPUT          },
    { &GPIO_D4_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_D5_CTRL,    INPUT+PULL_UP   },
    { &GPIO_D6_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_D7_CTRL,    PALT            },

    { &GPIOE,           0x04            },  // Port E Data port Init

    { &GPIO_E0_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_E1_CTRL,    INPUT+PULL_DN   },
    { &GPIO_E2_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_E3_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_E4_CTRL,    INPUT+PULL_UP   },
    { &GPIO_E5_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_E6_CTRL,    INPUT+PULL_DN   },
    { &GPIO_E7_CTRL,    PALT            },

    { &GPIOF,           0x40            },  // Port F Data port Init

    { &GPIO_F0_CTRL,    PALT            },
    { &GPIO_F1_CTRL,    PALT            },
    { &GPIO_F2_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_F3_CTRL,    INPUT+PULL_UP   },
    { &GPIO_F4_CTRL,    INPUT           },
    { &GPIO_F5_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_F6_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_F7_CTRL,    OUTPUT+PULL_UP  },

    { &GPIOG,           0x02            },  // Port G Data port Init

    { &GPIO_G0_CTRL,    PALT            },
    { &GPIO_G1_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_G2_CTRL,    INPUT           },
    { &GPIO_G3_CTRL,    PALT            },
    { &GPIO_G4_CTRL,    PALT            },
    { &GPIO_G5_CTRL,    PALT            },
    { &GPIO_G6_CTRL,    INPUT           },
    { &GPIO_G7_CTRL,    PALT            },

    { &GPIOH,           0x01            },  // Port H Data port Init

    { &GPIO_H0_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_H1_CTRL,    INPUT+PULL_DN   },
    { &GPIO_H2_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_H3_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_H4_CTRL,    INPUT+PULL_DN   },
    { &GPIO_H5_CTRL,    INPUT+PULL_DN   },
    { &GPIO_H6_CTRL,    OUTPUT+PULL_UP  },
    { &GPIO_H7_CTRL,    PALT            },

    { &GPIOI,           0x30            },  // Port I Data port Init

    { &GPIO_I0_CTRL,    INPUT           },
    { &GPIO_I1_CTRL,    INPUT           },
    { &GPIO_I2_CTRL,    INPUT           },
    { &GPIO_I3_CTRL,    INPUT           },
    { &GPIO_I4_CTRL,    INPUT           },
    { &GPIO_I5_CTRL,    INPUT           },
    { &GPIO_I6_CTRL,    INPUT           },
    { &GPIO_I7_CTRL,    INPUT           },

    { &GPIOJ,           0x00            },  // Port J Data port Init

    { &GPIO_J0_CTRL,    INPUT           },
    { &GPIO_J1_CTRL,    PALT            },
    { &GPIO_J2_CTRL,    PALT            },
    { &GPIO_J3_CTRL,    PALT            },
    { &GPIO_J4_CTRL,    INPUT           },
    { &GPIO_J5_CTRL,    INPUT           }

};
//-----------------------------------------------------------------------------
// The function of GPIO register init.
//-----------------------------------------------------------------------------
void Init_GPIO(void)
{
    BYTE iTemp;
    iTemp = 0x00;
    while( iTemp<(sizeof(asInitGPIOReg)/3) )
    {
        *asInitGPIOReg[iTemp].reg=asInitGPIOReg[iTemp].value;
        iTemp++;
    }

}

读取输入引脚的值(STATE_ACin()):

这里以监测适配器是否插入为例,在笔记本电脑中,在插入电源适配器后,电源充放电管理芯片会拉高AC_OK信号,EC接收该信号用于判断适配器的拔插状态,当AC_OK为高时,电源适配器为插入状态,当AC_OK信号为低时,电源适配器为拔除状态。假设充放电芯片的AC_OK与EC芯片的GPD1引脚连接。在前面的引脚初始化配置中已经将该引脚配置为输入模式了。

接下来需要在OEM_GPIO.H中定义宏STATE_ACin(),用读取GPD1引脚的输入值:

#define STATE_ACin()        IS_BIT_SET(GPIOD,1) //RCVV

在主循环中,例如在10ms事件轮询函数中,使用if语句来判断适配器的拔插状态,这里一般会使用上次状态来判断状态变化,当状态发生变化时才执行相应的操作

void Oem_Hook_Timer10ms(void)
{
	new_state = STATE_ACin();
	if(new_state != old_state) //适配器状态改变,插入或者拔出适配器
	{
		if(STATE_ACin()!= 0) //插入适配器
		{
			//1.适配器插入后点亮相应的指示灯
			//2.判断电池电量,进而是否进行充电操作
			//3.通过SCI Event通知操作系统适配器插入了
		}
		else //拔出适配器
		{
			//1.适配器拔出后熄灭相应的指示灯
			//2.通过SCI Event通知操作系统适配器拔出了
		}
		old_state = STATE_ACin();
	}

}

输出引脚输出高低电平,以大小写灯为例:

在大小写Caps按键按下后,大小写灯的状态会发生变换,大写状态时会点亮Caps灯,小写状态时会熄灭Caps灯。首先需要在宏定义中定义on/off

#define CAPLED_ON()     CLR_BIT(GPIOG,1)
#define CAPLED_OFF()    SET_BIT(GPIOG,1)

当矩阵键盘或者外接USB键盘有操作Caps按钮的操作时,代码中会操作这两个宏来实现相应的操作。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-05-07 11:20:04  更:2022-05-07 11:20:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:22:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码