1.CC2530在正常运行的时候需要一个高频时钟信号和一个低频的时钟信号
2.时钟信号的来源:
3.CC2530芯片默认上电的时候,是内部的两个RC电路作为高频和低频的时钟来源
4.如果我们在用串口,特别是无线通信的时候,必须要用32M的石英晶振作为高频时钟来源
5.高频时钟源的特点:
两个高频时钟源可以同时起振产生高频时钟信号,但同一时刻只能由一个时钟源提供给CC2530;
而两个低频时钟源,某一时刻只能有一个起振,并且起振的这个时钟源供给CC2530
6.系统高频时钟切换步骤
共用到四个寄存器
SLEEPCMD和CLKCONCMD为命令控制寄存器,用于配置时钟
SLEEPSTA和CLKCONSTA为状态判断寄存器,用于判断控制寄存器操作是否成功
注:在第一代Zigbee:CC2430/2431中,SLEEPCMD和SLEEPSTA合并为SLEEP寄存器
(1)让2个高频时钟源起振
(2)等待高频时钟源振荡稳定
(3)延时一段时间
(4)不分频输出
(5)选中32M高频时钟源作为系统主时钟
(6)确认当前工作的系统时钟是不是所选的高频时钟
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设置分频值。
(二)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博客