一、项目目的:

熟悉 ZigBee 模块相关硬件接口。使用 IAR 开发环境设计程序,学习 CC2530 定时器的使用,利用 CC2530 的定时器 T1 查询方式控制 LED 周期性闪烁。

二、项目原理:

LED及按键原理图,如下图所示:
CC2530 的 T1 定时器(16 位)需要配置三个寄存器 T1CTL,T1STAT,
IRCON 。I/O 口配置参考前文。寄存器功能如下:

LED 初始化配置:
P0DIR |= 0x20; //P0_5 定义为输出
定时器 1 初始化配置:
T1CTL = 0x0d; //128 分频,自动重装 0X0000-0XFFFF
T1STAT= 0x21; //通道 0, 中断有效

全代码如下:

/*************************************
模块:HALL 模块
功能:通过定时器 T1 查询方式
控制 LED1 周期性闪烁
**************************************/
#include <ioCC2530.h>
#define uint unsigned int
#define uchar unsigned char
//定义控制 LED 灯的端口
#define LED1 P0_5 //定义 LED1 为 P0_5 口控制
//函数声明
void Delayms(uint xms); //延时函数
void InitLed(void); //初始化 P1 口
void InitT1(); //初始化定时器 T1
/****************************
//延时函数
*****************************/
void Delayms(uint xms) //i=xms 即延时 i 毫秒
{
uint i,j;
for(i=xms;i>0;i--)
for(j=587;j>0;j--);
}
/****************************
//初始化程序
*****************************/
void InitLed(void)
{
P0DIR |= 0x20; //P0_5 定义为输出
LED1 = 1; //LED1 灯初始化熄灭
}
//定时器初始化
void InitT1() //系统不配置工作时钟时默认是 2 分频,即 16MHz
{
T1CTL = 0x0d; //128 分频,自动重装 0X0000-0XFFFF
T1STAT= 0x21; //通道 0, 中断有效
}
/***************************
//主函数
***************************/
void main(void)
{
uchar count;
InitLed(); //调用初始化函数
InitT1();
while(1)
{
 if(IRCON>0)
{ IRCON=0;
if(++count>=1) //约 1s 周期性闪烁
{
count=0;
LED1 = !LED1; //LED1 闪烁
}}}}
依表寄存器配置如下: 
T3CTL |= 0x08 ; // 开溢出中断 
T3IE = 1; // 开总中断和 T3 中断 
T3CTL |=0XE0; 8 //128 分频 ,128/16000000*N=0.5S,N=65200 
T3CTL &= ~0X03; // 自动重装 00 - >0xff 65200/256=254( 次) ) 
T3CTL |=0X10; // 启动 
EA = 1; // 开总中断

全代码如下:

/*************************************
模块:HALL 模块 功能:通过定时器 T3 中断方式 控制 LED1 周期性闪烁 
**************************************/ 
#include #define uint unsigned int #define uchar unsigned char 
//定义控制 LED 灯的端口 
#define LED1 P0_5 //定义 LED1 为 P0_5 口控制 
//函数声明 
void Delayms(uint xms); //延时函数 
void InitLed(void); //初始化 LED 
void InitT3(); //初始化定时器 T3 
uint count;//用于定时器计数 
/**************************** //延时函数 
*****************************/ 
void Delayms(uint xms) //i=xms 即延时 i 毫秒 
{ uint i,j; for(i=xms;i>0;i--) for(j=587;j>0;j--); } 
/**************************** //初始化程序 
*****************************/ 
void InitLed(void) { P0DIR |= 0x20; //P0_5 定义为输出 
LED1 = 1; //LED1 灯熄灭 
} 
//定时器初始化 
void InitT3() {
53 
T3CTL |= 0x08 ; //开溢出中断 
T3IE = 1; //开总中断和 T3 中断 
T3CTL|=0XE0; //128 分频,128/16000000*N=0.5S,N=65200 
T3CTL &= ~0X03;//自动重装 00->0xff 65200/256=254(次) 
T3CTL |=0X10; //启动 
EA = 1; //开总中断 
} 
/*************************** //主函数 
***************************/ 
void main(void) { InitLed(); //调用初始化函数 
InitT3(); while(1){} } #pragma vector = T3_VECTOR //定时器 T3 
__interrupt void T3_ISR(void) { IRCON = 0x00; //清中断标志, 也可由硬件自动完成 
if(++count>254) //254 次中断后 LED 取反,闪烁一轮(约为 0.5 秒时间) 
{ count = 0; // 计数清零 
LED1=~LED1; } }

三、项目步骤:

  1. 将 CC2530 核心板插在 HALL 传感器底板,使用配套方口 USB 线连接
    PC 机和 DY-WSN-Kit V1.0 物联网综合开发实训平台,给开发实训平台上电,打开 HALL 传感器底板开关(传感器底板左侧开关),传感器底板电源灯亮起。
  2. 使用旋钮开关选择 ZigBee 仿真器要连接的设备模块(根据 LED 指示灯是否亮起判断)。在这个项目中,将旋钮选择到 HALL 传感器底板。
  3. 启动 IAR 开发环境,新建工程,将项目工程中代码拷贝到新建工程中。
  4. 在 IAR 开发环境中编译、运行、调试程序,并把程序下载到 HALL 传感器底板的 CC2530 核心板上,观察项目现象。
  5. 关闭开发平台电源,关闭 HALL 传感器底板电源。
    注:代码为按键查询和按键中断,此过程重复两次。

    四、 项目过程:

    通过定时器 T3 中断方式控制 LED1 周期性闪烁
    这个项目的目标是利用定时器T3中断来控制LED1的周期性闪烁。
    通过定时器 T3 的中断方式,每隔大约0.5秒控制LED1闪烁一次。

项目硬件

一块单片机开发板
一个LED灯,连接到P0_5引脚

项目步骤

定义宏和数据类型
定义控制LED的端口
声明函数
实现延时函数
实现初始化LED函数
实现定时器T3的初始化函数
实现主函数
实现定时器T3的中断服务函数

五、 项目结果与分析:

1. 项目现象。

在上电或复位后,LED1 处于熄灭状态。这是因为在 InitLed 函数中,将 LED1 设置为 1(假定高电平熄灭,低电平点亮)。

定时器 T3 被配置为每隔约 0.5 秒产生一次中断。Timer3 的计数器会在 254 次中断后,触发一次中断服务程序。

LED1 闪烁现象:

在定时器 T3 中断服务函数 T3_ISR 中,每次中断发生时,count 变量自增。
当 count 达到 254 时,LED1 的状态会被取反(若原来熄灭则点亮,若原来点亮则熄灭),并且 count 变量被重置为 0。
由于定时器中断每 0.5 秒触发一次,经过 254 次中断后,LED1 的状态取反一次,因此 LED1 的闪烁周期大约为 0.5 秒。

2.对定时器寄存器的值进行更改,观察现象;更改代码,改变LED灯亮灭的周期;更改代码,改变LED灯亮灭的状态。

要进行进一步的实验和观察,我们可以通过更改定时器寄存器的值、修改代码来改变LED灯的亮灭周期以及状态。以下是具体的步骤和代码示例:

改变定时器寄存器的值

通过更改定时器的设置,可以调整LED灯闪烁的周期。例如,调整分频值和重装值。

示例代码

修改 InitT3 函数中的定时器设置:

void InitT3() 
{
    T3CTL |= 0x08;  // 开溢出中断
    T3IE = 1;  // 开总中断和 T3 中断

    // 修改分频值和重装值
    T3CTL |= 0xC0;  // 64 分频, 64/16000000*N=0.5S, N=32600
    T3CTL &= ~0x03;  // 自动重装 00->0xff 32600/256=127(次)
    T3CTL |= 0x10;  // 启动
    EA = 1;  // 开总中断
}

更改分频值和重装值后会改变定时器溢出的频率,从而改变LED灯闪烁的周期。

改变LED灯亮灭的周期

通过调整中断触发后的计数逻辑,可以改变LED灯的闪烁周期。

示例代码

T3_ISR 中修改计数逻辑:

__interrupt void T3_ISR(void) 
{
    IRCON = 0x00;  // 清中断标志, 也可由硬件自动完成
    if (++count > 127)  // 127 次中断后 LED 取反,闪烁一轮(约为 0.25 秒时间)
    {
        count = 0;  // 计数清零
        LED1 = ~LED1;  // LED 取反
    }
}

将计数值修改为 127 次中断后取反,LED的闪烁周期变为约 0.25 秒。

改变LED灯亮灭的状态

更改LED灯在初始化时的状态以及在中断服务函数中的取反逻辑。

示例代码

InitLed 函数中修改初始状态:

void InitLed(void) 
{
    P0DIR |= 0x20;  // P0_5 定义为输出
    LED1 = 0;  // LED1 初始状态为点亮
}

修改中断服务函数中的状态控制逻辑:

__interrupt void T3_ISR(void) 
{
    IRCON = 0x00;  // 清中断标志, 也可由硬件自动完成
    if (++count > 254)  // 254 次中断后 LED 取反,闪烁一轮(约为 0.5 秒时间)
    {
        count = 0;  // 计数清零
        LED1 = !LED1;  // LED 取反
    }
}

通过上述的代码修改,可以观察到以下现象:

  1. 更改定时器寄存器的值:LED的闪烁周期会随分频值和重装值的变化而变化。
  2. 改变LED灯亮灭的周期:通过调整中断触发后的计数逻辑,可以改变LED的闪烁周期。
  3. 改变LED灯亮灭的状态:通过更改初始状态和取反逻辑,可以控制LED初始状态和闪烁的逻辑。