上篇我们简单认识了一下CC2530开发板,现在继续CC2530微控制器中的寄存器和工程文件的搭建。

一.认识相关寄存器

1.PxSEL

端口功能选择寄存器。设置端口是通用I/O端口还是外设功能端口。CC2530中P0 P1和P2。

名称结构解析

SEL为选择简称,P为端口(port)简称,x是端口组的序号。

P1SEL |= 0x01;  // 将P1.0引脚配置为外设功能
P1SEL &= ~0x02; // 将P1.1引脚恢复为GPIO模式
 

2.PxDIR

端口方向寄存器。作为通用I/O时,确定数据的传输方向。

名称结构解析
  • P:代表端口(Port)
  • x:端口编号(如0、1、2...或A、B、C...)
  • DIR:方向(Direction)
功能说明: 每个位对应一个引脚
  • 置1时:对应引脚设为输出模式
  • 置0时:对应引脚设为输入模式

 P1DIR |= 0X03;//将P1_0和P1_1设置为输出
 

3.PxINT

端口输入模式寄存器。作为通用输入端口时,选择输入模式是上拉、下拉还是三态。

要配置PxINT寄存器,需要设置相应的位来启用中断,并选择中断触发条件(上升沿、下降沿或两者)。

#include <ioCC2530.h>

void configurePortInterrupt() {
    // 配置P1.2为输入
    P1DIR &= ~0x04;  // P1.2设置为输入
    P1INP &= ~0x04;  // P1.2设置为上拉/下拉模式
    P1 &= ~0x04;     // P1.2设置为下拉

    // 配置P1.2中断
    P1IEN |= 0x04;   // 使能P1.2中断
    PICTL |= 0x02;   // 设置P1.2为下降沿触发中断

    // 使能P1中断
    IEN2 |= 0x10;    // 使能P1中断

    // 使能全局中断
    EA = 1;          // 使能全局中断
}
 

需要编写它的中断服务程序,在CC2530中,中断服务程序需要根据中断源进行编写。

#pragma vector = P1INT_VECTOR
__interrupt void INTP1(void) {
    if (P1IFG & 0x04) {  // 检查P1.2是否触发中断
        // 处理P1.2中断
        // 例如,切换LED状态
        P1_0 ^= 0x01;    // 切换P1.0状态

        // 清除P1.2中断标志
        P1IFG &= ~0x04;
    }

    // 清除P1中断标志
    P1IF = 0;
}
 

代码中“pragma vector”作为IAR嵌入式编译器的指令,“P1INT_VECTOR”表示中断服务函数是为P1中断源服务的。

这里着重讲一下关键字“__interrupt”(注意英文前的--是两横),在这里表示该函数是一个中断函数(函数体没有参数,也没有返回值),后面紧接着为函数的终端名称(可以自定义)。

二.代码编写

1.一般代码格式

第一步定义头文件
#include <iocc2530.h>
~~~//这里通常为做代码宏定义以及常量定义
第二步
void delay(unsigned int T)//写一个简单的延时函数
{
  while(T--);
}
第三步
void Init_port()//相应引脚初始化
{
  P1SEL &= ~0x03;
  P1DIR |= 0X03;
}
第三步
这里一般编写相应的中断函数以及使用效果函数
第四步
编写相应的主函数
void main()
{
    while(1)
    {
    }
}

2.做一个简单的LED灯点亮

#include <iocc2530.h>//头文件

void delay(unsigned int T)//写一个简单的延时函数
{
  while(T--);
}

void Init_port()//相应引脚初始化
{
  P1SEL &= ~0x03;
  P1DIR |= 0X03;
}
void main()
{
    Init_port();//引脚初始
    while(1)
    {
      LED1 = 1;//点亮LED1
    }
}
#include <iocc2530.h>//头文件
#define LED1 P1_0
void delay(unsigned int T)//写一个简单的延时函数
{
  while(T--);
}
void main()
{
    Init_port();//引脚初始
    while(1)
    {
      LED1 = 1;//点亮LED1
    }
}

注意:我这里使用了两种不同的写法,第一种直接对相应的引脚初始化,第二种则是对引脚进行宏定义。

3.加一个按键控制LED灯

#include <iocc2530.h>//头文件

void delay(unsigned int T)//写一个简单的延时函数
{
  while(T--);
}

void Init_port()//相应的按键与LED灯的引脚初始化
{
  P1SEL &= ~0x03;
  P1DIR |= 0X03;
}
void Scan_SW1()//做一个按键扫描函数
{
  if(SW1 == 0)//检测按键是否按下,即是否为低电平
    {
      delay(200);//延时消抖
      if(SW1 == 0)//再次检测,如果依旧是低电平那么按键为按下状态
        {
          LED1  = 1;//此时点亮LED灯
        }
    }
  
}
void main()
{
    Init_port();//引脚初始
    while(1)
    {
      void Scan_SW1();//按键扫描函数
    }
}

相应的对按键进行初始化,然后做一个按键的扫描函数,这里着重解释一下按键延时消抖:通常机械开关在按下或释放时,由于触点的弹性,会产生短暂的抖动,导致电压信号出现多次快速跳变,如果不处理,可能会被误认为是多次按键。因此,消抖是必要的。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐