zigbee之点灯1

1、单纯亮个灯
2、按键点灯
3、中断点灯

一、单纯的亮个灯


首先找到你的zigbee板子的原理图,找到led灯对应的接口。
在这里插入图片描述
在这里我想点亮灯D1和D2,可以看到灯D1和D2对应的接口是P1_0和P1_1
我们可以在cc2530的中文手册中找到端口P1的相关设置
在这里插入图片描述
首先P0、P1、P2都是可以用作通用IO口也可以用作外设IO口,具体的选择跟上图是一样的。
PxSEL选择IO是通用还是外设
PxDIR选择是输入还是输出
PxINP设置上拉。要注意P1.0和P1.1没有上拉下拉功能,在这里可以不用设置。
在这里插入图片描述

#include <ioCC2530.h>

#define LED1 P1_0 //定义P1.0口为LED1控制端
#define LED2 P1_1 //定义P1.1口为LED2控制端

/**LED口初始化**/
void InitLed(void)
{
  P1SEL &= ~0x03; //设置为通用IO口
  P1DIR |= 0x03; //0000 0011 P1.0,P1.1口定义为输出,
  LED1 = 1;
  LED2 = 1;      //灯的默认状态为熄灭状态
}

void main(void)
{
  //初始化
  InitLed();
 
   while(1)
 {  
      LED1 = 0;
      LED2 = 0;
  }
}

之所以设定 P1SEL &= ~0x03; P1DIR |= 0x03; 是为了避免对端口其他位置的改变
&按位或 全1为1
P1SEL & 1111 1100(~0000 0011) 最后两位为0,在或运算下,最后两位的值是不会改变的。如果其他位有改变,也不会有影响。
|按位与 有1为1
同理 P1DIR | 0000 0011 最后两位为1,在与运算下,最后两位的值不会改变。

如果要设置流水灯,那么挨个亮灭就可以了

#include <ioCC2530.h>

#define LED1 P1_0 //定义P1.0口为LED1控制端
#define LED2 P1_1 //定义P1.1口为LED2控制端

/**延时函数**/
void Delayms(int ms)
{
  int i,j;
  for(i = 0;i < ms;i++){
  for(j = 0;j < 535;j++);
  }
}

/**LED口初始化**/
void InitLed(void)
{
  P1SEL &= ~0x03; //设置为通用IO口
  P1DIR |= 0x03; //0000 0011 P1.0,P1.1口定义为输出,
  LED1 = 1;
  LED2 = 1;      //灯的默认状态为熄灭状态
}

void main(void)
{
  //初始化
  InitLed();
 
   while(1)
 {  
      LED1 = ~LED1;
      Delayms(500);
      LED1 = ~LED1;
      LED2 = ~LED2;
      Delayms(500);
      LED2 = ~LED2;
  }
}

大概最后的效果是D1亮一下灭了然后D2再亮一下灭这样循环。

二、按键点灯


同样是上图
在这里插入图片描述
想形成的效果是按一下S1灯开,再按一下灯关。
在这里按键S1的连接端口为P0_1 这个端口有上拉电阻的功能,所以这里要设置P0INP

#include <ioCC2530.h>

#define LED1 P1_0 //定义P1.0口为LED1控制端
#define LED2 P1_1 //定义P1.1口为LED2控制端
#define KEY P0_1  //定义P0.1为按键S1控制端


/**延时函数**/
void Delayms(int ms)
{
  int i,j;
  for(i = 0;i < ms;i++){
  for(j = 0;j < 535;j++);
  }
}
/**LED口初始化**/
void InitLed(void)
{
  P1SEL &= ~0x03; //设置为通用IO口
  P1DIR |= 0x03; //0000 0011 P1.0,P1.1口定义为输出,
  LED1 = 1;
  LED2 = 1;      //灯的默认状态为熄灭状态
}
/**按键初始化**/
void KeyInit(void)
{
  P0SEL &= ~0x02; //设置P0.1为普通IO口 0000 0010
  P0DIR &= ~0x02; //设置P0.1为输入模式
  P0INP &= ~0x02; //打开上拉电阻
}
/**读取按键状态,KEY=0表示按键被按下,KEY=1表示按键抬起**/
int KeyScan(void)
{
  if(KEY == 0){
    Delayms(10);
    if(KEY == 0){
      while(!KEY){
       return 1;
      }
    }
  }
   return 0;
}
void main(void)
{
  //初始化
  InitLed();
  KeyInit();
  
   while(1)
  {  
    if(KeyScan())
    {
        LED1 = ~LED1;
        LED2 = ~LED2;
    }
  }  
}   

这个代码IAR单步运行调试的时候是显示是对的,全速运行的时候有的时候按下会亮有的时候不会,不知道是代码逻辑问题还是哪里我没注意到的问题。

三、中断点灯


首先这里关于中断有几个概念。
中断向量:中断服务程序的入口地址。每个中断源都对应一个固定的入口地址。当内核响应中断请求时,就会暂停当前的程序执行,然后跳转到该入口地址执行代码。
中断服务函数: 内核响应中断后执行的相应处理程序。

CPU 有 18 个中断源。每个中断源都有它自己的位于一系列 SFR 寄存器中的中断请求标志。相应标志位请求的每个中断可以分别使能或禁用。
在这里插入图片描述
表2-5
在这里插入图片描述

在这里插入图片描述

大概意思就是,我请求一个中断,这个中断作用在某个端口,在这里,我是按下S1的按键后请求一个中断,这个中断响应在灯的P0口。而在中断源会有设置中断屏蔽,如果P0要响应就得开相应的设置。
注意一定要清楚中断标志,不然就会一直中断。

在这里插入图片描述
在这里插入图片描述

/******通过按键S1产生外部中断改变LED1状态******/

#include <ioCC2530.h>
#define LED1 P1_0
#define KEY1 P0_1

/**延时函数**/
void Delayms(int ms)
{
  for(int i = 0;i < ms;i++){
    for(int j = 0;j < 535;j++);
  }
}

/**灯初始化**/
void InitLed(void)
{
  P1DIR |= 0x01;  //定义为输出口
  LED1 = 1; //LED1默认熄灭
}

/**按键初始化**/
void InitKey()
{
  P0IEN |= 0x2; //P0.1设置为中断方式1
  PICTL |= 0x1; //下降沿触发
  IEN1 |= 0x20; //允许P0口中断
  P0IFG = 0x00; //初始化中断标志位
  EA = 1;   //打开总中断
}

/**中断函数**/
#pragma vector = P0INT_VECTOR
 __interrupt void PA(void)
{
  Delayms(10); //消抖
  LED1 = ~LED1;
  P0IFG = 0; //清理中断标志
  P0IF = 0; //要清理中断标志位不然一直一直中断
}

/**主函数**/
void main(void)
{
  InitLed();
  InitKey();
  while(1){
    
  }
}

小声bb一个我容易混乱的点
因为这里大多都是字节运算 八位的顺序是从右往左为0~7
意思就是 76543210 0位是最右边是端口上的0位比如P1_0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值