CC2530的通用IO端口(GPIO)输入和输出控制

前言:

单片机基本结构:
在这里插入图片描述
单片机的程序开发过程:
在这里插入图片描述
单片机的程序运行:
在这里插入图片描述


1.CC2530引脚概述

CC2530微控制器采用QFN40封装,有40个引脚,21个数字IO端口

P0、P1为8位端口,P2为5位端口,此21个端口均可以通过编程进行配置
其中P1_0、P1_1具有20mA的输出驱动能力,其余部分只有4mA

特殊功能寄存器(SFR):微控制器内部的特殊功能的存储单元,用来存放控制微控制器内部器件的命令、数据或运行过程中的一些状态信息,操作微控制寄存器的本质:对SFR进行读写操作,某些SFR可以进行位寻址操作。

每一个SFR的本质:一个内存单元,使用内存地址标识内存单元
    为了方便记忆与使用,每个SFR都会起一个名字,在程序设计时,只要引入头文件ioCC2530.h,就可以直接使用寄存器的名称访问内存地址

1.1.CC2530的通用I/O端口(GPIO)相关的常用寄存器

PxSEL:端口功能选择,设置端口是通用I/O外设I/O

x端口号:0、1、2,可位寻址
默认情况下,复位后,所有数字输入/输出引脚都配置为通用输入引脚
0:通用I/O
1:外设I/O

PxDIR:作为通用I/O时,用来设置数据的传输方向

x端口号:0、1、2,可位寻址
P2DIR只有第0位至第4位是端口2的方向选择控制位,第6位和第7位是端口0外设优先级控制位
0:输入
1:输出

PxINP:作为通用输入端口时,选择输入模式时上拉下拉还是三态

默认情况下,复位后,输入配置为带有上拉的输入。如果要取消输入端口的上拉或下拉功能,必须将PxINP中的相应位设置为1
P2INP中,第0位至第4位是端口2的输入模式选择位,第5位至第7位是端口0、端口1、端口2的上下拉选择位

1.2.设置寄存器中某些位的方法

1.2.1.对寄存器的某些位清0而不影响其他位

使用 &= 将寄存器指定位清0,同时不影响其他位的值

例子: 寄存器P1TM当前值为0x6c,现需要将该寄存器的第1位、第3位和第5位设置为0,同时不影响该寄存器其他位的值,使用C语言实现:



分析:
    将 0000 0000中要操作的位 置10010 1010,将该数 取反1101 0101,十六进制为 ~0x2A,再将该值与寄存器P1TM 相与,就可实现要求
    P1TM当前值为 0x6c,二进制为 0110 1100,相与为 0110 1100 && 1101 0101 = 0100 0100,实现1、3、5位清0,而其他位不变

正确写法:
     P1TM &= ~0x2A;

注意:
    该方法只适用于操作 多位同时清0某一位清0的情况

1.2.2.对寄存器的某些位置1而不影响其他位

使用 |= 将寄存器指定位置1,同时不影响其他位的值

例子: 寄存器P1TM的当前值为0x6c,现需要将该寄存器的第1位,第4位和第5位置1,同时不能影响其他位的值,使用C语言实现


分析:
    将0000 0000中要操作的位置10011 0010,十六进制为 0x32,再将该值与寄存器P1TM相或,就可实现要求
    0110 1100 || 0011 0010 = 0111 1110,实现1、4、5位置1,而其他位不变

正确写法:
    P1TM |= 0x32;

注意:
    该方法只适用于多位同时置1某一位置1的情况

2.案例:按键输入控制灯光输出状态

要求:

在ZigBee的小模块上,实现2个案件分别控制2个LED灯开关的功能,即SW1按下后松开,LED5亮,SW1再次按下后松开,LED5灭。SW2以同样的方式控制LED6。电路连接如图:
在这里插入图片描述

设计思路:

1.设计一个端口初始化函数,对端口的功能进行配置,LED相关的端口设置为输出按键相关的端口设置为输入,并且配置成上拉模式
2. 在主函数中不断扫描按键端口的变化,没有按键按下,该端口为高电平,如果有按键按下,则为低电平。当发现按键端口有低电平时,先要进行去抖动处理
3. 因为一个按键有“开灯”和“关灯”两种状态,需要定义一个按键状态的全局变量来处理按键按下的时候,应该是亮LED还是关LED

  1. 准备工作
    引入CC2530必要的头文件,定义相关变量等
#include "ioCC2530.h"

#define LED5 P1_3
#define LED6 P1_4
#define SW1 P1_2
#define SW2 P0_1

unsigned char Stat_key = 0;   //按键状态全局变量

/*===================延时函数======================*/
void Delay(unsigned int t){
  
  while(t--);
}
  1. 端口功能选择
    微控制器的大部分I/O口都是功能复用的,在使用的时候需要通过功能选择寄存器来配置端口的功能

CC2530的特殊功能寄存器PxSEL是端口功能选择寄存器
PxSEL寄存器(端口功能选择):

P1SEL &= ~0x1c;//将P1_2、P1_3、P1_4设置为通用I/O口
P0SEL &= ~0X02;//将P0_1设置为通用I/O口

  1. 端口传输方向设置

PxDIR寄存器(端口方向设置):

P1DIR |= 0x18;//将P1_3和P1_4端口设置为输出
P1DIR &= ~0x04;//将P1_2设置为输入
P0DIR &= ~0x02;//将P0_1设置为输入

  1. 对于输入的端口

输入方式用来从外界器件获取输入的电信号,当CC2530的引脚为输入端口时,该端口能够提供“上拉”、“下拉”和“三态”三种输入模式,可以通过编程进行设置。在本案例中,实际上不需要对PO_ 1和P1_ 2引脚进行输入方式的设置,因为CC2530复位后,各个/O端口默认使用的就是上拉模式

P0INP寄存器和P1INP寄存器(端口输入方式设置):

P2INP寄存器(端口输入方式设置):

  1. 设计端口初始化函数InitPort()
  1. 设置P1SEL寄存器,将P1_2、P1_3和P1_4设置为通用I/O口
  2. 设置P1DIR寄存器,将P1_3和P1_4设置为输出,将P1_2设置为输入
  3. 设置P0SEL寄存器,将P0_1设置为通用I/O口
  4. 设置P0DIR寄存器,将P0_1设置为输入
  5. 将PxINP寄存器,将P1_3和P1_4设置为上拉模式,也可以不设置
  1. 设计键盘扫描函数ScanKeys()
  1. 没有按键按下,端口输入为高电平,当端口有低电平产生是,则有可能会是按键按下,需要经过去抖动处理,如果该端口还是低电平,则确认为有按键按下
  2. 在进行按键处理时,先等待按键松开,然后根据灯光状态标志Stat_key进行开灯或关灯动作

Stat_key为灯光状态标志字节,其第0位和第1位分别标志着LED5和LED6的当前状态
该字节的第0位为1时,LED5当前已亮
该字节的第0位为0时,LED5当前熄灭
该字节的第1位为1时,LED6当前已亮
该字节的第1位为0时,LED6当前熄灭

  1. 主函数实现
/*===========================主函数=====================*/
void main(){
  InitPort();
  while(1){
    ScanKeys();
  }
}
  1. 完整版源代码
#include "ioCC2530.h"

#define LED5 P1_3
#define LED6 P1_4
#define SW1 P1_2
#define SW2 P0_1

unsigned char Stat_key = 0;   //按键状态全局变量

/*===========================延时函数======================*/
void Delay(unsigned int t){
  
  while(t--);
}
/*===========================端口初始化函数===============*/
void InitPort(){
  P1SEL &= ~0x18;            //将P1_3和P1_4设置为通用I/O口
  P1DIR |= 0x18;             //将P1_3和P1_4设置为输出方式
  P1SEL &= ~0x04;            //将P1_2设置为通用I/0口
  P1DIR &= ~0x04;            //将P1_2设置为输入方式

  P0SEL &= ~0x02;            //将P0_1设置为通用I/0口

  P0DIR &= ~0x02;            //将P0_2设置为输入方式
  P0INP &= ~0x02;            //将P0_2输入方式设置为上拉/下拉
  P1INP &= ~0x04;            //将P1_2输入方式设置为上拉/下拉
  P2INP &= ~0x60;            //将P0端口和P1端口引脚设置为上拉
  LED5 = 0;                  //上电的时候,LED5不亮
  LED6 = 0;                  //上电的时候LED6不亮
}
/*===========================按键扫描函数================*/
void ScanKeys(){
  if(SW1 == 0){              //发现SW1有低电平信号
    Delay(100);              //延时100ms,按键去抖动
    if(SW1 == 0){            //确定SW1有按键动作
      while(SW1 == 0){       //等待按键1松开
        if((Stat_key & 0x01) == 0x01){  //判断按键1按下之前,LED灯是打开还是关闭
          Stat_key &= ~0x01;
          LED5 = 0;
        }else{
          Stat_key |= 0x01;
          LED5 = 1;
        }
      }
    }
  } 
  if(SW2 == 0){              //发现SW2有低电平信号
    Delay(100);              //按键去抖动
    if(SW2 == 0){            //确定SW2有按键动作
      while(SW2 == 0){       //等待按键2松开
        if((Stat_key & 0x02) == 0x02){  
          Stat_key &= ~0x02;
          LED6 = 0;
        }else{
          Stat_key |= 0x02;
          LED6 = 1;
        }
      }
    }
  }      
}
/*===========================主函数=====================*/
void main(){
  InitPort();
  while(1){
    ScanKeys();
  }
}

  • 16
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: GPIO通用输入/输出)是一种常见的设备接口,在计算机和电子设备中广泛使用。它是一组能够通过编程进行控制和读取的数字引脚,可以连接到各种外部设备上。 通常情况下,计算机系统通过位于主板上的GPIO控制器芯片来提供GPIO接口。GPIO通道的数量和特性可能因设备而异,但通常都包含一些输入输出引脚输入引脚用于接收外部设备发送的信号,比如按钮按下、传感器检测到的信号等。输出引脚用于控制外部设备的状态,比如点亮LED灯、控制继电器等。 在软件编程方面,我们可以使用操作系统提供的GPIO库或者编程语言的相关函数来实现对GPIO控制。这些函数可以设置引脚的工作模式(输入输出)、读取引脚的状态(高电平或低电平)以及设置引脚的状态(输出高电平或低电平)。通过编写相应的代码,我们可以实现与外部设备之间的交互。 GPIO的应用非常广泛。它可以用于连接各种传感器和执行器,如温度传感器、湿度传感器、光线传感器、运动探测器等。通过读取传感器的信号,我们可以获取环境的相关数据。通过控制执行器,我们可以实现对外部设备的控制,如开关电灯、控制电机转动等。 总之,GPIO是一种通用的、灵活的设备接口,可以在计算机和电子设备中进行输入输出控制和读取。通过编程,我们可以与各种外部设备进行连接和通信,实现众多应用场景。 ### 回答2: GPIO是一种通用输入/输出接口,广泛应用于嵌入式系统和物联网设备中。它可以连接各种传感器、执行器和外设,实现与外界的数据交互。 GPIO的主要作用是提供一个程序控制的接口,使嵌入式系统可以读取外部的输入信号,或者向外部输出控制信号。通过GPIO嵌入式系统可以与各种传感器进行通信,获取环境中的信息。例如,可以通过GPIO连接温度传感器,读取当前的温度值;可以连接光照传感器,获取室内或室外的光照强度。同时,GPIO也可以连接执行器,实现对外部设备的控制。比如,可以通过GPIO控制LED灯的亮灭,或者控制电机的转动。 GPIO的使用非常灵活,可以通过软件进行配置和控制。通常,GPIO会被配置为输入模式或输出模式。在输入模式下,GPIO用于读取外部信号的状态,例如读取按键的按下情况。在输出模式下,GPIO用于向外部发送控制信号,例如给LED灯提供开关信号。通过修改GPIO的状态和引脚配置,嵌入式系统可以实现不同的功能需求。 总之,GPIO作为一种通用输入/输出接口,在嵌入式系统和物联网设备中起到了非常重要的作用。它通过连接各种传感器和外设,实现了与外界的通信和数据交互。同时,GPIO的灵活性和可编程性,使得嵌入式系统可以根据需要进行配置和控制,满足各种不同的应用需求。 ### 回答3: GPIO通用输入/输出)是一种可以通过编程控制的数字引脚,可用于输入输出数字信号。GPIO通常用于连接外部设备,如传感器、执行器或其他电子元件,以便与计算机或嵌入式系统进行数据交互。 GPIO的工作方式是基于二进制系统,它可以配置为输入输出模式。在输入模式下,GPIO可以检测外部设备的电平状态,例如开关的开/关状态或传感器的触发信号。在输出模式下,GPIO可以向外部设备发送电压信号,例如驱动电机或控制LED灯。 在使用GPIO时,我们可以通过编程的方式来控制引脚的状态。通过设置引脚的状态,我们可以读取输入信号的状态或者发送输出信号到外部设备。这种灵活的控制方式使得GPIO嵌入式系统和物联网应用中广泛使用。 使用GPIO需要根据具体的硬件平台和编程语言来进行配置和控制。在树莓派等单板计算机中,我们可以使用Python等高级语言来编写GPIO控制代码。在嵌入式系统中,我们可以使用C/C++等低级语言来操作GPIO的寄存器以实现控制。 总之,GPIO是一种通用输入/输出接口,它可以连接外部设备,并通过编程方式实现与计算机或嵌入式系统的数据交互。它在各种应用中都起着重要的作用,从简单的按钮控制到复杂的传感器和执行器控制都可以通过GPIO来实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

364.99°

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值