logo
 
首页-> 产品信息-> 8位单片机
 
入门指南
开发&工具
应用方案
客户支持
 
学习e条龙
一、单片机简介 二、指令系统 三、IO端口 四、中断系统
五、定时/计数器 六、串行接口 七、模拟外设 八、其它硬件
九、开发工具 十、应用实例 十一、附录  

定时 / 计数器原理及应用

内容索引
5.1 SPMC65系列单片机的定时/计数器 5.4 捕获器(Capture)
5.2 Timer控制寄存器  5.5 比较模式(Compare)
5.3 定时/计数器  5.6 PWM模式 120

5.1  SPMC65 系列单片机的 定时 / 计数器

  SPMC65 系列单片机共有 6 个定时 / 计数器( Timer ),每个 Timer 都分别具备 CCP(Capture/Compare/PWM) 功能,即捕获、比较和 PWM 输出功能。 Timer 有 4 种工作模式: 8 位 /16 位定时 / 计数器模式、捕获模式(捕获器)、比较模式和 PWM 模式。另外,除了 PWM 模式外,其它三种模式都可以以 8 位或 16 位的方式工作。所有功能通过相应控制寄存器进行设置,见 表 5.1 简介:

表 5 . 1 SPMC65 系列单片机定时 / 计数器功能简介

定时 / 计数器模式

捕获器

比较模式

PWM 模式

8 位

16 位

8 位

16 位

8 位

16 位

Timer 0

脉宽 / 周期

脉宽

8 位

Timer 1

脉宽 / 周期

脉宽

12 位

Timer 2

脉宽 / 周期

脉宽

8 位

Timer 3

脉宽 / 周期

脉宽

12 位

Timer 4

脉宽 / 周期

脉宽

8 位

Timer 5

脉宽 / 周期

脉宽 / 周期

16 位

  SPMC65 系列单片机最多共有 6 个 Timer ,而这 6 个 Timer 分为三种类型,其主要是在功能、结构上有一定的区别,具体请参考下面的描述:

 1. 类型 I : (Timer 0 、 Timer 2 、 Timer 4)
 
   ■ 8 位或 16 位定时 / 计数器
  
   ■ 8 位或 16 位捕获模式 (8 位脉宽 / 周期测量, 16 位脉宽测量 )
  
   ■ 8 位或 16 位比较模式
  
   ■ 8 位 PWM 模式
 
  2. 类型 II : (Timer 1 、 Timer 3)
 
   ■ 8 位或 16 位定时 / 计数器
  
   ■ 8 位或 16 位捕获模式 (8 位脉宽 / 周期测量, 16 位脉宽测量 )
  
   ■ 8 位或 16 位比较模式
  
   ■ 12 位 PWM 模式
 
  3. 类型 III : (Timer5)
 
   ■ 8 位或 16 位定时 / 计数器
  
   ■ 8 位或 16 位捕获模式 (8 位 /16 位脉宽 / 周期测量 )
  
   ■ 8 位或 16 位比较模式
  
   ■ 16 位 PWM 模式

  这些功能通过控制寄存器 P_TMRx_Ctrl0 (x=0~5) 设置,本章会从三种定时 / 计数器各选出一个定时 / 计数器进行详细介绍,如会详细介绍类型 I 的 Timer 0 、类型 II 的 Timer 1 以及类型 III 的 Timer 5 。而其它 Timer 的应用、功能设置等请参考同类型 Timer 的介绍。

  而 SPMC65 系列单片机中,具体型号芯片的 Timer ,除了在数量上会有所删减外,具体的 Timer 的工作模式还会有一定的删减,请参考具体型号芯片的数据手册;但其在功能设置上与本章所述描的是一样的。

5.2 Timer控制寄存器

5.2.1 Timer 相关寄存器简述

  SPMC65 系列单片机 Timer 的功能很强大,而它的使用、设置却很简单,下面分别介绍 SPMC65 系列单片机有关 Timer 的寄存器分类:

  基本功能寄存器:

■ Timer 控制寄存器 0 : P_TMRy_z_Ctrl0 ,主要用于设置 Timer 的工作模式;( y=0,2,4;z=1,3,5 )

■ Timer 控制寄存器 1 : P_TMRy_z_Ctrl1 ,主要用于设置 Timer 的计数频率;( y=0,2,4;z=1,3,5 )

■ Timer x 计数值寄存器( R ): P_TMRx_Count 、 P_TMRx_CountHi ,分高低字节;( x=0~5 )

■ Timer x 重载值寄存器( W ): P_TMRx_Preload 、 P_TMRx_PreloadHi ,分高低字节;( x=0~5 )

  CCP 功能相关寄存器:

■ Timer x 脉宽捕获值寄存器: P_TMRx_Cap 、 P_TMRx_CapHi ,分高低字节;( x=0~5 )

■ Timer x 周期捕获值寄存器: P_TMRx_CapCycle8 ① ;( x=0~4 )

■ 捕获控制寄存器: P_CAP_Ctrl ;

■ Timer x 比较值寄存器: P_TMRx_Comp 、 P_TMRx_CompHi ,分高低字节;( x=0~5 )

■ Timer xPWM 周期寄存器:分 8 位、 12 位以及 16 位模式(具体请参考后面的介绍);( x=0~5 )

■ Timer xPWM 占空比寄存器:分 8 位、 12 位以及 16 位模式(具体请参考后面的介绍);( x=0~5 )

注 ① : Timer 5 工作在 16 位捕获器模式下时,周期捕获值寄存器分高低字节寄存器。

  本小节将详细介绍 SPMC65 系列单片机的 Timer 基本功能寄存器(即基本的定时 / 计数功能相关的寄存器),而与 CCP 功能相关的寄存器介绍将在后面的小节中介绍。

5.2.2 Timer 控制寄存器

  Timer 控制寄存器 0 P_TMRy_z_Ctrl0 ( y=0,2,4;z=1,3,5 )

  写 Timer 控制寄存器 0 ( P_TMRy_z_Ctrl0 )可以完成对 Timer 的工作模式设置,要启动 Timer (包括 Timer 的各种工作模式)时要设置好相对的模式选择位即可,而相应的模式选择位写入“ 000 ”时,则 Timer 停止。 P_TMRy_z_Ctrl0 默认初始值为 #00h ,其各个位的功能请参考下面介绍:

表 5 . 2 Timer0-1 控制寄存器 0 P_TMR0_1_Ctrl0 ( $11 , R/W )

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

-

T1FC2

T1FC1

T1FC0

-

T0FC2

T0FC1

T0FC0

-

R/W

R/W

R/W

-

R/W

R/W

R/W

表 5 . 3 Timer 2-3 控制寄存器 0 P_TMR2_3_Ctrl0 ( $18 , R/W )

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

-

T3FC2

T3FC1

T3FC0

-

T2FC2

T2FC1

T2FC0

-

R/W

R/W

R/W

-

R/W

R/W

R/W

表 5 . 4 Timer 4-5 控制寄存器 0 P_TMR4_5_Ctrl0 ( $1F , R/W )

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

-

T5FC2

T5FC1

T5FC0

-

T4FC2

T4FC1

T4FC0

-

R/W

R/W

R/W

-

R/W

R/W

R/W

  TxFC[2 : 0] : Timer x 模式设置位( x=0~5 )

  Timer 控制寄存器 0 各个位设置时,对应的工作模式请参考下表:

表 5 . 5 Timer 模式设置对照表

TxFC2

TxFC1

TxFC0

Timer0/2/4 模式

Timer1/3 模式

Timer5 模式

1

1

1

8 位 PWM

12 位 PWM

16 位 PWM

1

1

0

16 位脉宽捕获

16 位脉宽捕获

16 位脉宽 / 周期捕获

1

0

1

16 位比较模式

16 位比较模式

16 位比较模式

1

0

0

16 位定时 / 计数器

16 位定时 / 计数器

16 位定时 / 计数器

0

1

1

8 位脉宽 / 周期捕获

8 位脉宽 / 周期捕获

8 位脉宽 / 周期捕获

0

1

0

8 位比较模式

8 位比较模式

8 位比较模式

0

0

1

8 位定时 / 计数器

8 位定时 / 计数器

8 位定时 / 计数器

0

0

0

停止

停止

停止

  Timer 控制寄存器 1 P_TMRy_z_Ctrl1 ( y=0,2,4;z=1,3,5 )

  写 Timer 控制寄存器 1 ( P_TMRy_z_Ctrl1 )可以设置对应 Timer 的预分频数,即可完成对 Timer 计数频率的设置; P_TMRy_z_Ctrl1 默认初始值为 #00h ,其各个位的具体功能请参考下面介绍:

表 5 . 6 Timer 0-1 控制寄存器 1 P_TMR0_1_Ctrl1 ( $12 , R/W )

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

-

T1PSS2

T1PSS1

T1PSS0

-

T0PSS2

T0PSS1

T0PSS0

-

R/W

R/W

R/W

-

R/W

R/W

R/W

表 5 . 7 Timer 2-3 控制寄存器 1 P_TMR2_3_Ctrl1 ( $19 , R/W )

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

-

T3PSS2

T3PSS1

T3PSS0

-

T2PSS2

T2PSS1

T2PSS0

-

R/W

R/W

R/W

-

R/W

R/W

R/W

表 5 . 8 Timer 4-5 控制寄存器 1 P_TMR4_5_Ctrl1 ( $20 , R/W )

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

-

T5PSS2

T5PSS1

T5PSS0

-

T4PSS2

T4PSS1

T4PSS0

-

R/W

R/W

R/W

-

R/W

R/W

R/W

  TxPSS[2 : 0] : Timer x 预分频设置位(计数频率设置)( x=0~5 )

  111 = 外部事件

  110 = F SYS ÷ 512

  101 = F SYS ÷ 128

  100 = F SYS ÷ 32

  011 = F SYS ÷ 8

  010 = F SYS ÷ 4

  001 = F SYS ÷ 2

  000 = F SYS

  F SYS :系统时钟频率

  Timer x 计数值低字节寄存器 P_TMRx_Count ( x=0~5 )

  Timer x 重载值低字节寄存器 P_TMRx_Preload ( x=0~5 )

  SPMC65 系列单片机中, Timer 的计数值寄存器与重载值寄存器是映射到同一个地址的,而这两组寄存器分别是只读、只写的,即读该寄存器时为读取当前计数值,写该寄存器时为写入数据到重载值寄存器。计数值 / 重载值寄存器的低字节寄存器默认初始值为 #00h 。

表 5 . 9 Timer x 计数值 / 重载值低字节寄存器

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

W

TxPL7

TxPL6

TxPL5

TxPL4

TxPL3

TxPL2

TxPL1

TxPL0

R

TxCN7

TxCN6

TxCN5

TxCN4

TxCN3

TxCN2

TxCN1

TxCN0

  Bit [7:0] 写: Timer x 重载值的 低字节

  Bit [7:0] 读: Timer x 计数值的 低字节

  Timer x 计数值高字节寄存器 P_TMRx_CountHi ( x=0~5 )

  Timer x 重载值高字节寄存器 (P_TMRx_PreloadHi ( x=0~5 )

  与其相对的低字节寄存器一样,这两个寄存器实际上是映射到了同一个地址上,分别是只读、只写的寄存器,读取时为读取当前 Timer 的计数值,写入时为写入数据到重载值寄存器。计数值 / 重载值高字节寄存器默认初始值为 #00h 。

表 5 . 10 Timer 0 计数值 / 重载值高字节寄存器

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

W

TxPL15

TxPL14

TxPL13

TxPL12

TxPL11

TxPL10

T0xPL9

TxPL8

R

TxCN15

TxCN14

TxCN13

TxCN12

TxCN11

TxCN10

TxCN9

TxCN8

  Bit [7:0] 写: Timer x 重载值的高字节

  Bit [7:0] 读: Timer x 计数值的高字节

  注: 写入数据顺序要按照从高字节到低字节的顺序写。例如:要设置 16 位定时器模式先设置位于高字节的 P_TMR0_PreloadHi 然后设置位于低字节的 P_TMR0_Preload 。而读取数据的顺序正好相后,要按照选读取低字节寄存器,再读取高字节寄存器的顺序。

5.3 定时 / 计数器

5.3.1  定时 / 计数器的结构

  SPMC65 系列单片机的 6 个 Timer 都可工作在 8 位 /16 位可重载的定时 / 计数器模式下。在作定时 / 计数器时,需要设置几个寄存器,如下:

  1. 定时 / 计数器功能选择(设置 Timer 控制寄存器 0 );

  2. 8 位预分频寄存器(设置 Timer 控制寄存器 1 );

  3. 8 位 /16 位重载值寄存器。

  定时 / 计数器的计数频率共有 8 种选择 , 可以通过设置 Timer 控制寄存器 1 (设置对应定时 / 计数器的预分频设置位)来选择。其中 7 种时钟频率由系统时钟的 1 ~ 512 分频得到,因而频率输入范围非常广。而在定时 / 计数器的控制寄存器设置中,可以设置定时器的计数频率信号来自于外部事件,即可对外部信号进行计数。而各定时 / 计数器对应的外部事件输入端口如 表 5.11 所示:

表 5 . 11 定时 / 计数器外部事件输入端口

定时 / 计数器

外部事件端口

定时 / 计数器

外部事件端口

定时 / 计数器 0

与 PB0 复用

定时 / 计数器 3

与 PB5 复用

定时 / 计数器 1

与 PB1 复用

定时 / 计数器 4

与 PD4 复用

定时 / 计数器 2

与 PB4 复用

定时 / 计数器 5

与 PD5 复用

  8 位 /16 位重载值寄存器的作用是在定时 / 计数器开始工作或者溢出后重新赋初值。

  

  定时器的 8 位 /16 位计数值寄存器每收到一个外部或内部时钟输入后加一。以一个 8 位定时器为例,当其计数到 255 时,这时再来一个时钟信号,计数器便会溢出。此时,如果定时 / 计数器的溢出中断已经使能了,便会产生溢出中断。同时,在计数器从 255 即将变为 0 时,重载值寄存器中的值会被取出,载入计数器,重新从载入的初值开始计数。 图 5.1 为定时 / 计数器结构图。

图 5 . 1 定时 / 计数器结构框图

5.3.2  8 位定时 / 计数器

  SPMC65 系列单片机的 Timer 都可以在 8 位定时 / 计数器模式下工作,设置寄存器 P_TMRy_z_Ctrl0 (y=0, 2, 4; z=1, 3, 5) 可以使相对应的 Timer 工作在 8 位定时 / 计数器模式下。

  下面以一个 8 位定时 / 计数器—— Timer0 为例,分析定时 / 计数器工作在 8 位模式下的机制。

  8 位定时 / 计数器定时长度的计算如下:

8 位定时 / 计数器

  DATA = P_TMRx_Preload

  T_TMRx = Timer x 时钟分频后的周期 , x = 0~5

  中断周期 = {$100 - DATA} * T_TMRx

  以 Timer 0 为例, 图 5.2 为 8 位定时 / 计数器的结构图:

图 5 . 2 8 位定时 / 计数器结构

而 图 5.3 中所示的是定时 / 计数器溢出和中断发生的信号时序图。

图 5 . 3 溢出和中断发生信号时序图

  

  如果 P_TMR0_1_Ctrl0[2:0]=001 且 PB0 设置为输入(即设置了定时 / 计数器的计数频率信号为外部事件),那么 PB0 就可以作为定时 / 计数器 0 的外部时钟输入端,进行外部脉冲计数。定时 / 计数器 0 的低字节寄存器 P_TMR0_Count ($13) 可以自动装入初值并负责计数( 8 位定时 / 计数器模式下时,其相关寄存器低字节的有效),在其计数的过程中,可以从中读取当前的计数值。一旦计数溢出,如果该溢出中断使能,则会产生溢出中断,同时,计数寄存器会自动的被载入初值(重载值)。如 图 5.4 所示,为 8 位计数器计数情况和中断发生的关系。

图 5.4 8 位计数器计数情况和中断发生的关系

【例 5 - 1 】: 将 Timer 0 设置成 8 位定时 / 计数器模式

  lda   # 00000001B     ; 将 Timer0 设置 8 位定时 / 计数器模式,并启动 Timer0
    
  sta   P_TMR0_1_Ctrl0
    
  lda   # 00000101B     ; 设置 Timer0 时钟频率 Fsys/128
    
  sta   P_TMR0_1_Ctrl1
    
  lda   #156        ; 设置 Timer0 重载计数值 = 256-156= 100
    
  sta   P_TMR0_Preload   ; Fsys(8MHz)/128/100= 625Hz

5.3.3  16 位定时 / 计数器

  一般 8 位的 CPU ,总线宽度为 8 位,通常无法直接访问 16 位的数据。为了克服这样的局限性问题,在 SPMC65 系列单片机中设计了一个数据寄存器 Timer x MSB ( x = 0~5 ),用于 16 位数据高 8 位的读写操作,如 图 5.5 所示,它有专门的读 / 写缓冲器。在读取 16 位数据时,用户需要先读出低字节,与此同时,高字节被锁存在缓冲器里,低字节读取结束,然后再读取高字节,这时相当于读取缓冲器中保存的定时 / 计数器高字节数据。相反的,在写 16 位数据时,用户需要先写入高字节并被缓冲器自动保存,然后再写入低字节,直到 16 位数据全部写入,缓冲器中的高字节和低字节将会同时载入定时 / 计数器中去。

图 5 . 5 16 位定时 / 计数器的寄存器读写操作示意图

  数据寄存器和中断周期之间的关系如下:

16 位定时 / 计数器

  DATA={ P_TMRx_PreloadHi, P_TMRx_Preload }

  T_TMRx = Timer x 时钟分频后的周期 , x = 0~5

  中断周期 = {$10000 - DATA} * T_TMRx

  以 Timer 0 工作在 16 位定时 / 计数器模式下为例, 图 5.6 为 16 位定时 / 计数器的结构图:

  而 图 5.7 中所示的是定时 / 计数器溢出和中断发生的信号时序图:

图 5 . 6 16 位定时 / 计数器结构

图 5 . 7 定时 / 计数器溢出和中断发生的信号时序图

  如果 P_TMR0_1_Ctrl0 [2:0]=100 且 PB0 设置为输入,那么 PB0 就可以作为定时 / 计数器 0 的时钟输入端,进行外部脉冲计数。定时 / 计数器 0 有两个计数寄存器:高字节寄存器 P_TMR0_CountHi ($14) 和低字节寄存器 P_TMR0_Count ($13) ,这两个寄存器可以自动的载入初值进行计数,在计数的过程中随时可以读取当前的计数值。当该 16 位定时 / 计数器 0 溢出时,如果溢出中断使能,则会产生溢出中断,同时定时 / 计数器 0 会自动重载初值继续计数。如 图 5.8 所示,为 16 位计数器计数情况和中断发生的关系示意图。

图 5 . 8 16 位计数器工作状态和中断之间的关系示意图

【例 5-2 】: 将 Timer 0 设置为 16 位定时 / 计数器工作方式:

  lda   #00000100B      ; 将 Timer0 设置为 16 位定时 / 计数器模式
    
  sta   P_TMR0_1_Ctrl0
    
  lda   #00000101B      ; 设定 Timer0 时钟频率为 Fsys/128
    
  sta   P_TMR0_1_Ctrl1
    
  lda   #254         ; 首先 设定 Timer0 计数重载值高字节为 (256-254)x 256= 512
    
  sta   P_TMR0_PreloadHi
    
  lda   #143         ; 然后 设定 Timer0 计数重载值低字节为 256-143= 113 。
    
  sta   P_TMR0_Preload    ; 设定 Fsys(8Mhz)/128/(512+113)= 100Hz(10ms)

5.3.4 定时 / 计数器中断

定时 / 计数器有以下五种中断源:

•  定时 / 计数器 0 溢出中断

•  定时 / 计数器 1 溢出中断

•  定时 / 计数器 2 溢出中断

•  定时 / 计数器 3 溢出中断

•  定时 / 计数器 4 溢出中断

•  定时 / 计数器 5 溢出中断

下面是设置定时 / 计数器溢出中断的几个步骤:

•  执行指令 “SEI ” 关闭总的中断开关;

•  决定采用 8 位还是 16 位的定时 / 计数方式并选择一个合适的定时 / 计数器;

•  设置所选的定时 / 计数器的相关寄存器;

•  在 寄存器 P_INT_Ctrl1( $0F) 中使能该定时器中断;

•  执行指令“ CLI ”打开总的中断开关;

•  设置完毕,等待中断产生。

【例 5-3 】: 将 Timer 0 设置为 8 位定时 / 计数器工作方式并产生 1ms 的溢出中断。

 lda   #00000001B     ; 将 Timer0 设置为 8 位工作方式
    
  sta   P_TMR0_1_Ctrl0
    
  lda   #00000100B     ; 设定 Timer0 时钟频率为 Fsys/32
    
  sta   P_TMR0_1_Ctrl1
    
  lda   #6         ; 设定 Timer0 计数重载值为 256-6= 250
    
  sta   P_TMR0_Preload   ; 设定 Fsys(8MHz)/32/250= 1KHz(1ms)
    
  lda   #$FF        ; 清除所有的中断标志位
    
  sta   P_INT_Flag1
    
  set   P_INT_Ctrl1,0   ; 使能 Timer0 溢出中断
    
  cli            ; 打开总的中断开关

【例 5-4 】: 将 Timer 1 设置为 16 位定时 / 计数器工作方式并产生 10ms 的周期溢出中断

  lda   #01000000B     ; 将 Timer1 设置为 16 位工作方式
    
  sta   P_TMR0_1_Ctrl0
    
  lda   #01010000B     ; 设定 Timer1 时钟频率为 Fsys/128
    
  sta   P_TMR0_1_Ctrl1
    
  lda   #254        ; 首先 设定 Timer1 计数重载值高字节为 (256-254)x 256= 512
    
  sta   P_TMR1_PreloadHi
    
  lda   #143        ; 然后 设定 Timer1 计数重载值低字节为 256-143= 113
    
  sta   P_TMR1_Preload   ; 设定 Fsys(8Mhz)/128/(512+113)= 100Hz(10ms)
    
  lda   #$FF        ; 清除所有的中断标志位
    
  sta   P_INT_Flag1
    
  set   P_INT_Ctrl1,1   ; 使能 Timer1 溢出中断
    
  cli            ; 打开总的中断开关


5.4  捕获器 ( Capture )

5.4.1  SPMC65系列单片机的捕获器

  SPMC65 系列单片机共有 6 个 Timer ,都具有 8 位 /16 位捕获功能,支持两种触发模式:上升沿触发和下降沿触发。在 8 位捕获模式下,可以进行脉宽和周期的测量。在 16 位捕获模式下,只能进行脉宽测量( Timer 5 可进行 16 位的脉宽 / 周期测量)。所有功能可以通过相应控制寄存器进行设置,见下表简介:

表 5 . 12 SPMC65 系列单片机捕获功能简表

捕获器

捕获输入管脚

8 位

16 位

Timer 0

脉宽 / 周期

脉宽

与 PB0 复用

Timer 1

脉宽 / 周期

脉宽

与 PB1 复用

Timer 2

脉宽 / 周期

脉宽

与 PB4 复用

Timer 3

脉宽 / 周期

脉宽

与 PB5 复用

Timer 4

脉宽 / 周期

脉宽

与 PD4 复用

Timer 5

脉宽 / 周期

脉宽 / 周期

与 PD5 复用

  

  当 Timer 工作于 8 位或 16 位的捕获模式下,捕获输入管脚(例如定时 / 计数器 0 的 PB0 )必须设置成输入状态,才能进行事件捕获。而为了保证捕获值的正确,需要选择合适的计数频率。当需要得到脉宽值或周期值时,捕获器的触发沿极性和捕获中断触发极性也必须设置正确。除了 Timer 要设置的控制寄存器,以及相关的捕获值寄存器之外,捕获器操作相关的寄存器还有如下: P_CAP_Ctrl ($58) 、 P_IRQ_Opt0 ($33) 和 P_IRQ_Opt1 ($34) 。如 图 5.9 所示为捕获器原理框图。

图 5 . 9 捕获器原理框图

5.4.2  控制寄存器

  SPMC65 系列单片机的 6 个 Timer 可通过设置 Timer 控制寄存器( P_TMRy_z_Ctrl0:y=0,2,4;z=1,3,5 )使其工作在捕获器模式下;设置 Timer 控制寄存器 1 ( P_TMRy_z_Ctrl1:y=0,2,4;z=1,3,5 )可选择计数频率。控制寄存器 0 和 1 的各个位功能,以及设置方法请参考前面小节中的介绍。当启动 Timer 的捕获模式时,需要设置对应的工作模式选择位即可,而相应工作模式选择位写入 000B 时,即使其停止工作。   

  而每一个捕获器都有对应的脉宽捕获值低字节寄存器( P_TMRx_Cap:x=0~5 ),高字节寄存器( P_TMRx_CapHi:x=0~5 ),以及周期捕获值寄存器( P_TMRx_CapCycle8:x=0~5 );而定时 / 计数器 5 有 16 位脉宽 / 周期捕获器的工作模式,所以定时 / 计数器 5 还有两个寄存器分别对应 16 位周期捕获值的寄存器:定时 / 计数器 5 周期捕获值的 低字节( P_TMR5_CapCycleLo ),以及定时 / 计数器 5 周期捕获值的 高字节( P_TMR5_CapCycleHi )。

  捕获器 x 脉宽捕获值的低字节 P_TMRx_Cap ( x=0~5 )

  捕获器 x 脉宽捕获值低字节寄存器( P_TMRx_Cap )是与定时 / 计数器 x 的重载值低字节寄存器映射到了同一地址上;不过,当定时 / 计数器工作在捕获器的模式下时,写脉宽捕获值的高、低字节寄存器是没有意义的。与前面所述一样,当 Timer 工作在 8 位捕获器模式下时,其相关寄存器中,低字节寄存器有效,即捕获器脉宽捕获值寄存器组中,只有低字节的寄存器 P_TMRx_Cap 有效;其它有高低字节寄存器之分的 Timer 相关寄存器也一样。

  寄存器 P_TMRx_Cap 和 P_TMRx_CapHi 的默认初始值都为 #00h :

表 5 . 13 捕获器 x 脉宽捕获值的低字节寄存器 P_TMRx_Cap

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

W

TxPL7

TxPL6

TxPL5

TxPL4

TxPL3

TxPL2

TxPL1

TxPL0

R

TxCW7

TxCW6

TxCW5

TxCW4

TxCW3

TxCW2

TxCW1

TxCW0

  Bit [7:0] 写: TxPL [7:0] 定时 / 计数器 x 重载值的低字节 TxPL [7:0] (W)

  Bit [7:0] 读: TxCW [7:0] 捕获器 x 脉宽捕获值的低字节 TxCW [7:0] (R)

  捕获器 x 脉宽捕获值的高字节寄存器 P_TMRx_CapHi ( x=0~5 )

表 5 . 14 捕获器 x 脉宽捕获值高字节寄存器 P_TMRx_CapHi

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

W

TxPL15

TxPL14

TxPL13

TxPL12

TxPL11

TxPL10

TxPL9

TxPL8

R

TxCW15

TxCW14

TxCW13

TxCW12

TxCW11

TxCW10

TxCW9

TxCW8

  Bit [7:0] 写: TxPL [15:8] 定时 / 计数器 x 重载值的高字节 TxPL [15:8] (W)

  Bit [7:0] 读: TxCW [15:8] 捕获器 x 脉宽捕获值的高字节 TxCW [15:8] (R)

  捕获器 x 周期捕获值寄存器 P_TMRx_CapCycle8 ( x=0~5 )

  捕获器 x 周期捕获值寄存器( P_TMRx_CapCycle8 )映射到了对应的脉宽捕获值高字节寄存器( P_TMRx_CapHi )。当 Timer 工作在 8 位脉宽 / 周期捕获器模式下时,读对应的 P_TMRx_CapCycle8 可获取捕获的 8 位周期捕获值,写该寄存器没有意义。该寄存器默认初始值为 #00h 。

表 5 . 15 捕获器 x 周期寄存器 P_TMRx_CapCycle8

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

W

TxPL15

TxPL14

TxPL13

TxPL12

TxPL11

TxPL10

TxPL9

TxPL8

R

TxCC7

TxCC6

TxCC5

TxCC4

TxCC3

TxCC2

TxCC1

TxCC0

  Bit [7:0] 写: TxPL [15:8] 定时 / 计数器 x 重载值 TxPL [15:8] (W)

  Bit [7:0] 读: TxCC [7:0] 捕获器 x 周期捕获值 TxCC [7:0] (R)

  而 Timer5 可以工作在 16 位的脉宽 / 周期捕获器模式下,所以 Timer5 还多出了两个寄存器用于存放捕获的 16 位周期捕获值。这两个寄存器默认初始值都为 #00h 。

  定时 / 计数器 5 周期捕获值的低字节寄存器 P_TMR5_CapCycleLo ( $25 , R )

  定时 / >计数器 5 周期捕获值的高字节寄存器 P_TMR5_CapCycleHi ( $5F , R )

  捕获控制寄存器 P_CAP_Ctrl ( $58 , R/W )

  写捕获控制寄存器( P_CAP_Ctrl )可以设置对应的定时 / 计数器工作在捕获器模式下时的一些特性,如捕获数据保持选择、中断触发极性选择等。 P_CAP_Ctrl 在复位后默认值为 #00h ,该寄存器各个位的功能请参考 表 5.16 :

表 5 . 16 捕获控制寄存器 P_CAP_Ctrl ( $58 , R/W )

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

CAPOPT

CAPIP4

CAPIP3

CAP1P2

CAPIP1

CAP1P0

CAP1ES

CAP0ES

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

  Bit 7 CAPOPT:捕获数据保持选择位
           1=保持原来的捕获数据,直到对捕获数据寄存器进行读操作
           0=若接收到新数据,立即更新捕获数据
   Bit 6 CAPIP4:捕获器4中断触发极性选择位
           1=与捕获器4触发沿极性相同
           0=与捕获器4触发沿极性相反
   Bit 5 CAPIP3:捕获器3中断触发极性选择位
           1=与捕获器3触发沿极性相同
           0=与捕获器3触发沿极性相反
   Bit 4 CAPIP2:捕获器2中断触发极性选择位
           1=与捕获器2触发沿极性相同
           0=与捕获器2触发沿极性相反
   Bit 3 CAPIP1:捕获器1中断触发极性选择位
           1=与捕获器1触发沿极性相同
           0=与捕获器1触发沿极性相反
   Bit 2 CAPIP0:捕获器0中断触发极性选择位
           1=与捕获器0触发沿极性相同
           0=与捕获器0触发沿极性相反
   Bit 1 CAP1ES:捕获器1的触发沿极性选择位
           1=下降沿触发并清除计数器
           0=上升沿触发并清除计数器
   Bit 0 CAP0ES:捕获器0的触发沿极性选择位
           1=下降沿触发并清除计数器
           0=上升沿触发并清除计数器
   注: Timer 2~5 作为捕获器时,其触发沿极性选择位,以及 Timer5 作为捕获器时的中断触发极性选择位的设置,在 IRQ 和 Capture 设置寄存器 0 ( P_IRQ_Opt0, $33 )、 IRQ和 Capture 设置寄存器 1 ( P_IRQ_Opt1, $34 )中进行设置。具体可参考中断部分的介绍。

5.4.3   8位捕获器工作模式

  当 Timer 处于 8 位捕获模式下时,建议将中断触发与捕获器的触发沿极性设置成相同的极性。比如,如果捕获器的触发沿设置为下降沿( CAPxES=1 ),中断触发也是下降沿( CAPIPx = 1 ),并且 CAPOPT=0 (收到新数据后更新捕获数据),这样,一旦捕获器输入管脚上有下降沿输入时,计数器马上清除。在接下来的一个上升沿来临时,计数器的值即脉宽值被立即送入寄存器 P_TMRx_Cap 中,然后接着继续计数。在下一个下降沿到来时, 计数器的值即周期值又被送入寄存器 P_TMRx_CapCycle8 中,同时中断标志 CAPxIF 置位,然后计数器清零又重新开始计数,进行下一个捕获操作。如果 CAPOPT=1 ,并且没有对存放脉宽值或周期值的寄存器进行读操作,那么即使有新数据,这两个寄存器的值也不会被更新,除非进行读操作。

  另外,如果捕获脉宽大于计数器所能表示的最大值时,可以用定时 / 计数器的溢出中断来辅助计数。例如:如果捕获的脉宽信号大于定时 / 计数器最大计数值 (FFh) ,那么,当定时 / 计数器计数到 FFH 时,发生溢出中断,中断次数加 1 ,同时,定时 / 计数器继续计数。当计数完毕,可以根据中断次数和当前计数值计算出正确的捕获值。

  8 位捕获模式和 16 位捕获模式有所不同。在 16 位捕获模式下(捕获器 5 除外),只能进行脉宽测量,因为捕获器必须占用两个字节的 8 位寄存器来保存 16 位的脉宽捕获值。但是在 8 位捕获模式下,既可以进行脉宽测量也可以进行周期测量。 8 位捕获器操作时序请参考 图 5.10 :

图 5 . 10 8 位捕获器操作时序

  捕获器模块为用户提供了一个输入信号保持功能。将 P_CAP_Ctrl 的捕获数据保持选择位设置为 1 就可以进行一次性输入信号捕获,捕获器的捕获值(脉宽 / 周期)寄存器一直会保持这个捕获信号的值,直到将该信号读出。然后再进行第二次捕获、保持、读出,如此循环。可以利用该功能进行脉宽和周期的测量。 8 位脉宽捕获和保持的操作时序请参考 图 5.11 。

图 5 . 11 8 位脉宽捕获和保持操作

  8 位脉宽捕获和周期捕获的计算公式如下:

 If
 
    T_TMRx = 定时 / 计数器 x 分频后的时钟周期 , x = 0 ~ 5
 
  then
 
    8 位 捕获器
   
   捕获脉宽值 = [P_TMRx_Cap + 1] * T_TMRx
  
   捕获周期值 = [P_TMRx_CapHi + 1] * T_TMRx
  
   注:捕获的脉宽 / 周期值允许有一个时钟周期的误差。

  【例 6-5 】: 将 Timer 0 设置为 8 位捕获模式:

 lda   #00000000B
    
  sta   P_IOB_Data
    
  sta   P_IOB_Attrib
    
  lda   #11111110B     ; 将 PB0 设置为输入,作为捕获器 0 的输入管脚
    
  sta   P_IOB_Dir
    
  lda   #00000011B     ; 将 Timer 0 设置为 8 位捕获模式
    
  sta   P_TMR0_1_Ctrl0
    
  lda   #00000110B     ; Timer 0 分频率 Fsys/512 (15.6KHz~61Hz)
    
  sta   P_TMR0_1_Ctrl1
    
  lda   #00000101B     ; 设置为下降沿采数据,捕获器 0 中断为下降沿触发
    
  sta   P_CAP_Ctrl

5.4.4  16 位捕获器工作模式

  当 Timer 处于 16 位捕获模式下时,建议将中断触发极性与捕获器计数清除极性设置成相反。例如:如果捕获器触发沿设置为下降沿( CAPxES=1 ),那么捕获中断就设置成上升沿触发( CAPIPx = 0 ),并且 CAPOPT=0 (收到新数据后更新捕获数据),这样,一旦捕获器输入管脚上有下降沿输入时,计数器马上清除。在接下来的一个上升沿来临时,计数器的值即脉宽值被立即送入寄存器 P_TMRx_Cap 和 P_TMRx_CapHi 中,并且产生捕获中断,然后接着继续计数。在下一个下降沿到来时,计数器清零又重新开始计数,进行下一个捕获操作。如果 CAPOPT=1 ,并且没有对存放捕获值的寄存器进行读操作,那么即使有新数据,寄存器的值也不会被更新,直到对其进行读操作后才会再次更新。

  另外,如果捕获脉宽大于定时 / 计数器所能表示的最大值时,可以用定时 / 计数器的溢出中断来辅助计数。例如:如果捕获的脉宽信号大于定时 / 计数器 1 最大计数值( #FFFFh ),那么,当定时 / 计数器计数到 #FFFFh 时,发生溢出中断,中断次数加 1 ,同时,定时 / 计数器继续计数。当计数完毕,可以根据中断次数和当前计数值计算出正确的脉宽值。

  由于 16 位捕获器只能进行脉宽捕获(捕获 5 除外),所以,当需要测量周期时,可由软件处理来实现。即:改变捕获中断的触发极性。在下一次捕获中断到来的时候捕获到信号的周期值。如 图 5.12 所示为 16 位捕获器的操作原理。

图 5.12 16 位捕获器的操作原理

  16 位脉宽捕获计算方法如下:

 If

  T_TMRx = 定时 / 计数器 x 分频后的时钟周期 , x = 0 ~ 5

 then

  16 位 捕获器

 捕获脉宽值 =[{ P_TMRx_CapHi , P_TMRx_Cap }+1] * T_TMRx

 注意:捕获的脉宽 / 周期值允许有一个时钟周期的误差。

  【例 6-6 】 :将 Timer 1 设置为 16 位捕获模式

  lda   #00000000B
    
  sta   P_IOB_Data
    
  sta   P_IOB_Attrib
    
  lda   #11111101B     ; 将 PB1 设置为输入,作为捕获器 1 的输入管脚
    
  sta   P_IOB_Dir
    
  lda   #01100000B     ; 将 Timer 1 设置为 16 位捕获模式
    
  sta   P_TMR0_1_Ctrl0
    
  lda   #01100000B     ; Timer 1 分频率 Fsys/128 (62.5KHz~1Hz)
    
  sta   P_TMR0_1_Ctrl1
    
  lda   #00001010B     ; 设置为下降沿采数据,捕获 1 中断为下降沿触发
    
  sta   P_CAP_Ctrl

5.4.5  捕获中断

  捕获器相关中断如下:

  •  Timer 0 捕获中断

  •  Timer 1 捕获中断

  •  Timer 2 捕获中断

  •  Timer 3 捕获中断

  •  Timer 4 捕获中断

  •  Timer 5 捕获中断

  下面是设置 Timer 捕获中断的几个步骤:

  1. 执行指令 “SEI ” 关闭总的中断开关;

  2. 决定采用 8 位还是 16 位的捕获方式并选择一个合适的 Timer x (x=0~5) ;

  3. 设置所选的 Timer 的相关寄存器;

  4. 在 寄存器 P_INT_Ctrl0 ( $0D )、 P_INT_Ctrl1($0F) 中使能该 Timer 捕获中断;

  5. 执行指令 “ CLI ”打开总的中断开关 ;

  6. 设置完毕,等待捕获中断产生。

  【例 6-7 】: 将 Timer 1 设置为 16 位捕获模式并查询捕获中断。

  lda  #00000000B
   
  sta  P_IOB_Data
   
  sta  P_IOB_Attrib
   
  lda  #11111101B      ; 将 PB1 设置为输入,作为捕获器 1 的输入管脚
   
  sta  P_IOB_Dir
   
  lda  #01100000B      ; 将 Timer 1 设置为 16 位捕获模式
   
  sta  P_TMR0_1_Ctrl0
   
  lda  #01100000B      ; Timer 1 分频率 Fsys/128 (62.5KHz~1Hz)
   
  sta  P_TMR0_1_Ctrl1
   
  lda  #0001010B      ; 设置为下降沿采数据,捕获 1 中断为下降沿触发
   
  sta  P_CAP_Ctrl     ;
   
  L_Te stT1L61:
   
  lda  P_INT_Flag1
   
  and  # 10000000B     ; 捕获 1 中断 ? ( 捕获数据就绪 )
   
  beq  L_TestT1L61     ; 否
   
  set  P_INT_Flag1,7    ; 清除捕获 1 中断标志
   
  lda  P_TMR1_Cap     ; 将脉宽低字节值送入累加器 A
   
  ldx  P_TMR1_CapHi    ; 将脉宽高字节值送入 X 寄存器

 jmp  L_TestT1L61

5.5  比较模式 (Compare )

5.5.1 SPMC65 系列单片机 Timer 的比较模式

  SPMC65 系列单片机的 6 个 Timer 都可以通过相应控制寄存器的设置,使其工作在比较模式( Compare )。即当某一个 Timer 被设置为比较模式时,相应的管脚就会输出占空比为 50 %的方波。 SPMC65 系列单片机的比较模式简介请参考 表 5.17 。

表 5 . 17 SPCM65 系列单片机比较模式简介

比较模式

比较输出端口

8 位

16 位

Timer 0

与 PB2 复用

Timer 1

与 PB3 复用

Timer 2

与 PD3 复用

Timer 3

与 PD2 复用

Timer 4

与 PD6 复用

Timer 5

与 PD7 复用

  当 Timer x 作为 8/16 位比较输出时,相应的管脚(如 Timer 0 的 PB2 )便会输出精度为 8/16 位的方波,并且可以进行 7 级分频选择。比较功能的计数初值在 Timer x ( x=0~5 )的比较值寄存器 P_TMRx_Comp 和 P_TMRx_CompHi ( 16 位模式中有)中设置。比较模式设置后,计数器从设置的初始值开始计数,当计数器发生第一次溢出时,在相应比较管脚上输出一个高电平,然后载入初始值重新开始计数,当计数器发生第二次溢出时,又在相应比较管脚上输出一个低电平,第三次溢出会再次输出一个高电平,依次不断循环。也就是说,相应管脚会一直输出占空比为 50 %的方波。

5.5.2  比较模式控制寄存器

  SPMC65 系列单片机的 Timer 可通过设置控制寄存器,使其工作在比较模式下;设置 Timer x 控制寄存器 0 (P_TMRy_z_Ctrl0:y=0,2,4;z=1,3,5 )可选择比较器的工作模式,设置 Timer x 控制寄存器 1 ( P_TMRy_z_Ctrl1:y=0,2,4;z=1,3,5 )可选择计数频率。控制寄存器 0 和 1 的各个位功能,以及设置方法请参考前面小节中的介绍。

  每一个 Timer 工作在 8/16 比较模式下时,都有对应的比较值低字节寄存器( P_TMRx_Comp ),高字节寄存器( P_TMRx_CompHi )( 16 位比较模式下才有效)。而 6 个 Timer 对应的比较值寄存器都是类似的。

  Timer x 比较器比较值低字节寄存器 P_TMRx_Comp ( x=0~5 )

  Timer x 比较模式比较值的低字节寄存器( P_TMRx_Comp )以及高字节寄存器( P_TMRx_CompHi )实际上与 Timer x 所对应的重载值(或计数值)低字节、高字节寄存器对应同一地址;所以对其写操作时,也需要按照从高字节寄存器到低字节寄存器的顺序。 P_TMRx_Comp 和 P_TMRx_CompHi 默认初始值为 #00h 。

表 5 . 18 Timer x 比较模式比较值低字节寄存器 P_TMRx_Comp

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

W

TxCP7

TxCP6

TxCP5

TxCP4

TxCP3

TxCP2

TxCP1

TxCP0

R

TxCN7

TxCN6

TxCN5

TxCN4

TxCN3

TxCN2

TxCN1

TxCN0

  Bit [7:0] 写: TxCP [7:0] Timer x 比较模式 比较值 的低字节 TxCP [7:0] (W)

  Bit [7:0] 读: TxCN [7:0] 定时 / 计数器 x 计数值 的低字节 TxCN [7:0] (R)

  Timer x 比较器比较值高字节寄存器 P_TMRx_CompHi ( x=0~5 )

表 5 . 19 Timer x 比较器比较值高字节寄存器 P_TMRx_CompHi

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

W

TxCP15

TxCP14

TxCP13

TxCP12

TxCP11

TxCP10

TxCP9

TxCP8

R

TxCN15

TxCN14

TxCN13

TxCN12

TxCN11

TxCN10

TxCN9

TxCN8

  Bit [7:0] 写: TxCP [15:8] Timer x 比较模式比较值的高字节 TxCP [15:8] (W)

  Bit [7:0] 读: TxCN [15:8] 定时 / 计数器 x 计数值的高字节 TxCN [15:8] (R)

5.5.3  8 位比较模式

  8 位比较模式时序见 图 5.13 。下面以 Timer 0 的 8 位比较模式为例介绍:

  首先将寄存器 P_TMR0_1_Ctrl0 ( $12 )的 T0FS[2 : 0] 位设置为“ 010” ;并在寄存器 P_TMR0_Comp ( $13 )中设置好计数初值;比较输出功能使能后,计数器从设置的初始值开始计数,当计数器发生第一次溢出时, PB2 管脚上输出一个高电平。如果 Timer 0 的溢出中断使能,此时会产生溢出中断。然后载入初始值重新开始计数,当计数器发生第二次溢出时, PB2 管脚上输出一个低电平,第三次溢出会再次输出一个高电平,依次不断循环。也就是说, PB2 管脚会一直输出占空比为 50 %的方波。

  比较输出频率计算公式如下:

*: 比较输出频率

Timer_Prescaler : Timer x 预置分频计数频率( x=0~5 )

图 5 . 13 8 位比较器输出时序

  【例 6-8 】: 将 Timer 0 设置为 8 位比较模式

 lda #00000010B      ; 将 Timer 0 设置为 8 位比较输出

 sta P_TMR0_1_Ctrl0

 lda #00000101B      ; 设置 Timer 0 时钟源为 Fsys/128

 sta P_TMR0_1_Ctrl1

 lda #156         ; 设置定时 / 计数器 0 计数初值为 256-156= 100

 sta P_TMR0_Preload    ; 设置管脚 PB2 的比较输出频率为 Fsys(8MHz)/128/100= 625Hz

5.5.4  16 位比较 模式

  16 位比较模式与 8 位比较模式相似,唯一不同的是 16 位比较模式用两个计数寄存器进行 16 位计数,详细的 16 位比较模式时序请参考 图 5.14 。下面以 Timer 1 的比较模式为例介绍:

  首先将计数初值的高 8 位放入寄存器 P_TMR1_CompHi ($16) 中,低 8 位放入寄存器 P_TMR1_Comp ($15) ,再将寄存器 P_TMR0_1_Ctrl0 ($12) 中的 T1FS[2 : 0] 位设置为 “101” 。计数器开始计数,当计数器发生第一次溢出时, PB3 管脚上输出一个高电平。如果 Timer 1 的溢出中断使能,此时会产生溢出中断。 然后载入初始值重新开始计数,当计数器发生第二次溢出时, PB3 管脚上输出一个低电平,第三次溢出会再次输出一个高电平,依次不断循环。也就是说, PB3 管脚会一直输出占空比为 50 %的方波。

  16 位比较输出频率计算见公式如下:

*: 比较输出频率

Timer_Prescaler : Timer x 预置分频计数频率 (x=0~5)

图 5 . 14 16 位比较器输出时序

  【例 6-9 】: 将 Timer 1 设置为 16 位比较模式并产生输出波形

  lda  #01010000B       ; 将 Timer 1 设置为 16 位比较模式
   
  sta  P_TMR0_1_Ctrl0
   
  lda  #01010000B       ; 设置 Timer 1 时钟源为 Fsys/128
   
  sta  P_TMR0_1_Ctrl1
   
  lda  #02          ; 首先设置定时 / 计数器 1 的重载值高字节计数初值为 2x 256= 512
   
  sta  P_TMR1_PreloadHi
   
  lda  #143          ; 再设置定时 / 计数器 1 的重载值低字节计数初值为 256-143= 113
   
  sta  P_TMR1_Preload     ; 设置 PB3 的比较输出频率为 Fsys(8Mhz)/128/625=100Hz(10ms)

•  比较器中断

  比较中断实际上就是对应 Timer 的定时器溢出中断,而与比较器相关的中断有 5 个,如下:

  •  Timer 0 比较中断

  •  Timer 1 比较中断

  •  Timer 2 比较中断

  •  Timer 3 比较中断

  •  Timer 4 比较中断

  •  Timer 5 比较中断

  下面是设置 Timer 比较中断的几个步骤:

  1. 执行指令 “SEI ” 关闭总的中断开关;

  2. 决定采用 8 位还是 16 位的比较模式并选择一个合适的 Timer x (x=0~5) ;

  3. 设置所选的 Timer 的相关寄存器;

  4. 在寄存器 P_INT_Ctrl1($0F) 中使能该 Timer 的比较中断;

  5. 执行指令 ”CLI” 打开总的中断开关;

  6. 设置完毕,等待比较中断产生。

5.6 PWM 模式

5.6.1 SPMC65 系列单片机 Timer 的 PWM 模式

  SPMC65 系列单片机的 6 个 Timer 都可以通过相应控制寄存器的设置,使其工作在 PWM 模式。 Timer 作为 PWM 输出使用有三种类型(即对应三种类型的 Timer )。比如, Timer 0/2/4 只能作为 8 位 PWM 输出; Timer 1/3 可以输出 12 位 PWM ; Timer 5 可以输出 16 位 PWM 。 SPMC65 系列单片机的 PWM 功能简介请参考 表 5.20 。

  注: PWM 输出即输出频率、占空比均可调的方波。

表 5 . 20 SPMC65 系列单片机定时 / 计数器 PWM 功能简介

PWM

PWM 输出端口

Timer 0

8 位

与 PB2 复用

Timer 1

12 位

与 PB3 复用

Timer 2

8 位

与 PD3 复用

Timer 3

12 位

与 PD2 复用

Timer 4

8 位

与 PD6 复用

Timer 5

16 位

与 PD7 复用

表 5 . 21 分频后的几种 PWM 输出频率对照表

结果

PWM 频率

预分频

= F SYS ÷ 1

预分频

= F SYS ÷ 2

预分频

= F SYS ÷ 4

预分频

= F SYS ÷ 8

16 位 PWM

122HZ

61HZ

30.5 HZ

15.25 HZ

12 位 PWM

1.95KHZ

975HZ

487HZ

243.5HZ

11 位 PWM

3.9 KHZ

1.95KHZ

975HZ

487HZ

10 位 PWM

7.8 KHZ

3.9 KHZ

1.95KHZ

975HZ

9 位 PWM

15.6 KHZ

7.8 KHZ

3.9 KHZ

1.95KHZ

8 位 PWM

31.2 KHZ

15.6 KHZ

7.8 KHZ

3.9 KHZ

  注:系统时钟为 8MHz 。

5.6.2  PWM 模式控制寄存器

  SPMC65 系列单片机的 Timer 可通过设置控制寄存器,来使其工作在 PWM 模式下;设置 Timer 控制寄存器 0 ( P_TMRy_z_Ctrl0:y=0,2,4;z=1,3,5 )可选择 PWM 的工作模式,设置定时 / 计数器控制寄存器 1 ( P_TMRy_z_Ctrl1:y=0,2,4;z=1,3,5 )可选择计数频率。控制寄存器 0 和 1 的各个位功能,以及设置方法请参考前面小节中的介绍。

  而每一个定时 / 计数器工作在 8/12/16 位 PWM 模式下时,都有对应的周期值寄存器、占空比值寄存器。而在三类 PWM 模式中,只详细介绍每种类型 PWM 模式对应的其中一个定时 / 计数器的 PWM 模式相关寄存器,同类型的可以定时 / 计数器的 PWM 相关控制寄存器在功能、设置上是类似的。

  1 , 8 位 PWM 模式

  Timer x PWM 周期值寄存器 P_TMRx_PWMPeriod ( x=0,2,4 )

  Timer 的 PWM 模式为 8 位时,在一定计数频率的情况下,可以写入不同的值到 Timer x 的 PWM 周期值寄存器( P_TMRx_PWMPeriod ),以改变所输出 PWM 信号的周期。 P_TMRx_PWMPeriod 寄存器默认初始值为 #00h ,该寄存器具体功能请参考 表 5.22 :

表 5 . 22 Timer x PWM 周期值寄存器 P_TMRx_PWMPeriod

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

TxPP7

TxPP6

TxPP5

TxPP4

TxPP3

TxPP2

TxPP1

TxPP0

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

  Bit [7:0]: TxPP [7:0] : Timer x PWM 周期值 TxPP [7:0] (8 位 PWM 模式 )

  Timer x PWM 占空比寄存器 P_TMRx_PWMDuty ( x=0,2,4 )

  Timer x PWM 占空比寄存器( P_TMRx_PWMDuty ),设置 PWM 输出信号的占空比,该寄存器默认初始值为 #00h ,其具体的功能请参考:

表 5 . 23 Timer x PWM 占空比寄存器 P_TMRx_PWMDuty

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

TxPD7

TxPD6

TxPD5

TxPD4

TxPD3

TxPD2

TxPD1

TxPD0

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

  Bit [7:0] TxPD [7:0]: Timer x PWM 占空比值 TxPD [7:0] (8 位 PWM 模式 )

    注: Timer 工作在 8 位 PWM 模式下,使能 8 位 PWM 模式时,先写寄存器 P_TMRx_PWMDuty ,再写寄存器 P_TMRx_PWMPeriod 。

  2 , 12 位 PWM 模式

  Timer x PWM 周期值低字节寄存器 P_TMRx_PWMPeriod ( x=1,3 )

  Timer 的 PWM 模式为 12 位时,除了有低字节的周期值寄存器、占空比值寄存器外,还占用了一个字节的寄存器,为周期值和占空比值的高 4 位共用。定时 / 计数器 1 的这 3 个寄存器默认初始值为 #00h ,其具体功能请参考下面的表。

表 5 . 24 Timer x PWM 周期值低字节寄存器 P_TMRx_PWMPeriod

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

TxPP7

TxPP6

TxPP5

TxPP4

TxPP3

TxPP2

TxPP1

TxPP0

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

  Bit [7:0] TxPP [7:0] : Timer x PWM 周期值的低字节 TxPP [7:0] (12 位 PWM 模式 )

  Timer x PWM 占空比 / 周期值高 4 位寄存器 P_TMRx_DutyPeriod ( x=1,3 )

表 5 . 25 Timer x PWM 占空比 / 周期值高 4 位寄存器 P_TMRx_DutyPeriod

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

TxPD11

TxPD10

TxPD9

TxPD8

TxPP11

TxPP10

TxPP9

TxPP8

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

  Bit [7:4] TxPD [11:8] : Timer x PWM 占空比值的高 4 位 TxPD [11:8] (12 位 PWM 模式 )

  Bit [3:0] TxPP [11:8] : Timer x PWM 周期值 的高 4 位 TxPP [11:8] (12 位 PWM 模式 )

  Timer x PWM 占空比值低字节寄存器 P_TMRx_PWMDuty ( x=1,3 )

表 5 . 26 Timer x PWM 占空比值低字节寄存器 P_TMRx_PWMDuty

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

TxPD7

TxPD6

TxPD5

TxPD4

TxPD3

TxPD2

TxPD1

TxPD0

R/W

R/W

R/W

R/W

R/W

R/W

R/W

R/W

  Bit [7:0] TxPD [7:0]: Timer x PWM 占空 比值的低字节 TxP D [7:0] (12 位 PWM 模式 )

  注:写入数据顺序要按照从高字节到低字节的顺序写。

  12 位 PWM 模式如:

  • 更新周期值时,先写 P_TMR1_DutyPeriod ,然后再写 P_TMR1_PWMPeriod

                                                                                                                                • 更新占空比时,先写 P_TMR1_DutyPeriod ,然后再写 P_TMR1_PWMDuty

  3 , 16 位 PWM 模式

  Timer 5 的 PWM 模式为 16 位的,其周期值、占空比值寄存器各占两个字节,分别用于存放高字节、低字节的数值;这 4 个寄存器默认初始值为 #00h 。

  Timer 5 PWM 周期值低字节寄存器 P_TMR5_PWMPeriodLo ( $23 , R/W )

  Timer 5 PWM 周期值高字节寄存器 P_TMR5_PWMPeriodHi ( $24 , R/W )

  Timer 5 PWM 占空比值低字节寄存器 P_TMR5_PWMDutyLo ( $25 , R/W )

  Timer 5 PWM 占空比值高字节寄存器 P_TMR5_PWMDutyHi ( $5F , R/W )

  注:写入数据顺序要按照从高字节到低字节的顺序写

  16 位 PWM 模式如:

  •  更新周期值时,先写 P_TMR5_DutyPeriodHi ,然后再写 P_TMR5_PWMPeriodLo

  •  更新占空比时,先写 P_TMR5_DutyPeriodHi ,然后再写 P_TMR5_PWMDutyLo

5.6.3 8 位 PWM 工作模式

  SPMC65 系列单片机中, Timer 0/2/4 属于第一种 ( 类型 I) — 8 位 PWM 。当 TxFS[2:0] 设置为 111 后, Timer x 就工作在 8 位 PWM 模式下,相应的管脚 ( 例如,定时 / 计数器 0 对应 PB2) 自动成为 PWM 输出管脚。 PWM 周期在寄存器 P_TMRx_PWMPeriod 中设置;占空比在寄存器 P_TMRx_PWMDuty 中设置;在 8 位 PWM 模式下,使能 8 位 PWM 功能后用户必须首先写寄存器 P_TMRx_PWMDuty ,然后再写寄存器 P_TMRx_PWMPeriod 。时钟的分频系数由 TxPSS[2:0] 位选择。当 PWM 使能后,计数器载入计数初值( P_TMRx_PWMPeriod 的值),开始计数,同时,相应的管脚输出低电平。在计数过程中,计数值不断的和占空比值( P_TMRx_PWMDuty 的值)进行比较,相等时, PWM 管脚输出电平翻转,为高电平。计数器继续计数,直到溢出,此时一个周期的方波输出完成。接着, PWM 管脚再次翻转,输出低电平,计数器重新载入计数初值开始计数,产生下一个 PWM 输出,依次不断循环。

  如 图 5.15 所示为 8 位 PWM 模式原理框图。

  PWM 周期和占空比计算如下:

If

 PRDREG= 周期值寄存器数值

 DUTYREG= 占空比值寄存器数值

 T_TMRx= Timer x 预分频后计数时钟周期 (x=0,2,4)

Then

 PWM 周期 =[$100H-PRDREG]*T_TMRx

 PWM 占空比 =[$FFH-DUTYREG]*T_TMRx

图 5 . 15 8 位 PWM 模式原理框图

图 5 . 16 8 位 PWM 操作时序

  【例 6-10 】: 将 Timer 0 设置为 8 位 PWM 模式

 lda  #00000011B       ; 设置 Timer 0 计数频率为 Fcs/8
   
  sta  P_TMR0_1_Ctrl1
   
  lda  #00000111B      ; 将 Timer 0 设置为 8 位 PWM 模式
   
  sta  P_TMR0_1_Ctrl0
   
  lda  #178
   
  sta  P_TMR0_PWMDuty     ; 在 PB2 管脚上输出占空比 (255 - 178) / 255 ~= 30%
   
  lda  #$00
   
  sta  P_TMR0_PWMPeriod    ; PWM 频率 = 8.0MHz / (255 x 8) = 3.9 KHz

5.6.4 12位 PWM 工作模式

  SPMC65 系列单片机中, Timer 1/3 属于第二种 ( 类型 II ) — 12 位 PWM 。当 TxFS[2:0] 设置为 111 后, Timer x 就成为 12 位 PWM 发生器,相应的管脚 ( 如: Timer 1 对应 PB3) 自动成为 12 位 PWM 输出管脚。 PWM 周期在寄存器 P_TMRx_PWMPeriod 和 P_TMRx_DutyPeriod [3:0] 中设置;占空比在寄存器 P_TMRx_DutyPeriod [7:4] 和 P_TMRx_PWMDuty. 中设置;时钟的分频系数由 TxPSS[2:0] 位选择。当 PWM 使能后,计数器载入计数初值( P_TMRx_PWMPeriod 的值),开始计数,同时,相应的管脚输出低电平。在计数过程中,计数值不断的和占空比值 {P_TMRx_DutyPeriod [7:4], P_TMRx_PWMDuty [7:0]} 进行比较,相等时, PWM 管脚输出电平翻转,为高电平。计数器继续计数,直到溢出,此时一个周期的方波输出完成。接着, PWM 管脚再次翻转,输出低电平,计数器重新载入计数初值开始计数,产生下一个 PWM 输出,依次不断循环。

  一般 8 位 CPU ,总线宽度为 8 位,通常无法直接访问 16 位的数据。因此,在 12 位 PWM 模式下,用户需要先写入高字节寄存器 P_TMRx_DutyPeriod (MSB byte) 并被缓冲器自动保存,然后再写入低字节 P_TMRx_PWMPeriod ( 周期 ) / P_TMRx_PWMDuty ( 占空比 ) ,直到 12 位数据全部写入,缓冲器的值才会直正载入到寄存器当中,这样缓冲器中的高字节和低字节将会同时载入定时 / 计数器 x 中去。

  注: x=1,3

  如 图 5.17 所示为 12 位 PWM 模式原理框图。

  PWM 周期和占空比计算公式如下:

If

 PRDREG={P_TMRx_DuyPeriod [3:0], P_TMRx_PWMPeriod [7:0]}

 DUTYREG={P_TMRx_DuyPeriod [7:4], P_TMRx_PWMDuy [7:0]}

 T_TMRx = Timer x 预分频后计数时钟周期 (x=1,3)

Then

 PWM PERIOD=[$1000H-PRDREG]* T_TMRx

 PWM DUTY=[$FFFH-DUTYREG]* T_TMRx

图 5 . 17 12 位 PWM 输出原理框图

图 5 . 18 12 位 PWM 操作時序

  【例 6-11 】: 将定 Timer 1 设置为 12 位 PWM 模式

  lda  #01110000B     ; 将 Timer 1 设置为 12 位 PWM 模式
   
  sta  P_TMR0_1_Ctrl0
   
  lda  #00110000B     ; 设置 Timer 1 的计数频率为: Fsys/8
   
  sta  P_TMR0_1_Ctrl1
   
  lda  #$70
   
  sta  P_TMR1_DutyPeriod  ; PWM 占空比 $7FF , PWM 周期 $1000
   
  lda  #$00
   
  sta  P_TMR1_PWMPeriod
   
  lda  #$FF
   
  sta  P_TMR1_PWMDuty   ; 在 PB3 管脚产生 244Hz 50% 佔空比的 PWM 输出

5.6.5  16 位 PWM 工作模式

  SPMC65 系列单片机中, Timer 5 属于第三种 ( 类型 III ) — 16 位 PWM 。当 T5FC [2:0] 设置为 111 后,
Timer 5 就成为 16 位 PWM 发生器,相应的管脚 PD7 自动成为 16 位 PWM 输出管脚。 PWM 周期在寄存器 P_TMR5_PWMPeriodLo ($23) 和 P_TMR5_PWMPeriodHi ($24) 中设置;占空比在寄存器 P_TMR5_PWMDutyLo ($25) 和 P_TMR5_PWMDutyHi ($5F) 中设置;时钟的分频系数由 T5PSS [2:0] 位选择。当 PWM 使能后,计数器载入计数初值 { P_TMR5_PWMPeriodHi, P_TMR5_PWMPeriodLo} ,开始计数。同时,管脚 PD7 输出低电平。在计数过程中,计数值不断的和占空比值 {P_TMR5_PWMDutyHi, P_TMR5_PWMDutyLo} 进行比较,相等时, PWM 管脚输出电平翻转,为高电平。计数器继续计数,直到溢出,此时一个周期的方波输出完成。接着, PWM 管脚再次翻转,输出低电平,计数器重新载入计数初值开始计数,产生下一个 PWM 输出,依次不断循环。

  一般 8 位 CPU ,总线宽度为 8 位,通常无法直接访问 16 位的数据。因此,在 16 位 PWM 模式下,周期值寄存器和占空比值寄存器也分别占用了高字节寄存器( MSB byte )和低字节寄存器( LSB byte );在设置周期值寄存器和占空比值寄存器时,也需要按照先写高字节寄存,然后再写低字节寄存器的顺序。

  如 图 5.19 所示为 16 位 PWM 输出原理框图。而 Timer 5 的 PWM 模式的操作时序与其它类型 PWM 模式的类似,具体可以参考前面有 8/12 位 PWM 模式的介绍。

PWM 周期和占空比计算公式如下:

If

 PRDREG={P_TMR5_PWMPeriodHi, P_TMR5_PWMPeriodLo}

 DUTYREG={P_TMR5_PWMDutyHi, P_TMR5_PWMDutyLo}

 T_TMR5= Timer5 预分频后计数时钟周期

Then

 PWM 周期 =[$10000H-PRDREG]* T_TMR5

 PWM 占空比 =[$FFFF-DUTYREG]* T_TMR5

图 5 . 19 16 位 PWM 输出原理框图

  【例 6-12 】: 将 Timer 5 设置为 16 位 PWM 模式

 lda  #00000000B      ; 将 Timer5 时钟源设置为 Fcs/1
   
  sta  P_TMR4_5_Ctrl1
   
  lda  #01110000B      ; 将 Timer 5 设置为 16 位 PWM 功能
   
  sta  P_TMR4_5_Ctrl0
   
  lda  #$A0
   
  sta  P_TMR5_PWMDutyHi
   
  lda  #$00
   
  sta  P_TMR5_PWMDutyLo   ; 在 PD7 输出 PWM 波形 ,
   
                ; 占空比 = (0xFFFF-0xA000)/(0xFFFF-0x8000)~= 75%
   
  lda  #$80
   
  sta  P_TMR5_PWMPeriodHi
   
  lda  #$00
   
  sta  P_TMR5_PWMPeriodLo   ; PWM 频率 = 8.0MHz / (0xFFFF - 0x8000) ~= 244 Hz

5.6.6  PWM 中断

  与 PWM 操作相关的中断如下:

  •  Timer 0 溢出中断

  •  Timer 1 溢出中断

  •  Timer 2 溢出中断

  •  Timer 3 溢出中断

  •  Timer 4 溢出中断

  •  Timer 5 溢出中断

  下面是设置 PWM 中断的几个步骤:

  1. 执行指令 “SEI ” 关闭总的中断开关;

  2. 决定采用 8 位还是 12 位或是 16 位的 PWM 方式并选择一个合适的 Timer ;

  3. 设置与 PWM 操作相关寄存器;

  4. 在寄存器 P_INT_Ctrl1($000Fh) 中使能该 Timer 溢出中断( PWM 中断);

  5. 执行指令 ”CLI” 打开总的中断开关;

  6. 设置完毕,等待 PWM 中断产生。

  SPMC65 系列单片机的 PWM 中断应用可参考对应定时 / 计数器的中断应用。
版权所有:北京凌阳爱普科技有限公司 京ICP备05061966号 未经许可网站内容严禁复制、转载,任何人不得擅自使用
友情链接:凌阳爱普 嵌入式培训 安卓培训 凌阳大学计划 北京嵌入式培训 深圳嵌入式培训 成都嵌入式培训