车干的ZigBee学习笔记三---定时器

一、ZigBee时钟介绍

1、时钟信号的产生

(1)高频时钟信号由两个高频振荡器产生:
• 32 MHz 晶振
• 16 MHz RC 振荡器
32 MHz 晶振启动时间对一些应用程序来说可能比较长,因此设备可以运行在 16 MHz RC 振荡器,直到晶振稳定。16 MHz RC 振荡器功耗少于晶振,但是由于不像晶振那么精确,不能用于 RF 收发器操作。
(2)低频时钟信号由两个低频振荡器产生:
• 32 kHz 晶振
• 32 kHz RC 振荡器
32 kHz XOSC 用于运行在 32.768 kHz,为系统需要的时间精度提供一个稳定的时钟信号。校准时 32 kHz RCOSC 运 行 在 32.753 kHz 。 校 准 只 能 发 生 在 32 kHz XOSC 使 能 的 时 候 ,这个校准可以通过使能 SLEEPCMD.OSC32K_CALDIS 位禁用。比起 32 kHz XOSC 解决方案,32 kHz RCOSC 振荡器应用于降低成本和电源消耗。这两个 32 kHz 振荡器不能同时运行。

2、时钟信号作用
CC2530在正常运行时需要一个高频时钟信号和低频时钟信号
CC2530核心板CPU需要高频时钟信号保证程序的运行;
低频时钟信号供给看门狗、睡眠定时器等片上外设。

3、由于16 MHz RC 振荡器功耗少于晶振,但是由于不像晶振那么精确,不能用于 RF 收发器操作。
所以在使用串口,特别是无线通信时,必须要用到32M的石英晶振作为高频时钟来源。

4、高频时钟源特点
两个高频时钟源可以同时起振产生高频时钟信号
两个低频时钟源,某一时刻只能有一个起振,并且起振的这个时钟源供给CC2530

二、系统高频时钟源切换

1、切换步骤:

(1)让两个高频时钟源起振
(2)等待时钟源稳定
(3)延时一小段时间(大于63us)
(4)不分频输出(即输出32M)
注、CLKCONCMD低三位控制分频
在这里插入图片描述
(5)选择高频时钟源作为主频
(6)确认当前系统时钟是不是选定的高频时钟源

2、用到的寄存器 SLEEPCMD、SLEEPSTA、CLKCONCMD、CLKCONSTA

(1)SLEEPCMD 睡眠模式控制寄存器
在这里插入图片描述
(2)SLEEPSTA 睡眠模式控制状态寄存器
在这里插入图片描述
(3)CLKCONCMD 时钟控制命令寄存器
在这里插入图片描述
(4)CLKCONSTA 时钟控制状态寄存器
在这里插入图片描述

3、操作过程:

(1)让SLEEPCMD的第二位为0,开启两个时钟源。
(2)SLEEPSTA寄存器第6位为1表示32M时钟源振荡稳定
(3)延时大于63us
(4)CLKCONCMD低三位设为000,表示不分频
(5)CLKCONSTA的第6位控制的是系统的主时钟,默认情况下为1,即使用RC16M;当为0时,表示使用外部32M,所以将CLKCONCMD的第6位置0
(6)检查CLKCONSTA的第6位,如果为1,则表示系统还是16M的时钟源,如果为0则表示时钟源为32M。

4、例程:


#include<iocc2530.h>
#include<string.h>


#define uint unsigned int
#define uchar unsigned char

/**********LED延时函数*******/
void delay()
{
	uint x,y;
	for(x=0;x<)250;x++)
    for(y=0;y<2000;y++);
}

/**********时钟源切换延时函数*********/
void delayus()
{
  uchar x=250;
  while(x--);
}

/*******时钟源切换函数******/
void change32M()
{
  SLEEPCMD &= ~0x04;//让两个时钟源起振
  while(0==(SLEEPSTA & 0x40));//检测第6位是否为1,表示时钟源稳定
  delayus();//延时63us
  CLKCONCMD &= ~0x07;  //低三位设置分频,此处设置为000,表示不分频
  CLKCONCMD &= ~0x40;  //第6为置0表示使用32M的时钟源
  while(CLKCONSTA & 0x40); //检测第6位是否为0,为0则表示此时系统统时钟使用的时32M的时钟源
}

/*****IO口初始化函数******/
void Init()
{
  P1DIR |= 0x01; //P1_0
}


void main()
{
  Init();
  change32M();
  while(1)
  {
    P1_0 ^=1;  //异或运算
    delay();
  }
}


二、ZigBee定时器T1—查询方式

1、相关寄存器

CC2530的T1定时器(16位)需要配置三个寄存器T1CTL、T1STAT、IRCON
(1)T1CTL 定时器1的控制和状态
在这里插入图片描述
(2)T1STAT 定时器1状态寄存器
在这里插入图片描述
(3)IRCON 中断标志寄存器
在这里插入图片描述

2、例程

/*******定时器T1通过查询方式控制LED1周期性闪烁****/
#include<iocc2530.h>

typedef unsigned char uchar;
typedef unsigned int uint;

#define LED1 P1_0


/****P1口初始化函数*****/
void initled(void)
{
	P1DIR |= 0x01;
	LED1 = 1;
}

/******定时器初始化函数*******/
{
	void initT1()
	T1CTL = 0x0d;   //128分频,自动重装 0x0000-0xFFFF
	T1STAT= 0x21; //通道 0,中断有效
}

void main()
{
	uchar count=0; 
 
	initLed(); //调用初始化函数
	initT1(); 
 
	while(1) 
	{ 
		if(IRCON > 0) 
		{ 
			IRCON=0; 
			if(count++ >= 1) //约 1s 周期性闪烁,大约为 1025MS 
			{ 
				count=0; 
				LED1 = !LED1; //LED1 闪烁
			} 
		} 
	}
}

三、ZigBee定时器T3—中断方式

1、相关寄存器 ——— T3CTL, T3CCTL0, T3CC0, T3CCTL1, T3CC1

(1)T3CTL ——定时器3控制寄存器
在这里插入图片描述
(2)T3CCTL0 ——定时器3通道 0捕获/比较控制寄存器
在这里插入图片描述
(3)T3CC0 ——定时器 3 通道 0 捕获/比较值
在这里插入图片描述
(4)T3CCTL1 —— 定时 3 通道 1 捕获/比较控制
在这里插入图片描述
(5)T3CC1——定时器 3 通道 1 捕获/比较值

在这里插入图片描述

2、例程

#include <ioCC2530.h> 

typedef unsigned char uchar; 
typedef unsigned int uint; 

#define LED1 P1_0 

uint count;  //定时器计数

/*****P1初始化函数******/
void initled(void)
{
	P1DIR |= 0X01;
	LED1 = 1;
}

/*******定时器初始化函数*****/
void initT3()
{
	T3CTL |= 0x08 ; //开溢出中断 
	T3IE = 1; //开总中断和 T3 中断 
	T3CTL |= 0xE0; //128 分频,128/16000000*N=0.5S,N=62500
	T3CTL &= ~0x03; //自动重装 00->0xff 62500/255=245(次)
	T3CTL |= 0x10; //启动
	EA = 1; //开总中断
}


/********定时器T3中断处理函数*******/
#pragma vector = T3_VECTOR 
__interrupt void T3_ISR(void) 
{ 
	IRCON = 0x00; //清中断标志, 也可由硬件自动完成 
	if(count++ > 244) //245 次中断后 LED 取反,闪烁一轮(约为 0.5 秒时间) 
	{ 
		count = 0; //计数清零 
		LED1 = ~LED1; //改变 LED1 的状态
	} 
}


void main()
{
	initled();
	initT3();
	
	while(1);
}


参考声明:
https://www.bilibili.com/read/cv2435936?share_medium=android&share_source=qq&bbid=XY059F20DE97643AA518E1D8E5B92F72BC859&ts=1580379008736

发布了13 篇原创文章 · 获赞 3 · 访问量 1860

猜你喜欢

转载自blog.csdn.net/weixin_44127810/article/details/104117781