实验套件介绍
如图所示是我们的CC2530实验套件,从图上可以看出,板子中间有四个LED,分别是:LED3,LED4,LED1,LED2
板子上有两个按键SW1和SW2分别对应引脚 P1.2和P0.1
课堂任务
①通过按键SW1控制LED3灯的亮与灭
②通过按键SW1控制LED灯向下移动
③通过按键SW2控制LED灯向上移动
④SW1和SW2同时控制LED灯上下移动
预备知识
按键工作原理
当按键未被按下时,Key的电压为3.3V,当按键被按下时,Key的电压是0V。
按键按下与抬起改变的是Key的电压。
上拉与下拉
上拉是指单片机的引脚通过一个电阻连接到电源(高电平),当外界没有信号输入到引脚时,引脚被上拉电阻固定在高电平(逻辑值1)。
下拉是指单片机的引脚通过一个电阻连接到地(低电平),当外界没有信号输入到引脚时,引脚被下拉电阻固定在低电平(逻辑值0)。
思考:
上一页PPT的按键是上拉还是下拉?
请同学们画出一个下拉的按键原理图?
按键抖动
通常按键所用的都是机械弹性开关,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下就断开,而是在闭合或断开的瞬间均伴随一连串的抖动。
抖动时间的长短由按键的机械特性决定,一般为5~10 ms,一个按键的时间一般为几百毫秒至数秒。由于单片机的运行速度快,按键的抖动会导致在一次按下过程中,单片机识别出多次按下和抬起。为了避免这种情况,需要想办法消除抖动带来的影响。
按键消抖的方法有两种:
硬件消抖和软件消抖硬件消抖是通过电路硬件设计的方法来过滤按键输出信号,将抖动信号过滤成理想信号后再输出给单片机。软件消抖是通过程序过滤的方法,在程序中检测到按键动作后,延时一会儿后再次检测按键状态,如果延时前后按键的状态一致,则说明按键是正常执行动作,否则认为是按键抖动。
实验套件上按键的原理图
通过SW1控制LED3的亮灭
任务描述:
①上电后LED3点亮,其他LED灯熄灭
②按下SW1后LED3熄灭,再次按下LED3点亮
初始化设置:
①P1_2设置输入,P1的其他引脚设为输出设置为输出
P1DIR =0xFB; //(0xFB = 1111 1011)
②点亮LED3,熄灭其他LED
LED3 = 1;
LED1 = 0;
LED2 = 0;
LED4 = 0;
读取按键的值
unsigned char KeyScan(void)
{
if(SW1 == 0) //按键被按下
{
Delay_mS(50); //消除抖动
if(SW1 == 0) //再次确认按键被按下
{
while(!SW1); //直到松开按键
return(1);
}
}
return(0);
}
此函数用来读取按键的值,如果SW1被按下,将会返回1,如果没有按键被按下,将会返回0
主循环
while(1)
{
Keyvalue = KeyScan(); //读取按键值
if(Keyvalue>0)
{
LED3 = !LED3;
Keyvalue = 0;
};
}
同学们自己修改代码,使用按键SW1控制别的LED灯的亮灭!
通过SW1 控制LED灯向下流动
任务描述:
上电后LED3点亮,其他熄灭;
按下SW1后LED4点亮,其他熄灭;
再次按下SW1,LED1点亮,其他熄灭;
再次按下SW1,LED2点亮,其他熄灭:
实现代码
while(1)
{
Keyvalue = KeyScan(); //读取按键值
if(Keyvalue>0)
{
if(LED3 == 1) //如果当前LED3亮
{
LED3 = 0;
LED4 = 1;
}
else if(LED4 == 1)
{
LED4 = 0;
LED1 = 1;
}
else if(LED1 == 1)
{
LED1 = 0;
LED2 = 1;
}
else if(LED2 == 1)
{
LED2 = 0;
LED3 = 1;
}
Keyvalue = 0;
};
}
** LED灯向上移动**
同学们自己修改代码实现LED灯向上移动的效果!
按键SW2的使用
①初始化SW2,将SW2对应的引脚P01设为输入模式
P0DIR = 0; //P0所有引脚都设为输入模式
②按键扫描函数添加如下代码
if(SW2 == 0) //低电平有效
{
Delay(100); //检测到按键
if(SW2 == 0)
{
while(!SW2); //直到松开按键
return(2);
}
}
SW1和SW2同时控制LED灯上下移动
任务要求:
上电后LED3点亮,其他熄灭;
按下SW1按键后,点亮的那颗灯向下移动;
按下SW2按键后,点亮的那颗灯向上移动;
完整的源代码
#include <ioCC2530.h>
//定义控制灯的端口
#define LED1 P1_0 //定义LED1为P1_0口控制
#define LED2 P1_5 //定义LED2为P1_5口控制
#define LED3 P1_3 //定义LED3为P1_3口控制
#define LED4 P1_4 //定义LED4为P1_4口控制
#define SW1 P1_2 //定义SW1为P1_2端口
#define SW2 P0_1 //定义SW2为P0_1端口
/****************************
//延时
*****************************/
char pause = 0;
void Delay_mS(unsigned int n)
{
unsigned int tt,i = 0;
for(i = 0; i < n; i ++)
for(tt = 0; tt<1040; tt++);
while(pause);
}
void Delay_uS(unsigned int n)
{
unsigned int i = 0;
for(;i < n; i++);
}
/****************************
//初始化函数
*****************************/
void Initial(void)
{
CLKCONCMD &= 0x80;//使用外部32MHz晶振
P1DIR = 0xFB;//将P12设为输入,其他设为输出 (0xFB = 11111011)
LED1 = 0;//关闭LED1
LED2 = 0;//关闭LED2
LED3 = 0;//关闭LED3
LED4 = 0;//关闭LED4
}
/*****************************************
//读键值
*****************************************/
unsigned char KeyScan(void)
{
if(SW1 == 0) //低电平有效
{
Delay_mS(50); //检测到按键
if(SW1 == 0)
{
while(!SW1); //直到松开按键
return(1);
}
}
return(0);
}
unsigned char Keyvalue = 0 ; //用来记录按键的值
/***************************
//主函数
***************************/
void main(void)
{
Initial(); //调用初始化函数
LED3 = 1; //点亮LED3
while(1)
{
Keyvalue = KeyScan(); //读取按键值
if(Keyvalue == 1) //按键SW1被按下
{
if(LED3 == 1) //如果当前是LED3亮
{
LED3 = 0; //关闭LED3
LED4 = 1; //点亮LED4
}
else if(LED4 == 1) //如果当前是LED4亮
{
LED4 = 0;//关闭LED4
LED1 = 1;//点亮LED1
}
else if(LED1 == 1)//如果当前是LED1亮
{
LED1 = 0;//关闭LED1
LED2 = 1;//点亮LED2
}
else if(LED2 == 1)//如果当前是LED2亮
{
LED2 = 0;//关闭LED2
LED3 = 1;//点亮LED3
}
};
Keyvalue = 0;
}
}