[ZigBee] 5、ZigBee基础实验——图文与代码详解定时器1(16位定时器)(长文)

1、定时器1概述

  定时器1 是一个支持典型的定时/计数功能的独立16 位定时器,支持输入捕获,输出比较和PWM等功能。定时器有五个独立的捕获/比较通道。每个通道定时器要使用一个I/O 引脚。定时器用于范围广泛的控制和测量应用,可用的五个通道的正计数/倒计数模式将允许诸如电机控制应用的实现。

  定时器1 的功能如下:

• 五个捕获/比较通道
• 上升沿、下降沿或任何边沿的输入捕获
• 设置、清除或切换输出比较
• 自由运行、模或正计数/倒计数操作
• 可被1,8,32 或128 整除的时钟分频器
• 在每个捕获/比较和最终计数上生成中断请求
•  DMA 触发功能

2、16 位计数器

  【关于分频,时钟】定时器包括一个16 位计数器,在每个活动时钟边沿递增或递减。活动时钟边沿周期由寄存器位CLKCON.TICKSPD定义,它设置全球系统时钟的划分,提供了从0.25MHz 到32MHz 的不同的时钟标签频率(可以使用32 MHz XOSC 作为时钟源)。这在定时器1 中由T1CTL.DIV设置的分频器值进一步划分。这个分频器值可以从1、8、32 或128。因此当32 MHz 晶振用作系统时钟源时,定时器1 可以使用的最低时钟频率是1953.125Hz,最高是32 MHz。当16MHz RC 振荡器用作系统时钟源时,定时器1 可以使用的最高时钟频率是16MHz。

  【读取定时器当前值】计数器可以作为一个自由运行计数器,一个模计数器或一个正计数/倒计数器运行,用于中心对齐的PWM。可以通过两个8 位的SFR 读取16 位的计数器值:T1CNTHT1CNTL,分别包含在高位字节和低位字节中。当读取T1CNTL 时,计数器的高位字节在那时被缓冲到T1CNTH,以便高位字节可以从T1CNTH 中读出因此!!!T1CNTL 必须总是在读取T1CNTH 之前首先读取。对T1CNTL 寄存器的所有写入访问将复位16 位计数器。当达到最终计数值(溢出)时,计数器产生一个中断请求。

  【控制定时器】可以用T1CTL 控制寄存器设置启动并停止该计数器。当一个不是00 值的写入到T1CTL.MODE 时,计数器开始运行。如果00 写入到T1CTL.MODE,计数器停止在它现在的值上。

3、定时器1 操作

  一般来说控制寄存器T1CTL 用于控制定时器操作。状态寄存器T1STAT 保存中断标志。各种操作模式如下所述。

4、自由运行模式

  在自由运行操作模式下,计数器从0x0000 开始,每个活动时钟边沿增加1。当计数器达到0xFFFF(溢出),计数器载入0x0000,继续递增它的值,如图1 所示。当达到最终计数值0xFFFF,设置标志IRCON.T1IF 和T1STAT.OVFIF。如果设置了相应的中断屏蔽位TIMIF.OVFIM 以及IEN1.T1EN,将产生一个中断请求。自由运行模式可以用于产生独立的时间间隔,输出信号频率。(0xFFFF型)

               图1 自由运行模式

5、模模式

  当定时器运行在模模式,16 位计数器从0x0000 开始,每个活动时钟边沿增加1。当计数器达到T1CC0(溢出),寄存器T1CC0H:T1CC0L 保存的最终计数值,计数器将复位到0x0000,并继续递增。如果定时器开始于T1CC0 以上的一个值,当达到最终计数值(0xFFFF)时,设置标志IRCON.T1IF 和T1CTL.OVFIF。如果设置了相应的中断屏蔽位TIMIF.OVFIM 以及IEN1.T1EN,将产生一个中断请求。模模式可以用于周期不是0xFFFF的应用程序。计数器的操作展示在图2 中。(自定义上限型)

              图2 模模式

6、正计数/倒计数模式

  在正计数/倒计数模式,计数器反复从0x0000 开始,正计数直到达到T1CC0H:T1CC0L 保存的值。然后计数器将倒计数直到0x0000,如图3 所示。这个定时器用于周期必须是对称输出脉冲而不是0xFFFF 的应用程序,因此允许中心对齐的PWM 输出应用的实现。在正计数/倒计数模式,当达到最终计数值时,设置标志IRCON.T1IF 和T1CTL.OVFIF。如果设置了相应的中断屏蔽位TIMIF.OVFIM 以及IEN1.T1EN,将产生一个中断请求。(增减交替型)

            图3 正计数/倒计数模式

7、通道模式控制

  通道模式随着每个通道的控制和状态寄存器T1CCTLn 设置。设置包括输入捕获和输出比较模式。

8、 输入捕获模式

  当一个通道配置为输入捕获通道,和该通道相关的I/O 引脚必须被配置为输入。(什么是输入捕获模式,运作机制)在启动定时器之后,输入引脚的一个上升沿、下降沿或任何边沿都将触发一个捕获,即把16 位计数器内容捕获到相关的捕获寄存器中。因此定时器可以捕获一个外部事件发生的时间。(捕获外部事件发生时间)

   注意:在定时器可以使用一个输入/输出引脚之前,所需的I/O 引脚必须配置为定时器1 的外设引脚。通道输入引脚和内部系统时钟是同步的。因此输入引脚上的脉冲的最低持续时间必须大于系统时钟周期。

  16 位捕获寄存器的内容从寄存器T1CCnH:T1CCnL 中读出。当捕获发生时,要设置IRCON.T1IF 标志和该通道的中断标志T1STAT.CHnIF(n 是通道号码)。如果分别设置了相应的中断屏蔽位T1CCTLn.IM,以及IEN1.T1EN,将产生一个中断请求。

9、输出比较模式(最难理解的一个,下面的边沿对其和中心对其其实是基于输出比较的运作核心,用上面讲的几种简单的模式实现PWM,中心对齐是利用模模模式实现的)

  在输出比较模式中,与通道相关的IO要设置为输出模式。(什么是输出比较模式,运作机制)在定时器启动后, 计数器的内容会和通道比较寄存器中的内容T1CCnH:T1CCnL做比较。如果这两个内容(值)相等,输出引脚根据比较输出模式T1CCTLn.CMP的设置进行设置、复位或切换。(核心就是将T1CC0的值和每个通道寄存器中的值比较,相等了则产生中断等)

   注意:输出引脚运行在一个给定输出比较模式下时,它上面的所有边沿都是无故障运行的。

  写入比较寄存器T1CCnL 将被缓冲,这样写入到T1CCnL 的值不起作用,直到相应的高位寄存器T1CCnH 被写入。写入比较寄存器T1CCnH:T1CCnL 对于输出比较值不起作用,直到定时器达到0x00。

  注意:通道0 的输出比较模式较少,因为T1CC0H:T1CC0L 在模式6 和7 有一个特殊功能,这意味着这些模式对于通道0 是不能使用的。

  当发生一个比较时,设置IRCON.T1IF 标志和该通道的中断标志T1STAT.CHnIF(n 是通道号码)。如果分别设置了相应的中断屏蔽位T1CCTLn.IM,以及IEN1.T1EN,将产生一个中断请求。

  不同定时器模式下输出比较模式的例子给定在以下图中。

  边沿对齐:PWM 输出信号可以使用定时器在自由运行模式下,通道1 和2 在输出比较模式6 或7(第6和第7条线)下生成(由T1CCTLn.CMP 位定义,其中n 是1 或2),如图4 所示。PWM 信号的周期通过设置T1CC0 确定,通道输出的占空比由T1CCn 确定,其中n 是PWM 通道1 或2。也可以使用定时器自由运行模式。在这种情况下,T1CTL.DIV 位中的CLKCON.TICKSPD 和分频器值设置PWM 信号的周期。PWM 信号的极性由使用的是输出比较模式6 还是7 确定。PWM 输出信号还可以使用图4 所示的输出比较模式4 和5,或通过使用图5 所示的模模式生成。对于简单的PWM,最好使用使用输出比较模式4 和5 来生成。

  

               图4 输出比较模式,定时器自由运行模式

            图中0、1、2...6是7种模式,左边的波形对应每种模式

  

                

               图5 输出比较模式,定时器模模式

  中心对齐:PWM 输出可以通过选择定时器正计数/倒计数模式生成。根据PWM 信号所需的极性选择通道输出比较模式4 或5(由T1CCTLn.CMP 位定义,其中n 是1 或2)。PWM 信号的周期由T1CC0 确定,通道输出的占空比由T1CCn 确定,其中n 是PWM 通道1 或2。某些类型的电机驱动应用程序会需要中心对齐的PWM 模式,一般地这比边沿对齐的PWM 模式产生的噪音更少,因为I/O 引脚传输不集中在同一个时钟边沿上。

  

              图6  输出比较模式,定时器正计数/倒计数模式

  (附加小姿势)在一些类型的应用程序中,需要在输出之间定义一个延迟或死亡的时间。典型地,这用于输出驱动一个H桥配置,以避免H 桥的一边交叉传导失控。延迟或死亡时间可以通过使用T1CCn 在PWM 输出中获得,如下所示:
  假定通道1 和通道2 使用定时器正计数/倒计数模式,用于驱动输出,且这两个通道分别使用输出比较模式4 和5,那么定时器周期(定时器1 的时钟周期)是:
  tP = T1CC0 x 2
  死亡时间,即两个输出都为低电平的时间,(定时器1 的时钟周期)是:
  tD = T1CC1 – T1CC2
  当下列情况发生,比较输出引脚初始化为表9-1 所列的值:

?? 一个值被写入T1CNTL(所有定时器1 通道)
?? 0x7 被写到T1CCTLn.CMP(通道n)

                表9-1 初始的比较输出值(比较模式)

10、IR 信号产生和线性化 (*

  本节描述了CC253x 设备只需最少的SW 参与即可产生IR 的功能。

10.1、简介(*

  为远程控制产生IR 信号一般以下面两种方式之一完成:

?? 调制码
?? 非调制码(C 码,闪存代码)

  CC253x 包括灵活的定时器功能,以最少的CPU 参与,来执行这两种类型的IR 信号的产生和线性化。大多数IR 协议每个命令只需一个CPU 干预即可实现。

10.2、调制码(*

  调制码可以使用定时器1(16 位)和定时器3(8 位)生成。处于调制模式的定时器3 用于产生载波。定时器3 有一个单独的分频器,用于它的输入。它的周期使用T3CC0 设置。定时器3 通道1 用于PWM 输出。载波的占空比使用T3CC1 设置。通道1 使用比较模式:“在比较设置输出,在0xFF 清除”(T3CCTL1.CMP = 101)。
表9-2 显示了定时器3 的38kHz 载波的频率误差计算。(用定时器3产生载波)

              38kHz 载波的频率误差计算

  

  IRCTL.IRGEN 寄存器位使得IR 产生模式处于定时器1。当设置了IRGEN 位,定时器1采用定时器3通道1的输出比较信号作为标记,而不是采用系统标记。定时器1周期是使用T1CC0 设置的,定时器1处于调制模式(T1CTL.MODE = 10),通道0处于比较模式(T1CCTL0.MODE = 1)。通道1比较模式“在比较设置输出,在0x0000 清除”(T1CCTL1.CMP = 011)用于输出门控信号。

  标记载波的个数由T1CC1. T1CC1 设置,需要每个定时器1 周期由DMA 或CPU 更新一次。注意T1CC1的一个更新被缓冲,在定时器1 达到0x0000 之前不起作用。

  空间载波的个数由T1CC0 设置。其值必须设置为标记和空间载波周期希望的总数。比较值被缓冲直到定时器达到0x0000。

  定时器1 通道1 的输出进行定时器3 通道1 的输出和运算,作为IR 的输出,如图。

                图7  定时器在IR 产生模式的方框图

  定时器3 通道1 输出和定时器1 通道1 输出信号的时序是同步的,这样在IR 输出信号上就没有故障。当设置了IRGEN 位,IR 输出信号被送到引脚,而不是送到一般的定时器1 通道1 输出。下图显示了定时器3 被初始化为33%的占空比(T3CC0 = 3× T3CC1)的例子。定时器1 已经被初始化为3。(如果仅仅要实现一个空间周期,T1CC1 必须设置为0x00。)

                图8  调制的波形示例

10.3 非调制码(*

  要产生非调制IR 码,定时器1 要处于模模式。信号的周期由T1CC0 给定,脉冲宽度由T1CC1 给定。T1CC1给出标记周期的长度,T1CC0 给出标记和空间周期的总数。比较值被缓冲,直到定时器达到0x0000。如果比较值不能保持不变,必须在每个周期由DMA 或CPU 更新。

10.4 学习(*

  学习通过使用定时器1(16 位)和定时器3(8 位)的捕获功能完成。定时器3 可以处理载波频率检测,定时器1 可以处理调制信代码的学习。电路应该按照图9 所述安装。

            图9 IR 学习的方框图

10.4.1 载波频率检测(*

  定时器3 用于捕获和检测直接从IR 引脚二极管输入的载波频率。定时器必须对载波进行一定次数的采样。如果载波被检测,被检测出的频率必须提供平均数,这会存储在数据库中。

10.4.2 解调码学习(*

  IR 引脚二极管的输出由一个合适的电路解调。这一电路的输出用作处于捕获模式的定时器1 其中一个通道的输入。

10.5 其他注意事项(*

  IR 输出引脚在复位期间必须处于三态或下拉状态,以避免点亮IR LED 这一不必要的功耗。注意只有定时器1 通道1 的输出P1.1 是三态的,在复位期间和复位后没有上拉。

11、定时器1 中断

  为定时器分配了一个中断向量。当下列定时器事件之一发生时,将产生一个中断请求:

● 计数器达到最终计数值(溢出或回到零)
● 输入捕获事件
● 输出比较事件

  寄存器状态寄存器T1STAT 包括最终计数值事件和五个通道比较/捕获事件的中断标志。仅当设置了相应的中断屏蔽位和IEN1.T1EN 时,才能产生一个中断请求。中断屏蔽位是n 个通道的T1CCTLn.IM 和溢出事件TIMIF.OVFIM。如果有其它未决中断,必须在一个新的中断请求产生之前,通过软件清除相应的中断标志。而且,如果设置了相应的中断标志,使能一个中断屏蔽位将产生一个新的中断请求。

12、定时器1 DMA 触发

  有三种DMA 触发与定时器1 有关。这些是DMA 触发T1_CH0,T1_CH1 和T1_CH2,分别在以下定时器比较事件上产生:

● T1_CH0 – 通道0 比较
● T1_CH1 – 通道1 比较
● T1_CH2 – 通道2 比较

  通道3 和4 没有相关的触发。

13、定时器1 寄存器

  本节描述了定时器1 的寄存器,由以下寄存器组成:

● T1CNTH – 定时器1 计数高位
● T1CNTL – 定时器1 计数低位
● T1CTL – 定时器1 控制
● T1STAT –定时器1 状态
● T1CCTLn – 定时器1 通道n 捕获/比较控制
● T1CCnH – 定时器1 通道n 捕获/比较高位值
● T1CCnL – 定时器1 通道n 捕获/比较低位值

  TIMIF.OVFIM 寄存器位驻留在TIMIF 寄存器,和定时器3 和定时器4 寄存器一起描述。

14、作为数组访问定时器1 寄存器

  定时器1 捕获/比较通道寄存器可以在XDATA 存储空间中作为一个连续的区域被访问。这使得可以作为一个简单的索引结构方便地访问寄存器。5 个捕获/比较控制寄存器映射到0x62A0 - 0x62A4。16 位捕获/比较值映射到0x62A6 - 0x62AF。0x62A5 不使用。

15、代码示例

15.1、定时器轮训方式

  下面代码展示了通过设置定时器1计数来控制LED闪烁,这里没有采用中断方式,而是采用普通的轮训。关于LED的初始化我在前几节已经介绍了。这里重点看和定时器1相关的部分:

  ① 第33行将T1CTL设置为0x0d=0000 1101,参考下面寄存器表可知是通过设置定时器1的控制和状态寄存器来将定时器设置为:128分频,自由运行,从0x0000到0xFFFF反复计数。由于系统在没配置工作频率时默认是2分频,即32MHz/2=16MHz,因此定时器每次溢出的时间T=1/(16MHz/128)*65536=0.524s

  

  ② 第34行将T1STAT设置为0x21=0010 0001,参考下面的寄存器表知为使用定时器1的通道0,且中断有效。

  ③ 在49行一旦IRCON>0表明发生了某个中断,在该例程中我们仅仅用了TIMER1的中断,因此表明TIMER1中断发生:

  因此下面整个程序实现的功能是:利用定时器1的通道0产生0.524s的周期性中断,每次发生中断系统会自动置IRCON的第1位为1,在main函数的轮训中一旦检测到该信息,则让计数变量count加1,一旦count计数大于1时,就让LED状态翻转,实现1SLED闪烁控制。

 1 /****************************************************************************
 2 * 文 件 名: main.c
 3 * 版    本: 1.0
 4 * 描    述: 定时器T1通过查询方式控制LED1周期性闪烁
 5 ****************************************************************************/
 6 #include <ioCC2530.h>
 7
 8 typedef unsigned char uchar;
 9 typedef unsigned int  uint;
10
11 #define LED1 P1_0       // P1.0口控制LED1
12
13 /****************************************************************************
14 * 名    称: InitLed()
15 * 功    能: 设置LED灯相应的IO口
16 * 入口参数: 无
17 * 出口参数: 无
18 ****************************************************************************/
19 void InitLed(void)
20 {
21     P1DIR |= 0x01;      //P1.0定义为输出
22     LED1 = 1;           //使LED1灯上电默认为熄灭
23 }
24
25 /****************************************************************************
26 * 名    称: InitT1()
27 * 功    能: 定时器初始化,系统不配置工作时钟时默认是2分频,即16MHz
28 * 入口参数: 无
29 * 出口参数: 无
30 ****************************************************************************/
31 void InitT1()
32 {
33     T1CTL = 0x0d;       //128分频,自动重装 0x0000-0xFFFF
34     T1STAT= 0x21;       //通道0,中断有效
35 }
36
37 /****************************************************************************
38 * 程序入口函数
39 ****************************************************************************/
40 void main(void)
41 {
42     uchar count=0;
43
44     InitLed();             //调用初始化函数
45     InitT1();
46
47     while(1)
48     {
49         if(IRCON > 0)
50         {
51             IRCON=0;
52             if(count++ >= 1) //约1s周期性闪烁,示波器测大约为1025MS
53             {
54               count=0;
55               LED1 = !LED1;  //LED1闪烁
56             }
57         }
58     }
59 }

15.2、定时器中断方式

  上面采用轮训的方法是比较占资源的,类似我们按键那节中介绍的,除了轮训我们还可以用中断方式!在黄色初始化部分比采用轮训方式多了使能T1中断和总中断的部分(35、36行代码)。我之前没有加这两句代码,结果橙色部分的定时器1中断回调函数无法被触发!查datasheet发现Interrupt Overview:如果想触发回调函数,需要将EA开关和T1IE开关打开才行!

 1 /****************************************************************************
 2 * 文 件 名: main.c
 3 * 版    本: 1.0
 4 * 描    述: 定时器T1通过查询方式控制LED1周期性闪烁
 5 ****************************************************************************/
 6 #include <ioCC2530.h>
 7
 8 typedef unsigned char uchar;
 9 typedef unsigned int  uint;
10
11 #define LED1 P1_0       // P1.0口控制LED1
12
13 /****************************************************************************
14 * 名    称: InitLed()
15 * 功    能: 设置LED灯相应的IO口
16 * 入口参数: 无
17 * 出口参数: 无
18 ****************************************************************************/
19 void InitLed(void)
20 {
21     P1DIR |= 0x01;      //P1.0定义为输出
22     LED1 = 1;           //使LED1灯上电默认为熄灭
23 }
24
25 /****************************************************************************
26 * 名    称: InitT1()
27 * 功    能: 定时器初始化,系统不配置工作时钟时默认是2分频,即16MHz
28 * 入口参数: 无
29 * 出口参数: 无
30 ****************************************************************************/
31 void InitT1()
32 {
33     T1CTL = 0x0d;       //128分频,自动重装 0x0000-0xFFFF
34     T1STAT= 0x21;       //通道0,中断有效
35     T1IE = 1;                //开总中断和T1中断
36     EA = 1;                  //开总中断
37 }
38
39 //定时器T1中断处理函数
40 #pragma vector = T1_VECTOR
41 __interrupt void T1_ISR(void)
42 {
43     static uchar count=0;
44     IRCON = 0x00;            //清中断标志, 也可由硬件自动完成
45     if(count++ >= 1) //约1s周期性闪烁,示波器测大约为1025MS
46     {
47       count=0;
48       LED1 = !LED1;  //LED1闪烁
49     }
50 }
51
52 /****************************************************************************
53 * 程序入口函数
54 ****************************************************************************/
55 void main(void)
56 {
57     InitLed();             //调用初始化函数
58     InitT1();
59
60     while(1){}
61 }

Zigbee系列文章:

[ZigBee] 1、 ZigBee简介

[ZigBee] 2、 ZigBee开发环境搭建

[ZigBee] 3、ZigBee基础实验——GPIO输出控制实验-控制Led亮灭

[ZigBee] 4、ZigBee基础实验——中断

PS:如果您觉得还不错,点个赞,让更多人受益~

@beautifulzzzz 2016-07-13 continue~  
e-mail:[email protected] 
sina:http://weibo.com/beautifulzzzz?is_all=1

时间: 2024-10-18 16:06:29

[ZigBee] 5、ZigBee基础实验——图文与代码详解定时器1(16位定时器)(长文)的相关文章

tiny_cnn代码详解(3)——层间继承关系

在上一篇博文中我们顺利将tiny_cnn的程序调试通过,在这篇博文中我们尝试从整体角度给出对tiny_cnn这个深度学习框架的解读,重点论述一下其各个层直接类封装的继承关系. 一.卷积神经网络快速入门 tiny_cnn作为卷积神经网络的一种实现形式,在探讨其框架结构之前,首先需要简要介绍一些卷积神经网络相关的知识.首先,给出经典卷积神经网络的网络结构: 这个是经典的LeNet-5的网络结构图,五层网络.最早用于支票上的手写数字识别,也是最早的商业化的深度学习模型.从上图中可以看出,卷积神经网络主

Github-jcjohnson/torch-rnn代码详解

Github-jcjohnson/torch-rnn代码详解 [email protected] http://www.cnblogs.com/swje/ 作者:Zhouwan  2016-3-18 声明: 1)本文仅供学术交流,非商用.所以每一部分具体的参考资料并没有详细对应.如果某部分不小心侵犯了大家的利益,还望海涵,并联系博主删除. 2)本人才疏学浅,整理总结的时候难免出错,还望各位前辈不吝指正,谢谢. 请联系:[email protected] 或[email protected] 本研

开胃小菜——impress.js代码详解

README 友情提醒,下面有大量代码,由于网页上代码显示都是同一个颜色,所以推荐大家复制到自己的代码编辑器中看. 今天闲来无事,研究了一番impress.js的源码.由于之前研究过jQuery,看impress.js并没有遇到太大的阻碍,读代码用了一个小时,写这篇文章用了近三个小时,果然写文章比读代码费劲多了. 个人感觉impress.js的代码量(算上注释一共不到1000行)和难度(没有jQuery的各种black magic= =)都非常适合新手学习,所以写一个总结,帮助大家理解源码. 考

android四大基础组件--Service生命周期详解

android四大基础组件--ServiceService 生命周期详解 1.Service的生命周期: I> 在非绑定Service情况下,只有oncreate(),onStartCommand(),onDestory()方法情况下:  操作方法对应生命周期一: a.[执行startService(Intent)] 执行生命周期方法:oncreate()--->onStartCommand(): b.[执行stopService(Intent)] 执行生命周期方法:onDestory();

jQuery选择器代码详解(二)——select方法

原创文章,转载请注明出处,多谢! /* * @param selector 已去掉头尾空白的选择器字符串 * @param context 执行匹配的最初的上下文(即DOM元素集合).若context没有赋值,则取document. * @param results 已匹配出的部分最终结果.若results没有赋值,则赋予空数组. * @param seed 初始集合 */ function select(selector, context, results, seed) { var i, to

【夯实基础】java关键字synchronized 详解

尊重版权:http://www.cnblogs.com/GnagWang/archive/2011/02/27/1966606.html Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块. 二.然而,当一个线程访问object的一个sy

C#网络编程基础之进程和线程详解

在C#的网络编程中,进程和线程是必备的基础知识,同时也是一个重点,所以我们要好好的掌握一下. 一:概念 首先我们要知道什么是"进程",什么是"线程",好,查一下baike. 进程:是一个具有一定独立功能的程序关于某个数据集合的一次活动.它是操作系统动态执行的基本单元, 在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元. 线程:是"进程"中某个单一顺序的控制流. 关于这两个概念,大家稍微有个印象就行了,防止以后被面试官问到. 二:进程

Java基础11:Java泛型详解

Java基础11:Java泛型详解 泛型概述 泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用. 什么是泛型?为什么要使用泛型? 泛型,即"参数化类型".一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参.那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参). 泛型的本质是为了参数化类型(在不创建新的类型的

ARM Cortex-M底层技术(2)—启动代码详解

杂谈 工作了一天,脑袋比较乱.一直想把底层的知识写成一个系列,希望可以坚持下去.为什么要写底层的东西呢?首先,工作用到了这部分内容,最近和内部Flash打交道比较多,自然而然会接触到一些底层的东西:第二,近些年来Cortex-M阵营各厂商(ST.Nordic.ATMEL……)对新产品的迭代速度越来越快,以及微控制器应用普及程度的加深,越来越多的开发者把更多精力投注在应用层开发上,花在对底层技术上的时间越来越少,更深层次的原因是走嵌入式底层没有做互联网上层赚钱.希望自己可以把嵌入式ARM Cort