lesson4上 Zigbee时钟+定时器

1.CC2530在正常运行的时候需要一个高频时钟信号和一个低频的时钟信号

  • 高频时钟信号,主要供给CPU,保证程序的运行
  • 低频时钟信号,主要供给看门狗、睡眠定时器等偏上外设

2.时钟信号的来源:

  • 高频信号有两个:CPU芯片内部自带的16M的RC振荡电路或外部接入的32M石英晶振
  • 低频信号也有两个来源:芯片内部的32K RC电路或者外部接入的32.768K石英晶振

3.CC2530芯片默认上电的时候,是内部的两个RC电路作为高频和低频的时钟来源

4.如果我们在用串口,特别是无线通信的时候,必须要用32M的石英晶振作为高频时钟来源

5.高频时钟源的特点:

两个高频时钟源可以同时起振产生高频时钟信号,但同一时刻只能由一个时钟源提供给CC2530;

而两个低频时钟源,某一时刻只能有一个起振,并且起振的这个时钟源供给CC2530

6.系统高频时钟切换步骤

lesson4上 Zigbee时钟+定时器_第1张图片

共用到四个寄存器

SLEEPCMD和CLKCONCMD为命令控制寄存器,用于配置时钟

SLEEPSTA和CLKCONSTA为状态判断寄存器,用于判断控制寄存器操作是否成功

注:在第一代Zigbee:CC2430/2431中,SLEEPCMD和SLEEPSTA合并为SLEEP寄存器

lesson4上 Zigbee时钟+定时器_第2张图片

lesson4上 Zigbee时钟+定时器_第3张图片

lesson4上 Zigbee时钟+定时器_第4张图片

(1)让2个高频时钟源起振

  • 让SLEEPCMD寄存器的第2位为0,注:上电默认为1

(2)等待高频时钟源振荡稳定

  • SLEEPSTA寄存器的第6位为1表示32M 时钟源稳定

(3)延时一段时间

  • 超过63us延时

(4)不分频输出

  • 把寄存器CLKCONCMD的低3位,设置为000,表示不分频输出

(5)选中32M高频时钟源作为系统主时钟

  • 把寄存器CLKCONCMD的第6位,设置为0,表示32M作为系统主时钟;设置为1,表示16M作为系统主时钟,注:上电默认为1

(6)确认当前工作的系统时钟是不是所选的高频时钟

  • 如果读取CLKCONSTA寄存器的第6位为0,表示32M的时钟源已经作为系统主时钟,程序可以继续往下运行了

7.时钟配置程序实现

#include "iocc2530.h"
void delay()
{
  int i,j;
  for(i=0;i<1000;i++)
    for(j=0;j<800;j++);
}

void delay_us()
{
  char k=63;
  while(k--);
}
void Init32M()
{
  SLEEPCMD &= ~(0x01<<1); //1111 1110 开启两个高频时钟源
  while(SLEEPSTA & 0x40==0);//0100 0000 等待32M稳定
  delay_us();
  CLKCONCMD &= 0xF8;//低3位清零 不分频输出
  CLKCONCMD &= 0xBF; //1011 1111 设置32M为系统主时钟
  while(CLKCONSTA & 0x40); //0100 0000 等待32M成功配置为当前系统主时钟
}

void main()
{
  Init32M();
  P1SEL &= 0xFE;
  P1DIR |= 0x01;
  while(1)
  {
    P1_0^=1;
    delay();
  }
}

8.定时器(常用定时器1和定时器3/4)

CC2530的定时/计数器

CC2530共有6个定时/计数器(4个通用 + 2个特殊功能)

(1)定时器1: 16位定时器,功能最全,应优先选用

支持输入捕获、输出比较、PWM输出、触发DMA

5个独立的捕获/比较通道

具有三种工作模式:自由运行模式、模模式、正计数/倒计数模式

(2)定时器2: 16位定时器,用于CSMA-CA提供定时(一般很少使用)

(3)定时器3、定时器4: 8位定时器

支持输入捕获、输出比较

2个独立的捕获/比较通道(对应2个I/O引脚)

具有四种工作模式:自由运行模式、倒计数、模模式、正计数/倒计数模式

(4)睡眠定时器: 24位正计数定时器,运行在32.768KHz的时钟频率,主要用于系统进入或退出低功耗睡眠模式之间的周期定时

(5)看门狗定时器: 15位计数器,频率由32.768KHz时钟源规定(不使用看门狗功能时,可作为通用的定时器)

9.定时器寄存器以及时常计算

寄存器

(一)T1CTL:定时器1的控制寄存器。D1、D0控制运行模式;D3、D2设置分频值。

lesson4上 Zigbee时钟+定时器_第5张图片

(二)T1STAT:定时器1的状态寄存器,D4-D0位通道4到通道0的中断标志,D5为溢出标志,当到达最终值自动置1;

(三)IRCON:中断标志寄存器;0为无中断请求,1为有中断请求。

(四)IEN1:中断允许寄存器1

时长计算

这里假设定时器 1s,外部时钟16M 32分频 自由模式

在这里我们是计划定时一秒 那么计数器要计多少次呢?在这里我们定义计数器次数为为number

number = 1s/(32/16000000) = 500000

在这里我们计数器需要计数 500000 在前面我们知道 在前面我们知道自由模式需要计数器计数到 0xFFFF(65535)次才溢出一次也就是进入一次中断(中断来源第一点),那么我们让进入中断为count

count = 500000/65536 = 7.6 也就是进入中断七次 我们可以通过判断进入七次 来判断一秒的时间

定时器代码区

T1CTL = 0x09  //0000 1001 32分频,自由模式

程序实现:使用定时器1 模模式 系统时钟为16MHz,分频系数为128,定时0.1s

实现LED1状态每秒翻转,LED2状态每10秒翻转

#include "iocc2530.h"
void delay()
{
  int i,j;
  for(i=0;i<1000;i++)
    for(j=0;j<800;j++);
}

void delay_us()
{
  char k=63;
  while(k--);
}
void Init32M()
{
  SLEEPCMD &= ~(0x01<<1); //1111 1110 开启两个高频时钟源
  while(SLEEPSTA & 0x40==0);//0100 0000 等待32M稳定
  delay_us();
  CLKCONCMD &= 0xF8;//低3位清零 不分频输出
  CLKCONCMD &= 0xBF; //1011 1111 设置32M为系统主时钟
  while(CLKCONSTA & 0x40); //0100 0000 等待32M成功配置为当前系统主时钟
}
void Init_Timer1()//定时器1模模式 系统时钟为16MHz,分频系数为128,定时0.1s
{  
  //设置最大计数值 
  T1CC0L = 0xd4;//低8位 
  T1CC0H = 0x30;//高8位

  //开启通道0的比较模式 
  T1CCTL0 |= 0x04;  
  
  //使能定时器1的中断 
  T1IE = 1;  
  //T1OVFIM = 1;定时器1溢出中断,因为复位置1,可不设置  
  
  //使能总中断 
  EA = 1;
    
  
  //设置定时器1的分配系数和工作模式 
  T1CTL = 0x0e;//分频系数是128模模式
}
void main()
{
  //Init32M();
  Init_Timer1();
  P1SEL &= 0xFC;//P1_0 P1_1
  P1DIR |= 0x03;
  while(1);
}
#pragma vector = T1_VECTOR
__interrupt void Timer1_Sevice(){
    static char count=0; 
    //清除定时器1通道0中断标志
    T1STAT &= ~0x01;
    if(++count%10==0)
    {
      P1_0=~P1_0;
    }
    if(count==100)
    {
      count=0;
      P1_1=~P1_1;
    }
}

定时器具体使用参考见链接:CC2530的定时/计数器原理与应用_cc2530定时器_364.99°的博客-CSDN博客

此外定时器3/4的使用见链接:定时器 T3定(8 位)通过中断方式控制 LED_定时器中断2秒高低8位_RockeyQin的博客-CSDN博客

你可能感兴趣的:(Zigbee无线设备通信,嵌入式硬件,物联网)