概述
cc2530一共有4个定时器:
可以看到,一个MAC Timer ,一个 16为和两个8为的定时器,现在我将就16位的定时器来实现定时闪烁LED灯
1)创建Timer驱动文件,编写Timer初始化函数:
我们默认的时钟频率是8Mhz 所以需要我们手动更改,1.1是配置32Mhz时钟的写法,直接复制粘贴即可;
注意,定时器的原理其实可以抽象成一个水龙头滴水模型,水柱大小就是时钟频率,而水的阀门就是分频器,与stm32不同,cc2530分频有限:分为:1、8、32、128 分频
我们选择设置1ms定时:
水桶就是计数器,也就是滴了多少滴水后溢出,我们需要设置为1000,换成十六进制就是3E8,
分别对应寄存器高八位和低八位;
为什么是1000?
我们设置分频为32分频,也就是记一次为1/1000000s.该书乘以1000不就是1ms吗
因为配置寄存器比较死板,所以推荐大家复制即可,只要会算周期就可以。
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*函数名:TimerInit
*参数:none
*返回:none
*描述:定时器初始化函数
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void TimerInit(void)
{
//1.1 配置系统时钟为32Mhz
CLKCONCMD &= ~0x40;
for(;CLKCONSTA & 0x40;);
CLKCONCMD &= ~0x7F;
//1.2 初始化定时器
T1CTL = 0x0A;//定时器控制寄存器:模式为模模式,为32分频
T1CC0H = 0x03;//定时器高八位
T1CC0L = 0xE8;//定时器1低八位
T1CCTL0 |= 0x04;//定时器模式为比较模式
//1.3 定时器中断初始化
EA = 1;//开总中断
T1IE = 1;//定时器1中断使能
//6.2 结构体变量的初始化
pa1.CheckTime = 0;
pa1.SetTime = 0;
pa1.Flag = 0;
}
代码后面已经含有相关介绍,应该看得懂,6.2 的不用管,这只是后面用来存变量的一个结构体初始化的内容。
2)、编写中断函数:
#pragma vector=T1_VECTOR
__interrupt void T1_INT(void)
{
//2.1 定时器标志位清零
T1IF = 0;
//2.2 定时器计数
SysTimeNum++;
}
中断函数比较简单,中断向量和中断函数的写法也是固定的,复制即可,这里要注意的是中断标志位,T1IF同其他中断一样,系统不会自动置0,需要我们手动编写。
3)、实现计数函数:
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*函数名:TimerSet
*参数:set
*返回:unsigned long
*描述:定时器s设定时间函数
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned long TimerSet(unsigned long set)
{
return SysTimeNum + set;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*函数名:TimerCheck
*参数:check
*返回:unsigned char
*描述:定时器比较时间函数
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned char TimerCheck(unsigned long check)
{
return (unsigned char)(SysTimeNum > check);
}
这里我要说明一下,这个计数函数只好用于学习,因为他有一个隐患,就是会溢出,不过通过这个原理可以利用回调函数来进行环式的计算就不会出现溢出
那么这个思路是什么呢?
就是定义一个计数的变量,传入一个总时间,然后在中断函数里让计数变量自增,在主函数里面判断溢出即可:
3)、主函数代码:
void main(void)
{
LEDInit();
TimerInit();
static unsigned long ledtime = 0;
TimeSetCallBack(500,TimeLed,1);
while(1)
{
if(TimerCheck(ledtime))
{
ledtime = TimerSet(500);
LEDToggle(0);
}
}
}
主函数里面定义了一个存储时间的变量ledtime ,那么是如何实现的计时呢?
原理:初始化变量ledtime = 0;那么在第一次进如判断的时候TimerCheck(ledtime)的值就是1,也即是会执行括号里面的赋值与LED反转语句,第一次将ledtime 赋了500,那么下次条件为真的时候就是5ms之后,也就是led反转的时间。
好了,对于一些不完美的地方,可以试着自己动手改善;
都看到这了,不妨看看你还有那些需要的吧:
专注分享:公众号“代码栈”
最后
以上就是飞快帆布鞋为你收集整理的cc2530 定时器T1的运用:实现毫秒级而别LED闪烁;详细的全部内容,希望文章能够帮你解决cc2530 定时器T1的运用:实现毫秒级而别LED闪烁;详细所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复