ARM学习随笔(16)定时器的使用
2014-08-15 19:59
274 查看
ADuC7023具有3个通用定时器/计数器:定时器0、定时器1和定时器2(或看门狗定时器)。
这3个定时器可以在自由模式或周期模式下工作。
在自由模式下,计数器将从最大值递减计数一直到零,并且在达到最小值后重新递增计数。(它也可以从最小值开始递增计数直到满量程并且在达到最大值后重新开始递减计数。)
在周期模式下,计数器以装载寄存器(TxLD寄存器)中的值为起始值,开始递减/递增计数至0或满量程,然后再以该寄存器中的值为起始值,重新开始计数。(即一旦打开定时器,会一直周期循环不停的计数,如果在定时器中断处理程序中没有及早的关闭定时器,则可能会导致中断混乱,这次中断未处理完,下次中断来临。因此很有必要添加这几句:
T1CON=0x40; //关闭定时器,就不会产生中断
T1CLRI = 0; // Clear Timer IRQ
//处理中断代码
//T1CON=0xC0;
//处理完毕后如果还需要采用刚才的装载寄存器装载的值进行定时的话可以再开启中断。
)
通过对某一定时器的控制寄存器(TxCON)进行写操作,可以启动相应的定时器。
①在正常模式下,当递减计数时,每一次计数器的值达到0时就会产生一个IRQ中断。当递增计数时,每一次计数器的值达到满量程值时也会产生一个IRQ中断。向某一定时器(TxCLRI)的清除寄存器内写入任一数据,可以清除IRQ中断。
②当使用异步的时钟定时器时,取消定时器模块内的中断所占用的时间要比执行中断程序中的代码所占用的时间长。在退出中断服务程序之前,要保证中断信号已经被取消。
这可以通过检查IRQSTA寄存器来实现。
定时器间隔可通过下式计算:
Interval:时间间隔 Prescaler:预分频 soure clock:时钟源 TxLD为装载值,计数器加1经历经过预分频时钟源的时间(如分频器为1,时钟源为1KHZ,则计1次经历1毫秒)
定时器有关的寄存器并不多,需要关注的其实就三个 T1CON(控制寄存器:控制时钟源,分频器,定时器开关,定时器模式等) T1LD(装载寄存器) T1CLRI(中断清除寄存器,在中断服务程序中最好加这一句)
几个关键部分:
void Frequency(uint32 frequency)
{
irq_detect=0;
time_limit=0;
T1LD=HCLK/frequency;
GP1DAT=0x01010000;
T1CON=0x000000C0;
IRQEN=0x00000008;
while(!irq_detect);
//等待该频率的方波发送完毕
}
void irq_function(void)
{
if ((IRQSTA & BIT3) == BIT3)
// Timer1 IRQ
{
T1CON=0x40;
//关闭定时器,就不会产生中断
T1CLRI = 0;
// Clear Timer IRQ
time_limit++;
if(time_limit==2)
{
irq_detect=1;
time_limit=0;
}
else
{
GP1DAT=0x01000000;
T1CON=0xC0; //开启定时器
}
}
}
定时器就像是在背后默默的一直算计着,不让他在处理中断的时候停下来的话它也还在计时,你必须把它关了,它才会暂停计时,打开了以后它会继续按照原装载值计时。
PS:在做方波产生程序中,误以为sizeof可以算字符指针中的字符的个数,结果却一直为4,后来知道sizeof是对分配的内存空间计数的,具体如下
实际上,用sizeof来返回类型以及静态分配的对象、结构或数组所占的空间,返回值跟对象、结构、数组所存储的内容没有关系。
具体而言,当参数分别如下时,sizeof返回的值表示的含义如下:
数组——编译时分配的数组空间大小;
指针——存储该指针所用的空间大小(存储该指针的地址的长度,是长整型,应该为4);
类型——该类型所占的空间大小;
对象——对象的实际占用空间大小;
函数——函数的返回类型所占的空间大小。函数的返回类型不能是void。
而strlen返回字符串的长度。该字符串可能是自己定义的,也可能是内存中随机的,该函数实际完成的功能是从代表该字符串的第一个地址开始遍历,直到遇到结束符'\0'。返回的长度大小不包括'\0'。
char str[20]="0123456789";
int a=strlen(str); //a=10; >>>> strlen 计算字符串的长度,以结束符 0x00 为字符串结束。
int b=sizeof(str); //而b=20; >>>> sizeof 计算的则是分配的数组 str[20] 所占的内存空间的大小,不受里面存储的内容改变。
这3个定时器可以在自由模式或周期模式下工作。
在自由模式下,计数器将从最大值递减计数一直到零,并且在达到最小值后重新递增计数。(它也可以从最小值开始递增计数直到满量程并且在达到最大值后重新开始递减计数。)
在周期模式下,计数器以装载寄存器(TxLD寄存器)中的值为起始值,开始递减/递增计数至0或满量程,然后再以该寄存器中的值为起始值,重新开始计数。(即一旦打开定时器,会一直周期循环不停的计数,如果在定时器中断处理程序中没有及早的关闭定时器,则可能会导致中断混乱,这次中断未处理完,下次中断来临。因此很有必要添加这几句:
T1CON=0x40; //关闭定时器,就不会产生中断
T1CLRI = 0; // Clear Timer IRQ
//处理中断代码
//T1CON=0xC0;
//处理完毕后如果还需要采用刚才的装载寄存器装载的值进行定时的话可以再开启中断。
)
通过对某一定时器的控制寄存器(TxCON)进行写操作,可以启动相应的定时器。
①在正常模式下,当递减计数时,每一次计数器的值达到0时就会产生一个IRQ中断。当递增计数时,每一次计数器的值达到满量程值时也会产生一个IRQ中断。向某一定时器(TxCLRI)的清除寄存器内写入任一数据,可以清除IRQ中断。
②当使用异步的时钟定时器时,取消定时器模块内的中断所占用的时间要比执行中断程序中的代码所占用的时间长。在退出中断服务程序之前,要保证中断信号已经被取消。
这可以通过检查IRQSTA寄存器来实现。
定时器间隔可通过下式计算:
Interval:时间间隔 Prescaler:预分频 soure clock:时钟源 TxLD为装载值,计数器加1经历经过预分频时钟源的时间(如分频器为1,时钟源为1KHZ,则计1次经历1毫秒)
定时器有关的寄存器并不多,需要关注的其实就三个 T1CON(控制寄存器:控制时钟源,分频器,定时器开关,定时器模式等) T1LD(装载寄存器) T1CLRI(中断清除寄存器,在中断服务程序中最好加这一句)
几个关键部分:
void Frequency(uint32 frequency)
{
irq_detect=0;
time_limit=0;
T1LD=HCLK/frequency;
GP1DAT=0x01010000;
T1CON=0x000000C0;
IRQEN=0x00000008;
while(!irq_detect);
//等待该频率的方波发送完毕
}
void irq_function(void)
{
if ((IRQSTA & BIT3) == BIT3)
// Timer1 IRQ
{
T1CON=0x40;
//关闭定时器,就不会产生中断
T1CLRI = 0;
// Clear Timer IRQ
time_limit++;
if(time_limit==2)
{
irq_detect=1;
time_limit=0;
}
else
{
GP1DAT=0x01000000;
T1CON=0xC0; //开启定时器
}
}
}
定时器就像是在背后默默的一直算计着,不让他在处理中断的时候停下来的话它也还在计时,你必须把它关了,它才会暂停计时,打开了以后它会继续按照原装载值计时。
PS:在做方波产生程序中,误以为sizeof可以算字符指针中的字符的个数,结果却一直为4,后来知道sizeof是对分配的内存空间计数的,具体如下
实际上,用sizeof来返回类型以及静态分配的对象、结构或数组所占的空间,返回值跟对象、结构、数组所存储的内容没有关系。
具体而言,当参数分别如下时,sizeof返回的值表示的含义如下:
数组——编译时分配的数组空间大小;
指针——存储该指针所用的空间大小(存储该指针的地址的长度,是长整型,应该为4);
类型——该类型所占的空间大小;
对象——对象的实际占用空间大小;
函数——函数的返回类型所占的空间大小。函数的返回类型不能是void。
而strlen返回字符串的长度。该字符串可能是自己定义的,也可能是内存中随机的,该函数实际完成的功能是从代表该字符串的第一个地址开始遍历,直到遇到结束符'\0'。返回的长度大小不包括'\0'。
char str[20]="0123456789";
int a=strlen(str); //a=10; >>>> strlen 计算字符串的长度,以结束符 0x00 为字符串结束。
int b=sizeof(str); //而b=20; >>>> sizeof 计算的则是分配的数组 str[20] 所占的内存空间的大小,不受里面存储的内容改变。
相关文章推荐
- ARM学习随笔(7)keil下Flash magic的使用
- ARM学习随笔(12)定时器查询方式和中断方式
- Atlas学习手记(16):使用PasswordStrength检测密码强度
- javascript学习随笔(使用window 和 frame )
- Effective c++ 条款16学习笔记: 成对使用new和delete时要采取相同形式
- ARM学习之路(二) Vi编辑器的使用(by 星空武哥)
- UNIX网络编程学习(16)--使用poll的TCP服务器程序
- 学习ARM开发(16)
- linux驱动学习之内核定时器使用
- 关于TelephonyManager的使用与手机电池电量小知识(Android学习随笔五)
- [转]Ultra Fractal教程系列16——学习基础技巧08——使用渐变
- Android学习指南之三十四:Android定时器Timer的使用
- javascript学习随笔(使用window和frame)的技巧
- Flex 学习随笔 ---- 使用WebService 与数据库连接
- Atlas学习手记(16):使用PasswordStrength检测密码强度
- arm 学习 + libxml2使用
- Atlas学习手记(16):使用PasswordStrength检测密码强度
- 学习ARM开发(16)
- javascript学习随笔(使用window和frame)的技巧
- 选项卡的使用方法一(Android学习随笔十二)