GPIO,英文全称为General-Purpose IO ports,也就是通用IO口。嵌入式系统中常常有数量众多,但是结构却比较简单的外部设备/电路,对这些设备/电路有的需要CPU为之提供控制手段,有的则需要被CPU用作输入信号。而且,许多这样的设备/电路只要求一位,即只要有开/关两种状态就够了,比如灯亮与灭。对这些设备/电路的控制,使用传统的串行口或并行口都不合适。所以在微控制器芯片上一般都会提供一个“通用可编程IO接口”,即GPIO。
接口至少有两个寄存器,即“通用IO控制寄存器”与“通用IO数据寄存器”。数据寄存器的各位都直接引到芯片外部,而对这种寄存器中每一位的作用,即每一位的信号流通方向,则可以通过控制寄存器中对应位独立的加以设置。这样,有无GPIO接口也就成为微控制器区别于微处理器的一个特征。GPIO可以理解为挂在mcu总线上的寄存器,寄存器的位宽是总线的宽度,8051就是8位。通用IO数据寄存器引出几个脚,我们就得到了几个可用的GPIO。基于上述原因,在设置CC2530 GPIO时,都是8bit地设置,例如P0=0xFE。为P0SEL和P0DIR赋值可以设定GPIO的功能和方向(input/output),改变的是GPIO控制寄存器;为P0赋值改变了GPIO的电平,改变的是GPIO数据寄存器。
在实际的MCU中,GPIO是有多种形式的。比如,有的数据寄存器可以按照位寻址,有些却不能按照位寻址,这在编程时就要区分了。比如传统的8051系列,就区分成可位寻址和不可位寻址两种寄存器。另外,为了使用的方便,很多mcu把glue logic等集成到芯片内部,增强了系统的稳定性能,比如GPIO接口除去两个标准寄存器必须具备外,还提供上拉寄存器,可以设置IO的输出模式是高阻,还是带上拉的电平输出,或者不带上拉的电平输出。这在电路设计中,外围电路就可以简化不少。
另外需要注意的是,对于不同的计算机体系结构,设备可能是端口映射,也可能是内存映射的。如果系统结构支持独立的IO地址空间,并且是端口映射,就必须使用汇编语言完成实际对设备的控制,因为C语言并没有提供真正的“端口”的概念。如果是内存映射,那就方便的多了。
二、设定GPIO的功能与方向
在ioCC2530.h文件中,规定了
/* Interrupt Flags 5 */
SFRBIT( IRCON2 , 0xE8, _IRCON27, _IRCON26, _IRCON25, WDTIF, P1IF, UTX1IF, UTX0IF, P2IF )
SFR( RFIRQF0 , 0xE9 ) /* RF Interrupt Flags LSB */
SFR( T4CNT , 0xEA ) /* Timer 4 Counter */
SFR( T4CTL , 0xEB ) /* Timer 4 Control */
SFR( T4CCTL0 , 0xEC ) /* Timer 4 Channel 0 Capture/Compare Control */
SFR( T4CC0 , 0xED ) /* Timer 4 Channel 0 Capture/Compare Value */
SFR( T4CCTL1 , 0xEE ) /* Timer 4 Channel 1 Capture/Compare Control */
SFR( T4CC1 , 0xEF ) /* Timer 4 Channel 1 Capture/Compare Value */
SFR( B , 0xF0 ) /* B Register */
SFR( PERCFG , 0xF1 ) /* Peripheral I/O Control */
SFR( ADCCFG , 0xF2 ) /* ADC Input Configuration (legacy name) */
SFR( APCFG , 0xF2 ) /* Analog Periferal I/O Configuration */
SFR( P0SEL , 0xF3 ) /* Port 0 Function Select */
SFR( P1SEL , 0xF4 ) /* Port 1 Function Select */
SFR( P2SEL , 0xF5 ) /* Port 2 Function Select */
SFR( P1INP , 0xF6 ) /* Port 1 Input Mode */
SFR( P2INP , 0xF7 ) /* Port 2 Input Mode */
/* USART 1 Control and Status */
SFRBIT( U1CSR , 0xF8, U1MODE, U1RE, U1SLAVE, U1FE, U1ERR, U1RX_BYTE, U1TX_BYTE, U1ACTIVE )
SFR( U1DBUF , 0xF9 ) /* USART 1 Receive/Transmit Data Buffer */
SFR( U1BAUD , 0xFA ) /* USART 1 Baud Rate Control */
SFR( U1UCR , 0xFB ) /* USART 1 UART Control */
SFR( U1GCR , 0xFC ) /* USART 1 Generic Control */
SFR( P0DIR , 0xFD ) /* Port 0 Direction */
SFR( P1DIR , 0xFE ) /* Port 1 Direction */
SFR( P2DIR , 0xFF ) /* Port 2 Direction */
三、使用P0.0控制LED
P0SEL = 0x00; //功能选择,设为普通GPIO
P0DIR = 0xFF; //方向选择,全设为output
if ( zclSampleLight_OnOff == LIGHT_ON )
{
P0 = 0x01; //置P0.0为高电平,开灯
}
else
{
P0 = 0x00; //置P0.0为低电平,关灯
}