【ZIGBEE(CC2530)学习】2-CC2530基础实验——通用IO口配置


在这里插入图片描述

一、实验介绍

  CC2530有21个IO口,可以配置为通用IO口或片上外设IO口,如配置为连接到ADC、定时器或USART外设。可以通过一系列寄存器对IO口进行配置。
  I/O端口具备如下重要特性:
   - 21 个数字I/O引脚
   - 可以配置为通用I/O 或外部设备I/O
   - 输入口具备上拉或下拉能力
   - 具有外部中断能力。
  21 个I/O引脚都可以用作于外部中断源输入口。

二、实验目的

  通过本实验了解并掌握CC2530通用IO口的使用及相关寄存器的配置。

三、实验设备

3.1、硬件设备

  1. ZIGBEE开发板
  2. SmartRF04EB仿真器

3.2、软件环境

  1. IAR Embedded Workbench for 8051集成开发环境

四、实验原理

4.1、IO口

  CC2530一共有21个IO口可使用,其中P0和P1有8个(0-7),而P2只有5个(0-4)。其中P10和P11有20mA的输出驱动能力,而其他的IO口只有4mA的驱动能力。
  每个IO口都可以作为通用IO口使用,也可以具备片上外设功能。
  通用IO口指可执行输入或输出的端口,例如输出高或低电平使对应IO口的LED实现亮或灭。用作通用IO口时,引脚可以组成3个8位端口,端口0、端口1和端口2表示为P0、P1和P2。其中P0和P1是完全的8位端口,而P2仅有5位可用。
  片上外设功能指IO口作为串口使用或ADC输入等。
  配置IO口,首先配置PxSEL寄存器来设定IO口为通用IO口或具备片上外设功能的IO口,当配置为通用IO口时,通过配置PxDIR寄存器来设定IO口为输入模式或输出模式,如果为输入模式,则需要通过配置PxINP寄存器来设定为上、下拉输入或三态输入,如果为输出模式,只需配置IO口为高电平或低电平。

4.2、PxSEL寄存器

  PxSEL(x=0,1,2)寄存器,叫功能选择寄存器,用于选择IO口位通用IO口或外设功能,有8位,每一位对应IO组中相应的IO口。
  P0SEL寄存器和P1SEL寄存器的8位都可以用来配置IO口的功能。
在这里插入图片描述
  由于P2组IO口只有5个引脚可用,其中P2_1和P2_2用于下载程序使用,所以这两个IO口不需要配置,即P2SEL寄存器的低3位为P2_4、P2_3、P2_0。P2SEL寄存器高5位用于端口1外设优先级控制。
在这里插入图片描述

4.3、PxDIR寄存器

  PxDIR(x=0,1,2)寄存器,叫方向寄存器,用于配置IO口为输入模式或输出模式,有8位,每一位对应IO组中相应的IO口。
  P0DIR寄存器和P1DIR寄存器的8位都可以用来配置IO口的方向。
在这里插入图片描述
  由于P2组IO口只有5个引脚可用,所以P2DIR寄存器的低5位用于配置P2_4-P2_0的方向。P2DIR寄存器高2位用于端口0外设优先级控制。
在这里插入图片描述

4.4、PxINP寄存器

  PxINP(x=0,1,2)寄存器,叫输入模式寄存器,用于配置IO口为上、下拉输入模式或三态输入模式,有8位,每一位对应IO组中相应的IO口。
  P0DIR寄存器和P1DIR寄存器的8位都可以用来配置IO口的输入模式。
在这里插入图片描述
  由于P2组IO口只有5个引脚可用,所以P2INP寄存器的低5位用于配置P2_4-P2_0的输入模式,而高3位用于对3个端口的所有引脚设置为上拉或下拉输入模式。
在这里插入图片描述

五、实验演示

  接下来我们解读一下第一次实验的代码。

#include<iocc2530.h>    //头文件
void main(void)
{
	P1SEL &= ~0x01;		//配置P1_0为通用IO口
	P1DIR |= 0x01;		//配置P1_0为输出模式
	P1_0 = 1;			//配置P1_0为高电平
}

  再看一下原理图,我们可以看到P1_0-P1_2上都接有LED,接下来我们将利用P0_0上的按键来控制3个LED的状态。
在这里插入图片描述
  我们首先初始化LED和按键,配置P1_2-P1_0和P0_0为通用IO口,且配置P1_2-P1_0为输出模式,P0_0为输入模式。

P1SEL &= ~0x07;	//1111 1000 配置P1_2-P1_0为通用IO口
P1DIR |= 0x07;	//0000 0111 配置P1_2-P1_0为输出模式
P1 = 0x00;		//0000 0000 配置P1_2-P1_0为低电平
P0SEL &= ~0x00;	//1111 1110 配置P0_0为通用IO口
P0DIR |= 0x00;	//0000 0000 配置P0_0为输入模式
P0INP |= 0x00;	//0000 0000 配置P0_0为上、下拉输入模式```

  由于我们的按键模块没有接上电阻,所以我们不需要配置为上拉或下拉输入模式的一种。
  当把按键按1下时,P0_0口检测到的是低电平,也就是我们可以用if语句来判断P0_0口的电平是否为低电平,

if(P0_0 == 0)

  当检测为低电平时说明此刻按键被按下,就可以执行我们想要的效果。
  但是按键在被按下和释放时是会发生抖动的,这个抖动可能会使得我们在按下或释放时,程序自动在这5-20ms内检测我们按下或释放多次,此时就无法达到预期的效果。
在这里插入图片描述
  这种抖动并不是无法消除,我们可以用软件来消除该抖动,只需在我们按下和释放时各进行一次5-20ms的延时,使得在这段时间内程序进入延时而没有去检测抖动。

void delay_ms(unsigned int xms)	//简单的ms级别延时模块
{
for(;xms>0;xms--)
for(unsigned int j=587;j>0;j--);
}
//main函数里
if(P0_0 == 0)					//检测到按键1被是否按下
{
delay_ms(10);				//按键按下时进行一次5-20ms的延时
while(P0_0 == 0);			//当按键未被释放时进入死循环
delay_ms(10);				//按键释放时进行一次5-20ms的延时
}

  回顾下我们要实现的效果,利用P0_0上的按键来控制3个LED的状态,接下来我们把所有的代码给整合起来。

#include<iocc2530.h>						//头文件
void delay_ms(unsigned int xms)			//ms级别延时
{
    for(;xms>0;xms--)
      for(unsigned int j=587;j>0;j--);
}
void main(void)
{
    P1SEL &= ~0x07;						//配置P1_2-P1_0为通用IO口
    P1DIR |= 0x07;						//配置P1_2-P1_0为输出模式
    P1 = 0x00;							//配置P1_2-P1_0为低电平
    P0SEL &= ~0x01;						//配置P0_0为通用IO口
    P0DIR |= 0x00;						//配置P0_0为输入模式
    P0INP |= 0x00;						//配置P0_0为上、下拉输入模式
    while(1)
    {
        if(P0_0 == 0)					//检测到按键1被是否按下
        {
            delay_ms(10);					//按键按下时进行一次5-20ms的延时
            while(P0_0 == 0);				//当按键未被释放时进入死循环	
            delay_ms(10);					//按键释放时进行一次5-20ms的延时
            P1 = ~P1;					//让P1组IO口的电平翻转
        }
    }
}

在这里插入图片描述
  以下是效果图。
在这里插入图片描述
在这里插入图片描述
  当按键1被按下时,进入10ms的按下消抖,随后进入死循环,当按键1被释放时,跳出死循环并进入10ms的释放消抖,随后LED的状态发生改变。
  注意的是我们实现的是当按键释放时LED的状态才发生改变。如果想实现按下的时候改变LED的状态,只需完成以下操作:

if(P0_0 == 0) -> if(P0_0 == 1)
while(P0_0 == 0) -> while(P0_0 == 1)

  有疑问可以加入QQ群交流:324611467

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值