Download presentation
Presentation is loading. Please wait.
1
第七章 定时计数器与可编程 计数器阵列
2
任课教师:刘忠国 山东大学课程中心网站: 宏晶官方网站: STC单片机编译(汇编)/编程(烧录)/仿真工具说 明书; stc15系列单片机器件手册等 keil μvision软件下载及指导手册(Help→μvision Help) Keil Software –Cx51 编译器用户手册: Cx51编译 器--对传统和扩展的8051微处理器的优化的C 编译器和库参考
3
第七章 定时计数器与可编程计数器阵列 本章学习目标 掌握定时计数器的应用 掌握可编程时钟输出模块的应用 掌握可编程计数器阵列模块的应用
4
第七章 定时计数器与可编程计数器阵列 7.1 定时/计数器及其应用 7.2 可编程时钟输出模块及其应用 7.3 可编程计数器阵列模块及其应用
第七章 定时计数器与可编程计数器阵列 7.1 定时/计数器及其应用 7.1.1 定时/计数器的结构及工作原理 7.1.2 定时/计数器的相关寄存器 7.1.3 定时/计数器的工作方式 7.1.4 定时/计数器量程的扩展 7.1.5 定时/计数器编程举例 7.2 可编程时钟输出模块及其应用 7.2.1 可编程时钟输出的相关寄存器 7.2.2 可编程时钟输出的编程实例 7.3 可编程计数器阵列模块及其应用 7.3.1 PCA模块的结构 7.3.2 PCA模块的特殊功能寄存器 7.3.3 PCA模块的工作模式 7.3.4 PCA模块的应用
5
第七章 定时计数器与可编程计数器阵列 STC15F2K60S2单片机内部集成了以下与定时功 能有关的模块: 1)三个16位的定时/计数器,不仅可以方便地用于定 时控制,而且还可以用作分频器和事件记录; 2)可编程时钟输出功能,可给外部器件提供时钟; 3)三路可编程计数器阵列(Programmable Counter Array, PCA)。可用于软件定时器、外部脉冲的捕捉、 高速输出以及脉宽调制(Pulse Width Modulation, PWM)输出。
6
§7.1定时/计数器及其应用 7.1.1 定时/计数器的结构及工作原理
定时/计数器的核心是一个加1计数器,加1计数器的 脉冲有两个来源,一个是外部脉冲源,另一个是系统 的时钟振荡器。 括号内1表示T1x12, 以下类同 AUXR.T0(1)x12 TCON.TR0 溢出中断标志 TCON.TR1 TCON.TF0 P3.4/T0 开启 运行 TCON.TF1 P3.5/T1 TMOD 图7-1 定时/计数器的结构框图(x =0, 1, 下同)
7
7.1.1定时/计数器的结构及工作原理 图中有两个模拟位开关, TMOD.C/T决定工作方式: 是 定时还是计数。
控制信号(由TCON.TR0(1)等形成) 决定计数器开启与 关闭。 用户可对特殊功能寄存器TMOD, TCON相应位设置, 从而选择不同工作方式(计数或定时)或是否启动计数器。 AUXR中T0x12, T1x12决定是否对振荡时钟进行12分频。 开启运行 AUXR.T0(1)x12 TMOD 由TCON.TR0(1)等形成 图7-1 定时/计数器的结构框图( x =0, 1, 下同)
8
7.1.1、定时/计数器的结构及工作原理 当脉冲源为时钟振荡器(等间隔脉冲序列)时, 每个时钟 周期计数器加1, 因计数脉冲为一时间基准, 所以脉冲数 乘以脉冲间隔时间即定时时间, 因此有定时功能。 当脉冲源为外部脉冲(通常间隔不等) 时, 就是外部事件 计数器, 当外输入端上有1→0的跳变时计数器加1。 外部输入信号的速率是不受限制的,但必须保证给出 的电平在变化前至少被采样一次。 TMOD TCON.TR0(1) 图7-1 定时/计数器的结构框图(x =0, 1, 下同)
9
7.1.1定时/计数器的结构及工作原理 计数器对这两个脉冲源之一进行输入计数,每输入一 个脉冲,计数值加1。
当计数到计数器全1时, 再输入一个脉冲就使计数值回 零, 同时从最高位溢出一个脉冲使寄存器TCON的TF0 或TF1置1, 作为计数器的溢出中断标志。 如果定时/计数器工作于定时状态,则表示定时时间到; 若工作于计数状态,则表示计数回零。 TCON.TF0(1) 溢出中断标志 TMOD TCON.TR0(1)
10
7.1.1定时/计数器的结构及工作原理 图7-2 CPU与TMOD、TCON、AUXR、T0、T1的关 系图
P3.5/T1 P3.4/T0 脉冲输入源 定时器0, 1的16位计数器 TR1 TF0 C/T 标志TF1 C/T TR0启动运行 溢出中断 M1 M0 T0(1)x12 16位的加1计数器由两个8位的特殊功能寄存器THx (高8位)和TLx(低8位)组成(x=0, 1, 下同)。 通过改变TMOD的相应位,它们可被设置为4种不同 的工作方式。
11
7.1.1定时/计数器的结构及工作原理 STC15F2K60S2除了定时/计数器T0和T1外,还有一个 16位定时器T2(简称T2)。
AUXR.2 定时器2的16位计数器 AUXR.3 引脚 AUXR.4 图7-3 定时器T2的原理框图 INT_CLKO内 定时器2的16位重装载寄存器
12
定时/计数器的相关寄存器 TMOD、TCON和AUXR用来确定定时/计数器的工作 方式并控制其功能。其中,TMOD控制定时/计数器0和 1的工作方式;TCON控制定时器T0、T1的启停及状态; AUXR设置定时器的速度和T2的功能。 1、TMOD:定时器工作方式控制寄存器 TMOD(地址为89H, 复位值为00H)寄存器的各位定义: 位号 D7 D6 D5 D4 D3 D2 D1 D0 定时器名 定时器1 定时器0 位名称 GATE C/ M1 M0
13
1、TMOD:定时器工作方式控制寄存器 位号 D7 D6 D5 D4 D3 D2 D1 D0 定时器名 定时器1 定时器0 位名称 GATE
C/ M1 M0 1)M1和M0:方式选择控制位 表7-1 定时/计数器的方式选择 M1 M0 工作方式 功能说明 0 0 16位自动装载的定时器/计数器 0 1 1 16位定时器/计数器 1 0 2 可自动装入的8位计数器 1 1 留作备用 对T0是不可屏蔽中断的16位自动重装定时器 对T1定时器/计数器1此时无效(停止计数)
14
1、TMOD:定时器工作方式控制寄存器 位号 D7 D6 D5 D4 D3 D2 D1 D0 定时器名 定时器1 定时器0 位名称 GATE
C/ M1 M0 2)C/ :功能选择位。 1:计数器功能(对T0或T1引脚的负跳变进行计数)。 0:定时器功能(对时钟周期进行计数)。 3)GATE:门控位。GATE用于选通控制。 1:INTx为高电平且TRx置位时, 启动定时器工作。 0:每当TRx置位时, 就启动定时器工作。 注意: TMOD寄存器(地址: 89H)不能进行位寻址,设置 时只能对整个寄存器赋值。
15
TMOD.GATE:门控位。GATE用于选通控制。 GATE=1: INTx为高电平且TRx置位时, 启动定时器工 作。
参考7.1.3定时/计数器的工作方式图7-4,图7-5,图7-6 TMOD.GATE:门控位。GATE用于选通控制。 GATE=1: INTx为高电平且TRx置位时, 启动定时器工 作。 GATE=0: 每当TRx置位时, 就启动定时器工作。 开启运行 TCON.TF0(1) 溢出中断标志 图7-1 定时/计数器的结构框图 由TCON.TR0(1)等形成 参考图7-5 定时器0和1的方式1的原理图
16
2、TCON:定时器控制寄存器 TCON(地址为88H,复位值为00H)寄存器的格式如下: 位号 D7 D6 D5 D4 D3 D2 D1
位名称 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 1)TF1:T1溢出标志位。 T1启动计数后,最高位产生溢出时,TF1由硬件置1, 向CPU请求中断,当CPU响应中断时,由硬件清0。 TF1也可以由程序查询或清0。 2)TF0:定时器/计数器0溢出标志位。 含义和功能与TF1相似。
17
2、TCON:定时器控制寄存器 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 TF1 TR1 TF0 TR0 IE1 IT1
3)TR1:T1的运行控制位。可由软件置位或清0。 当GATE(TMOD.7)=0,TR1=1启动T1开始计数, TR1=0时停止T1计数。 当GATE(TMOD.7)=1,TR1=1且INTx输入高电平时, 才允许T1计数。 4)TR0:定时器T0的运行控制位。 含义和功能与TR1相似。
18
2、TCON: 定时器0、1控制寄存器 因定时/计数器0、1可编程(选3种方式等), 所以在任何一 个定时/计数器开始工作前, 必须对其写入相应控制字: 把方式控制字写入TMOD, 选择定时器的工作方式; 把初值写入计数器THx、TLx, 控制计数长度; 将TCON相应位(TRx)置1或清零实现启动或停止计数。 在运行过程中,还可读出THx、TLx和TCON的内容来 随时查询T0、T1的状态。 位号 D7 D6 D5 D4 D3 D2 D1 D0 定时器名 定时器1 定时器0 位名称 GATE C/ M1 M0 TMOD 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 TCON
19
3、AUXR:辅助寄存器 辅助寄存器AUXR主要用来设置定时器的速度和定时 器2的功能以及串口UART的波特率控制。
STC15F2K60S2单片机是1T 的8051单片机, 为兼容传 统8051单片机, 定时器0和定时器1复位后是传统8051 的速度, 即12分频, 但指令执行速度仍然是1T的速度。 通过设置特殊功能寄存器AUXR中相关的位,定时器 也可不进行12分频,实现真正的1T速度。 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 T0x12 T1x12 UART_M0x6 T2R T2_C/ T2x12 EXTRAM S1ST2
20
3、AUXR:辅助寄存器 辅助寄存器AUXR(地址为8EH, 复位值为01H)各位定义: 1)T0x12:定时器0速度控制位。
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 T0x12 T1x12 UART_M0x6 T2R T2_C/ T2x12 EXTRAM S1ST2 1)T0x12:定时器0速度控制位。 0: 定时器0速度与传统8051定时器速度相同, 即12分频。 1: 定时器0速度是传统8051定时器速度的12倍, 即不分频。 2)T1x12:定时器1速度控制位。 0:即12分频。 1:不分频。 如果UART串口用T1作为波特率发生器,T1x12位决定 UART串口是12T 还是1T。
21
3、AUXR:辅助寄存器 3)T2R:定时器2运行控制位。 0:不允许定时器2运行; 1:允许定时器2运行。
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 T0x12 T1x12 UART_M0x6 T2R T2_C/ T2x12 EXTRAM S1ST2 3)T2R:定时器2运行控制位。 0:不允许定时器2运行; 1:允许定时器2运行。 4)T2_C/ :定时器2用作定时器和计数器的选择。 0:定时器(计数脉冲从内部系统时钟输入; 1:计数器(计数脉冲从P3.1/T2引脚输入)。 T2工作模式固定为16位自动重装载模式。不用设置工作方式。
22
3、AUXR:辅助寄存器 5)T2x12:定时器2速度控制位。 0: 12分频,T2每12个时钟计数一次;
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 T0x12 T1x12 UART_M0x6 T2R T2_C/ T2x12 EXTRAM S1ST2 5)T2x12:定时器2速度控制位。 0: 12分频,T2每12个时钟计数一次; 1:不分频,T2每1个时钟计数一次。 UART_M0x6用于控制UART串口1方式0时的波特率。 0:波特率SYSclk/12; 1:波特率SYSclk / 2; (第8章) S1ST2为串口1选择T1或T2作波特率发生器。(第8章) 0: 选择定时器1; 1: 选择定时器2 EXTRAM:设置是否允许使用内部1792字节扩展RAM。 0: 允许使用片内扩展RAM; 1: 禁止使用。
23
7.1.2 定时/计数器的相关寄存器 4. T2H/RL_TH2:定时器2的16位计数器的高字节 /16位重装载(重装值)寄存器高字节
定时/计数器的相关寄存器 4. T2H/RL_TH2:定时器2的16位计数器的高字节 /16位重装载(重装值)寄存器高字节 (共用地址为0D6H, 复位值为00H) 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 5. T2L/RL_TL2: 定时器2的16位计数器的低字节 /16位重装载(重装值)寄存器低字节 (共用地址为0D7H, 复位值为00H) 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 RL_TH2, RL_TL2: 是2个隐藏的寄存器, CPU通过TH2, TL2对其写入数值。
24
定时/计数器的相关寄存器 定时器2有2个隐藏的寄存器 RL_TH2和RL_TL2 。RL_TH2与 T2H共有同一个地址, RL_TL2与T2L共有同一个地址。 当T2R=0即定时器/计数器2被禁止工作时, 对T2L写入的内容会 同时写入RL_TL2, 对T2H写入的内容也会同时写入RL_TH2。 当T2R=1即定时器/计数器2被允许工作时, 对T2L写入内容, 实际 上不是写入当前寄存器T2L中, 而是写入隐藏寄存器RL_TL2中; 对T2H写入内容, 实际上也不是写入当前寄存器T2H中, 而是写入 隐藏的寄存器RL_TH2。 这样可以巧妙地实现16位重装载定时器。 当读T2H和T2L的内容时, 所读的内容就是T2H和T2L的内容, 而 不是RL_TH2和RL_TL2的内容。
25
定时/计数器的相关寄存器 定时器0(1)有2个隐藏的寄存器 RL_TH0(1)和RL_TL0(1) 。 RL_TH0(1)与TH0(1)共有同一个地址, RL_TL0(1)与TL0(1)共有 同一个地址。 当TR0(1)=0即定时器/计数器0(1)被禁止工作时, 对TL0(1)写入 的内容会同时写入RL_TL0(1), 对TH0(1)写入的内容也会同时写 入RL_TH0(1)。 当TR0(1)=1即定时器/计数器0(1)被允许工作时, 对TL0(1)写入 内容, 实际上不是写入当前寄存器TL0(1)中, 而是写入隐藏的寄 存器RL_TL0(1)中; 对TH0(1)写入内容, 实际上也不是写入当前 寄存器TH0(1)中, 而是写入隐藏的寄存器RL_TH0(1)。 这样可以巧妙地实现16位重装载定时器。 当读TH0(1)和TL0(1)的内容时, 所读的内容就是TH0(1)和TL0(1) 的内容, 而不是RL_TH0(1)和RL_TL0(1)的内容。
26
7.1.3 定时/计数器的工作方式 通过对寄存器TMOD中M1、M0的设置,定时/计数 器有4种不同的工作方式:
定时/计数器的工作方式 通过对寄存器TMOD中M1、M0的设置,定时/计数 器有4种不同的工作方式: 方式0: 16位自动重装方式 方式1: 16位定时/计数器方式 方式2: 8位自动重装方式 方式3: 留作备用 位号 D7 D6 D5 D4 D3 D2 D1 D0 定时器名 定时器1 定时器0 位名称 GATE C/ M1 M0
27
1、定时/计数器0和1的工作方式0 (16位自动重装方式)
图7-4 定时器0和1的工作方式0原理框图 AUXR.7/.6 定时器的16位计数器 TMOD.2/.6 P3.4/T0/T1CLKO P3.5/T1/T0CLKO TCON .4 /.6 定时器的16位重装载寄存器 INT_CLKO内 引脚P3.5/T1/T0CLKO 引脚P3. 4 / T0 / T1CLKO 当GATE(TMOD.7)=0, TRx=1启动定时器计数。当GATE=1, 允许由外部INTx高电平控制计数, 可实现脉宽测量。
28
1、定时/计数器0和1的工作方式0 (16位自动重装方式)
如何实现16位重装载定时器。 定时器0和1分别有2个隐藏寄存器RL_THx和RL_TLx。 RL_THx与THx共有同一个地址,RL_TLx与TLx共有同一 个地址。 当TRx=0即定时器/计数器被禁止工作时, 对TLx、THx写入 的内容会同时写入RL_TLx、 RL_THx。 当TRx=1即定时器/计数器工作时, 对TLx、THx写入的内容 实际上不是写入当前寄存器TLx、THx中, 而是写入隐藏的寄 存器(修改教材)不会写入RL_TLx、 RL_THx。(注意该情形的 前提条件是方式0)。 这里simulator和硬件仿真结果不同 方便调试? ! simulator时TH1是8位计数器, TL1是4位计数器 !?且方式0溢出中断时, RL_TLx、 RL_THx都不能自动加载 , TL1无法写入, TH1都可写入; 方式1、2时与教材所讲同。 注意在方式1时, TRx=1时,对TLx、THx的写, 是确实写入当前寄存器TLx、THx中。
29
1、定时/计数器0和1的工作方式0 (16位自动重装方式)
当定时器工作在模式0时,[TLx, THx]的溢出不仅置位 TFx,而且会自动将[RL_TLx, RL_THx]的内容重新装 入[TLx, THx]。 当位T0CLKO (INT_CLKO.0)=1时, 将引脚T1/P3.5 /T0CLKO配置为定时器0的时钟输出T0CLKO。 当位T1CLKO (INT_CLKO.1)=1时, 将引脚T0/P3.4 /T1CLKO配置为定时器1的时钟输出T1CLKO。 外部中断使能和时钟输出寄存器INT_CLKO 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 - EX4 EX3 EX2 LVD_WAKE T2CLKO T1CLKO T0CLKO
30
2. 定时/计数器0和1的工作方式1(16位定时/计数器方式)
定时(计数)溢出就置位中断标志 不能重装载计数初值(时间常数), 不能设置输出时钟 定时(计数)溢出时需用户重新加载计数初值, 否则从0开始计数 图7-5 定时器0和1的方式1的原理框图
31
2. 定时/计数器0和1的工作方式1(16位定时/计数器方式)
此模式下, 定时器配置为16位计数器, 由TLx 的8位和THx的8位构成。 TLx的8位溢出向THx进位, THx计数溢出置位 TCON中的溢出标志位TFx。 与方式0的区别是, THx计数溢出时, 不会自动 重新装载时间常数。此外, 本模式也不用于时 钟输出功能。
32
3. 定时/计数器0和1的工作方式2 (8位自动重装方式)
除了是8位计数且重装载寄存器不同外, 其他与方式0类似 图7-6 定时/计数器的工作方式2原理框图
33
3. 定时/计数器0和1的工作方式2 (8位自动重装方式)
方式2是能自动重置初值的8位定时/计数器,计数溢出 后具有自动恢复初值的功能。 当TL0/TL1计数溢出时, 不仅置位溢出标志TF0/TF1, 还自动将TH0/TH1的内容送入TL0/TL1, 使TL0/TL1从 初值开始重新计数。 用户可以通过程序把时间常数预置在TH0/TH1中, 再 装入后, TH0/TH1的内容保持不变。 当位T0CLKO (INT_CLKO.0)=1时, 将引脚T1/P3.5 /T0CLKO配置为定时器0的时钟输出T0CLKO。 当位T1CLKO (INT_CLKO.1)=1时, 将引脚T0/P3.4 /T1CLKO配置为定时器1的时钟输出T1CLKO。
34
定时/计数器的工作方式 在自动装载时间常数的工作方式0, 2中,用户不需要 在中断服务程序中重载定时常数,可产生高精度的定 时时间,适合用作较精确的定时脉冲信号发生器,如 波特率发生器等。 特别是工作方式0(16位自动重装方式),实际工程 中应用更加方便,因此,建议读者尽量使用方式0进 行定时器的应用设计。 定时器2的工作方式与定时器0或1的工作方式0类似, 读者可参照上述内容自行学习。 注意: T2工作模式固定为16位自动重装载模式。 (相当于方式0)
35
定时/计数器量程的扩展 实际中需要的定时时间常数超过定时器的定时能力, 特 别当单片机系统时钟频率较高时, 定时时长就更有限。 为满足需要, 经常需对单片机的定时能力进行扩展。 1、定时器的最大定时能力 定时状态时,定时器是对时钟周期进行计数,若对 时钟进行12分频,则每12个时钟周期计数一次。 当晶振频率为6MHz, 用12分频时, 计数的单位时间为: 单位时间为:Tu= = s =2μs 定时时间为:Tc=XTu。其中,Tu为单位时间,Tc为 定时时间,X为所需计数的次数值。
36
1、定时器的最大定时能力 单位时间:Tu =2μs 定时时间: Tc=XTu ,X为所需计数次数。
STC15F2K60S2单片机的定时/计数器是加1计数器。 因此, 不能直接将实际的计数次数值X作为计数初值送 入计数寄存器THx、TLx中, 而须将实际计数次数值先以28、216为模求补, 以补码 作为计数初值送入THx和TLx。 即应装入定时/计数器的计数初值为: X 其中,n=8或16。
37
1、定时器的最大定时能力 例如: 已知Tu=2μs, 要求定时Tc=1ms, 则:
晶振频率为6MHz, 用12分频时 则: 对方式0和方式1, 计数初值: = =0FE0CH (THx装入FEH,TLx装入0CH)。 当系统时钟频率为6MHz,12分频时: 8位定时器最大定时能力为: T= (28 - 0)×2μs=512μs 16位定时器最大定时能力为: T= ( )×2μs =131072μs= ms
38
2、定时量程的扩展 定时量程的扩展分为软件扩展和硬件扩展两种方法。 (1)软件扩展方法 软件扩展方法是在定时器中断服务程序中对定时器中 断请求次数进行计数,当中断请求次数达到要求值时 才进行相应的处理。 例如,某事件的处理周期为1s, 由于受到最大定时时间 的限制,无法一次完成定时。 可将定时器的定时时间设为10ms,启动定时器后,每 一次定时器溢出中断将产生10ms的定时。 在中断服务程序中对定时器中断次数进行计数,每计 数100次进行一次事件处理,则可实现1s的定时效果。
39
2、定时量程的扩展 (2)硬件扩展方法 硬件扩展方法可以使用外接通用定时器芯片对单片 机的定时能力进行扩展。
也可以利用单片机自身的资源对定时能力进行扩展。 例如, 将两个定时器串联起来使用 (一个用于定时方 式, 另一个用于计数方式, 请分析其最大定时时间)。 当系统时钟频率为6MHz,12分频时: 16位定时器最大定时能力为: T = ms 两个串联最大定时时间: T = 216 × ms ≈ s 由于该扩展方法占用较多的资源,较少采用。
40
7.1.5 定时/计数器编程举例 定时/计数器的应用若用中断方式, 编程需考虑两点: 正确初始化: 包括写入控制字, 时间常数计算并装入;
定时/计数器编程举例 定时/计数器的应用若用中断方式, 编程需考虑两点: 正确初始化: 包括写入控制字, 时间常数计算并装入; 中断服务程序的编写: 编写需定时完成的任务代码。 在定时/计数器初始化部分的一般步骤大致如下: 设置工作方式,将控制字写入TMOD寄存器 (对T0和 T1)或AUXR(对T2)。(注意TMOD不能进行位寻址)。 设置分频方式,将控制字写入AUXR寄存器。默认的 情况是12分频(兼容传统8051单片机),如使用传统 8051单片机模式,无需设置。 T2固定为16位自动重装载模式, 只设置定时/计数和分频。
41
在定时/计数器初始化部分的一般步骤大致:
计算定时/计数初值, 并将其装入TLx、THx寄存器 (对于T0和T1), 或T2L、T2H寄存器(对于T2)。 置位ETx和EA允许定时/计数器中断(若需要)。 置位TRx (对于T0和T1) 或T2R (对于T2) 以启动定 时/计数。 在中断服务程序中, 要注意计数初值的重新装入问题。
42
7.1.5 定时/计数器编程举例 【例7-1】 设系统时钟频率为6MHz,利用T0定时,每 隔1s将P2.0的状态取反。 解:
定时/计数器编程举例 【例7-1】 设系统时钟频率为6MHz,利用T0定时,每 隔1s将P2.0的状态取反。 解: 所要求定时时间1s超过了定时器的定时能力 (时钟频 率为6MHz, 12分频时, 16位定时器的最长定时时间为 ms), 所以无法采用定时器直接实现1s定时。 将定时器定时时间设为50ms, 在中断服务程序中对 定时器溢出中断请求进行计数, 当计够20次时, 将 P2.0状态取反, 否则返回主程序, 从而达到1s定时。
43
【例7-1】每隔1s将P2.0的状态取反 选择T0为16位定时器方式, 方式字为01H。系统时钟频 率为6MHz, 12分频时, 计数单位时间间隔为2μs。T0的 计数初值为: 计数次数 →TH0,TL0 汇编程序: $INCLUDE (STC15.INC) ;包含STC15F2k寄存器定义文件 ORG H LJMP MAIN ;转主程序 ORG BH ;T0中断服务程序入口地址 LJMP T0_ISR ORG H MAIN: MOV SP, #7F60H ;设置堆栈指针 MOV TMOD, #01H ;T0初始化, 方式1, 16位定时器方式
44
MOV TL0, #58H ;计数初值9E58H MOV TH0, #9EH ; 装入时间常数 MOV A, #20 ; A置初值20, 计数定时中断次数 SETB ET0 ;允外T0中断 SETB EA ;CPU开中断 SETB TR0 ;启动T0计数 SJMP $ ;等待 【例7-1】 头文件有定义: ET0 BIT 0A9H EA BIT 0AFH TR0 BIT 8CH T0_ISR:MOV TL0, #58H ; MOV TH0, #9EH ;需重新装入时间常数 DEC A ; 累加器A内容减1 JNZ EXIT CPL P ;计时1s到, 将P2.0的状态取反 MOV A, # ;累加器A重载20 EXIT: RETI END 对16位定时器方式(方式1) T0中断服务程序入口 头文件有定义: P2 DATA 0A0H ; P2.0(或P2^0)可直接用, C语言不能直接用
45
【例7-1】每隔1s将P2.0的状态取反。C语言程序:
#include “stc15.h” //包含STC15F2k60S2寄存器定义文件 sbit P20=P2^0; //声明P2.0的引脚位变量, 不能直接用P2^0 unsigned char i; //声明计数变量。C程序中尽量不要用ACC void main (void) { //SP=0x60; //用C语言设计程序,可不设置堆栈指针 TMOD=0x01; TL0=0x58; TH0=0x9E; i=20; //定时中断次数计数变量赋初值, 中服中减一计数 ET0=1; //允许T0中断 EA = 1; //开放总的中断 TR0=1; //启动T0计数 while(1); //等待中断 } 头文件有定义: sfr P2 0xA0; 头文件有定义: sfr TMOD=0x89; sfr TL0=0x8A; sfr TH0=0x8C; 头文件有定义: sbit ET0=IE^1 sbit EA=IE^7 sbit TR0=TCON^4
46
【例7-1】每隔1s将P2.0的状态取反。C语言程序:
void T0_ISR (void) interrupt 1 //定时器T0中断服务函 数 { TL0=0x58; //重新装入时间常数 TH0=0x9E; i--; //定时中断次数计数变量(初值20)减1 if(i==0) { //若减到0,则将P2.0取反 P20 = !P20; //将P2.0取反, 不能直接用P2^0 (P2.0) i = 20; //重新给计数变量赋值 }
47
【例7-1】每隔1s将P2.0的状态取反。 若用工作方式0 (16位自动装载), 则上述程序除将 TMOD值设置为0外, 中断服务程序中, 不需重新装入时 间常数, 即: 汇编语言程序中断服务程序中可省去下面两句: MOV TL0, #58H MOV TH0, #9EH ;重新装入时间常数 在C语言程序的中断服务程序中可省去下面两句: TL0=0x58; TH0=0x9E; //重新装入时间常数 其他部分的程序不变。 对于1T模式的使用,请读者自行实验学习。 思考: 若晶振频率改为 MHz, 时间常数应为多少?
48
[例7-1] 设时钟频率11.0592MHz,利用T0定时,每隔1s将P2.0的状态取反。
时间常数应为多少? 1s定时时间超过了定时器的定时能力 (时钟频率为 MHz, 12分频时, 16位定时器的最长定时时间为 ms), 所以无法采用定时器直接实现1s定时。 将定时器定时时间设为50ms, 在中断服务程序中对定 时器溢出中断请求进行计数, 当计够20次时, 将P2.0状 态取反, 否则返回主程序, 从而达到1s定时。 T0的计数初值为: 计数次数
49
[例7-2]设时钟频率18.432MHz, 用定时器2定时, 使P0.0口输出38.4KHZ方波。
←1/38400/2 12分频用12, 不分频时用1 汇编代码如下: ←12/ $INCLUDE (STC15.INC) ;包含寄存器定义文件 ;定义38.4KHz时的时间常数 ( /12/38400/2) T38_4KHz EQU 0FFECH TEST_PIN BIT P ;测试引脚定义 ORG 0000H LJMP MAIN ORG 0063H ;定时器2的中断服务程序入口地址 LJMP T2_ISR 计数初值 20 注意: 这里的时间常数是按对时钟频率进行12分频后计算出的
50
[例7-2]用定时器2定时,使P0.0口输出38.4KHZ方波
MAIN: MOV SP, #70H ;设置堆栈指针 ;ORL AUXR, #04H;设置T2为1T不分频 MOV T2H, #HIGH T38_4KHz ;设置定时器2重装载时间常数高字节 MOV T2L, #LOW T38_4KHz ;设置定时器2重装载时间常数低字节 ORL AUXR, #10 H ; ORL IE2, #04H ;允许定时器2中断 SETB EA ;开放CPU中断 SJMP $ ;定时器2中断服务程序 T2_ISR: CPL TEST_PIN ;TEST_PIN引脚定义为P0.0 RETI END AUXR.2=T2x12=1是不分频,按要求应为0, HIGH运算符取16位数的高字节 Ax51 User's Guide → Writing Assembly Programs→ Expressions and Operators→ Operators LOW取低字节 AUXR.4=T2R=1启动定时器2 中断中不需重新装载定时器2时间常数
51
[例7-2]定时在P0.0输出38.4KHZ方波,C语言代码如下:
#include “stc15.h” //包含STC15F2K寄存器定义文件 #define FOSC L //定义长整型(L)时间常数 #define T38_4KHz ( /12/38400/2) //38.4KHz sbit TEST_PIN = P0^0; //定义测试引脚 void main(void) { // AUXR|= 0x04; //设置T2为1T模式, 应设置为12分频 T2H = T38_4KHz>>8; //设置T2重装时间常数高字节 T2L = T38_4KHz; //设置T2重装时间常数低字节 AUXR |= 0x10; //启动定时器2 IE2 |= 0x04; //允许定时器2中断 EA = 1; //开放CPU中断 while (1); //循环等待中断 } 注意: 这里的时间常数是按对时钟频率进行12分频后计算出的
52
[例7-2]用定时使P0.0输出方波,C语言代码如下:
//定时器2中断服务函数 void t2_isr(void) interrupt 12 { TEST_PIN = ~TEST_PIN; //定时时间到即将P0.0引脚状态取反, 从而在P0.0输出38.4KHZ方波 }
53
7.1.5 定时/计数器编程举例 [例7-3] 利用定时器的门控方式实现正脉冲的脉宽测量。
定时/计数器编程举例 [例7-3] 利用定时器的门控方式实现正脉冲的脉宽测量。 当GATE=1, TRx=1, 只有引脚INTx输入高电平时, Tx 才被允许计数, 利用这一特点, 就可以测量引脚INTx上 正脉冲的宽度。 Tx的启动(1)信号 以T0为例的门控法测 量示意图如下图所示。 x=0, 1 INT0 x=0 引脚P3.2/INT0 图7-7 利用门控法测量脉冲宽度
54
[例7-3] 利用定时器的门控方式实现正脉冲的脉宽测量。
解:以T0为例,下面给出实现这一方法的关键代码: $INCLUDE (STC15.INC) ;包含寄存器定义文件 MOV TMOD, #09H ;T0工作于16位定时方式,GATE=1 MOV TL0,#00H ;计数初值0H MOV TH0,#00H CLR EX0 ;关外部中断 JNB P3.2, $ ;等待引脚P3.2/INT0升高(设初始为低电平) SETB TR0 ; 启动定时器T0 JB P3.2, $ ;等待引脚P3.2/INT0下降 CLR TR0 ;关定时器T0 MOV A, TL0 ;T0内容高8位送B,低8位送A MOV B, TH0 …… ;计算脉宽或送显示器显示
55
[例7-3] 利用定时器的门控方式实现正脉冲的脉宽测量。
思考: (1)当脉冲宽度超过定时器的最大定时时间应该如何 处理? (2)在动态读取运行中的定时/计数器的计数值时,如 果不加注意,就可能出错。这是因为不可能在同一时 刻同时读取TH0和TL0中的计数值。比如,先读TL0 后读TH0,因为定时/计数器处于运行状态,在读TL0 时尚未产生向TH0进位,而在读TH0前已产生进位, 这时读得的TH0就不对了;同样,先读TH0后读TL0 也可能出错。如何解决这个问题? 加定时中断 CLR TR0 ;关定时器T0
56
§7.2可编程时钟输出模块及其应用 在控制系统中, 有时需要为单片机外部的器件提供时 钟控制, 为此, STC15F2K60S2单片机提供了4路可编程 时钟输出功能。 MCLKO/P5.4, T0CLKO/P3.5, T1CLKO/P3.4, T2CLKO/P3.0。 因IO口输出频率最高不超过13.5MHz, 所以5V芯片对 外可编程时钟输出速度最快也不超过13.5MHz (对3.3V 芯片是8MHz)。
57
7.2.1 可编程时钟输出的相关寄存器 1、主时钟输出 主时钟可以是内部高精度R/C时钟,也可以是外部输 入的时钟或外部晶体振荡产生的时钟。
通过设置CLK_DIV寄存器的MCKO_S1和MCKO_S0 两位, 可将MCLKO/P5.4 管脚配置为主时钟输出,同 时,还可设置输 出频率。 时钟分频寄存器CLK_DIV(也称为PCON2, 地址为97H, 复位值为0000 x000B) 的各位定义如下: 位号 D7 D6 D5 D4 D3 D2 D1 D0 名称 MCKO_S1 MCKO_S0 ADRJ TX_RX - CLKS2 CLKS1 CLKS0
58
1、主时钟输出 时钟分频寄存器CLK_DIV 主时钟的输出频率由MCKO_S1和MCKO_S0控制。 表7-2 主时钟的输出频率设置
位号 D7 D6 D5 D4 D3 D2 D1 D0 名称 MCKO_S1 MCKO_S0 ADRJ TX_RX - CLKS2 CLKS1 CLKS0 主时钟的输出频率由MCKO_S1和MCKO_S0控制。 表7-2 主时钟的输出频率设置 MCKO_S1 MCKO_S0 MCLKO/P5.4主时钟的输出频率 无主时钟输出 1 主时钟输出频率= MCLK/1 主时钟输出频率= MCLK/2 主时钟输出频率= MCLK/4 其中, MCLK指主时钟频率:可以是内部高精度R/C时钟, 也可以是外部输入的时钟或外部晶体振荡产生的时钟。 5V芯片对外可编程时钟输出速度最快不超过13.5MHz
59
时钟分频寄存器CLK_DIV (PCON2)
表11-4 分频系数选择 位号 D7 D6 D5 D4 D3 D2 D1 D0 名称 MCKO_S1 MCKO_S0 ADRJ Tx_Rx - CLKS2 CLKS1 CLKS0 CLKS2, CLKS1,CLKS0: 设置分频系数,如表11-4所示。 CLKS2 CLKS1 CLKS0 分频后CPU实际工作时钟(系统时钟) 主时钟频率/1,不分频 1 主时钟频率/2 主时钟频率/4 主时钟频率/8 主时钟频率/16 主时钟频率/32 主时钟频率/64 主时钟频率/128
60
2. T2CLKO/P3.0, T1CLKO/P3.4和T0CLKO/P3.5的时钟输出
T2CLKO/P3.0, T1CLKOU/P3.4和T0CLKOU/P3.5时钟 输出由外部中断使能和时钟输出寄存器INT_CLKO (也 称AUXR2)的T2CLKO、T1CLKO和T0CLKO控制。 T0CLKO/P3.5的输出时钟频率由定时器0控制, T1CLKO/P3.4的输出时钟频率由定时器1控制, T2CLKO/P3.0的输出时钟频率由定时器2控制 定时器需要工作在定时器方式0 (16位自动重装模式)或 方式2 (8位自动重装载模式), 不允许定时器中断, 以免 CPU反复进中断, 影响时钟精确度。 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 - EX4 EX3 EX2 LVD_WAKE T2CLKO T1CLKO T0CLKO
61
2. T2CLKO/P3.0, T1CLKO/P3.4和T0CLKO/P3.5的时钟输出
外部中断使能和时钟输出寄存器INT_CLKO (地址为 8FH,复位值为X B)各 位的定义如下: 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 - EX4 EX3 EX2 LVD_WAKE T2CLKO T1CLKO T0CLKO 1) T2CLKO: 是否将P3.0脚设置为定时器2 (T2) 的时钟输 出引脚T2CLKO。 T2CLKO=0 , 不允许将P3.0引脚设置为T2的时钟输出 T2CLKO=1: 设置P3.0为T2的时钟输出引脚T2CLKO 输出频率=T2溢出率/2
62
1) T2CLKO/P3.0 的时钟输出 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 - EX4 EX3 EX2 LVD_WAKE T2CLKO T1CLKO T0CLKO T2CLKO=1: 设置P3.0为T2的时钟输出引脚T2CLKO 输出频率=T2溢出率/2 若T2_C/T=0, T2对内部系统时钟计数, 则: 1T输出频率=(SYSclk)/(65536-[RL_TH2, RL_TL2])/2 12T输出频率=(SYSclk)/12/(65536-[RL_TH2, RL_TL2])/2 若T2_C/T=1, T2对外部脉冲输入(P3.1/T2)计数, 则 输出频率= (T2_Pin_CLK)/(65536-[RL_TH2, RL_TL2])/2
63
2) T1CLKO: 是否将P3.4/T0脚配置为T1的时钟输出
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 - EX4 EX3 EX2 LVD_WAKE T2CLKO T1CLKO T0CLKO T1CLKO设置T1时钟输出引脚T1CLKO, 设置方法与T2 类似。 T1CLKO=1: 设置P3.4为T1的时钟输出引脚T1CLKO 输出频率=T1溢出率/2 定时器T1工作在定时器模式0 (16位自动重装模式)时: 若C/T=0, T1对内部系统时钟计数, 则: 1T输出频率=(SYSclk)/(65536-[RL_TH2, RL_TL2])/2 12T输出频率=(SYSclk)/12/(65536-[RL_TH2, RL_TL2])/2 若C/T=1, T1对外部脉冲输入(P3.5/T1)计数, 则 输出频率= (T1_Pin_CLK)/(65536-[RL_TH2, RL_TL2])/2
64
2) T1CLKO: 是否将P3.4/T0脚配置为T1的时钟输出
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 - EX4 EX3 EX2 LVD_WAKE T2CLKO T1CLKO T0CLKO T1CLKO=1: 设置P3.4为T1的时钟输出引脚T1CLKO 输出频率=T1溢出率/2 定时器T1工作在模式2 (8位自动重装模式)时: 若C/T=0, T1对内部系统时钟计数, 则: 1T模式时的输出频率=(SYSclk)/(256 - TH1)/2 12T模式时的输出频率=(SYSclk)/12/(256 - TH1)/2 若C/T=1, T1对外部脉冲输入(P3.5/T1)计数, 则 输出时钟频率= (T1_Pin_CLK)/(256 - TH1)/2 T1CLKO=0, 不允许将P3.4配置为定时器1的时钟输出。
65
3) T0CLKO: 是否将P3.5/T1脚配置为T0的时钟输出
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 - EX4 EX3 EX2 LVD_WAKE T2CLKO T1CLKO T0CLKO T0CLKO设置T0时钟输出引脚T0CLKO, 设置方法与T1 类似。 T0CLKO=1: 设置P3.5为T0的时钟输出引脚T0CLKO 输出频率=T0溢出率/2 定时器T0工作在定时器模式0 (16位自动重装模式)时: 若C/T=0, T0对内部系统时钟计数, 则: 1T输出频率=(SYSclk)/(65536-[RL_TH2, RL_TL2])/2 12T输出频率=(SYSclk)/12/(65536-[RL_TH2, RL_TL2])/2 若C/T=1, T0对外部脉冲输入(P3.4/T0)计数, 则 输出频率= (T0_Pin_CLK)/(65536-[RL_TH2, RL_TL2])/2
66
3) T0CLKO: 是否将P3.5/T1脚配置为T0的时钟输出
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 - EX4 EX3 EX2 LVD_WAKE T2CLKO T1CLKO T0CLKO T0CLKO=1: 设置P3.5为T0的时钟输出引脚T0CLKO 输出频率=T0溢出率/2 定时器T0工作在模式2 (8位自动重装模式)时: 若C/T=0, T0对内部系统时钟计数, 则: 1T模式时的输出频率=(SYSclk)/(256 - TH1)/2 12T模式时的输出频率=(SYSclk)/12/(256 - TH1)/2 若C/T=1, T0对外部脉冲输入(P3.4/T0)计数, 则 输出时钟频率= (T0_Pin_CLK)/(256 - TH1)/2 T0CLKO=0, 不允许将P3.5配置为定时器0的时钟输出。
67
7.2.2 可编程时钟输出的编程实例 1、若要使用主时钟输出, 例, 从P5.4/MCLKO输出时钟信 号, 频率是SYSclk (系统时钟), 只需加入下面语句即可: MOV CLK_DIV, #40H ;汇编语言程序设置CLK_DIV CLK_DIV = 0x40; //在C语言程序中 当CLK_DIV=40H时, SYSclk (系统时钟)就是主时钟, 也是输出时钟。 2、若要从T0CLKO/P3.5引脚输出时钟, 程序中需设置: 设置定时器0的工作方式为方式0或方式2 (将TMOD低 4位设为0或者2); 设置16位或8位重装载值(分别设置TL0和TH0); 启动定时器0工作(将TCON的TR0设置为1); 对INT_CLKO寄存器中的T0CLKO位置1, 让定时器0 的溢出在P3.5引脚输出时钟。
68
7.2.2 可编程时钟输出的编程实例 3、如果需要从T1CLKO/P3.4引脚输出时钟,需要在 用户程序中进行下面的设置:
设置定时器1的工作方式为方式0或方式2(将TMOD 的高4位设为0或2); 设置16位或8位重装载值(分别设置TL1和TH1); 启动定时器1工作(将TCON的TR1设置为1); 对 INT_CLKO寄存器中的T1CLKO位置1,让定时 器1的溢出在P3.4引脚输出时钟。
69
7.2.2 可编程时钟输出的编程实例 4、如果需要从T2CLKO/P3.0引脚输出时钟,需要在 用户程序中进行下面的设置:
设置16位重装载值(分别设置T2H和T2L); 对AUXR寄存器中的T2R位置1,T2_C/T清零,让定 时器2运行; 对 INT_CLKO寄存器中的T2CLKO位置1, 让定时器 2的溢出在P3.0引脚输出时钟。 T2只有16位重装载方式, 无需设置方式。
70
7.2.2 可编程时钟输出的编程实例 下面以一个具体实例,说明如何使用STC15F2K60S2单 片机的可编程时钟输出功能。 【例7-4】 设时钟频率SYSclk=18.432MHz, 设计程序, 从 T0 (P3.4/T1CLKO)引脚输出频率为125KHz的时钟; 从 T1 (P3.5/T0CLKO)引脚输出频率为38.4KHz的时钟。 解: 使用STC15F2K60S2的可编程时钟输出功能完成所 需要求。在下面的程序设计中 (C语言程序),T0和T1 均工作在1T模式。
71
例7-4 时钟18.432MHz, T0脚输出125KHz; T1 输出38.4KHz
#include "stc15.h" //包含STC15F2K60S2寄存器定义头文件 void main(void) { TMOD = 0x22; //T0,T1工作方式2, 8位自动重装计数器 AUXR = AUXR | 0x80; //T0工作在1T模式 AUXR = AUXR | 0x40; //T1工作在1T模式 //置T01的8位自动重装计数初值,输出频率= /2/74≈125KHz TH01 = (256-74); TL01 = (256-74); //置T10的8位自动重装计数初值,输出 /2/240 = 38400Hz TH10 = ( ); TL10 = ( ); TR0 = 1; //启动T0计数, 对系统时钟进行分频输出 TR1 = 1; //启动T1计数, 对系统时钟进行分频输出 INT_CLKO =INT_CLKO|0x03; //允许时钟输出 //至此时钟已经输出, 可通过示波器看到输出时钟频率 while(1); } 例7-4 时钟18.432MHz, T0脚输出125KHz; T1 输出38.4KHz T0 (P3.4/T1CLKO)输出125KHz; T1 (P3.5/T0CLKO) 输出38.4KHz。
72
【例7-5】设时钟频率为18.432MHz,使用定时器2的时钟输出功能,使P3.0口输出38.4KHZ的方波。
$INCLUDE (STC15.INC) ;STC15F2K60S2寄存器定义文件 T38_4KHz EQU 0FFECH ;( / 12/38400/2) ;( )=65516= 0FFECH ;12T模式下的重装时间常数 T2CLKO BIT P3.0 ;定义时钟输出引脚 ORG 0000H LJMP MAIN MAIN:MOV SP, #70H MOV T2H, #HIGH T38_4KHz ;T2时间常数高字节 MOV T2L, #LOW T38_4KHz ;T2时间常数低字节 MOV AUXR, #10H ;启动T2 ORL INT_CLKO, #04H ;允许T2时钟输出功能 SJMP $ END 20 Ax51 Assembler User's Guide → Writing Assembly Programs→ Expressions and Operators→ Operators
73
【例7-5】对应的C语言代码如下: #include "stc15.h" //包含STC15F2K60S2寄存器定义头文件 #define FOSC L //定义长整型(L)时间常数 #define T38_4KHz ( /12/38400/2) //输出38.4KHZ方波的的计数初值 sbit T2CLKO = P3^0; //时钟输出引脚 void main(void) { T2H= T38_4KHz>>8; //设置T2重装时间常数高字节 T2L = T38_4KHz; //设置T2重装时间常数低字节 AUXR = 0x10; //启动定时器T2 INT_CLKO |= 0x04; //允许T2时钟输出 while (1); //循环 }
74
§7.3可编程计数器阵列模块及其应用 STC15F2K60S2单片机集成了三路可编程计数器阵列 (PCA)模块。可用于软件定时器、外部脉冲的捕捉、 高速输出以及脉宽调制(PWM)输出。 PCA模块的结构 PCA模块含有一个特殊的16位定时器,有3个16位的 捕获/比较模块与之相连。如图所示。 CCP0/P1.1 CCP1/P1.0 CCP2/P3.7 图7-8 PCA模块结构
75
7.3.1 PCA模块的结构 模块0连接到P1.1/CCP0; 模块1连接到P1.0/CCP1; 模块2连接到P3.7/CCP2
上述CCP模块可通过AUXR1中的CCP_S0和CCP_S1 切换到其他引脚(参见表3-910)。 每个模块可编程工作在4种模式:上升/下降沿捕获、 软件定时器、高速输出或可调制脉冲输出。 (见7.3.3) CCP0/P1.1 CCP1/P1.0 CCP2/P3.7 图7-8 PCA模块结构
76
7.3.1 PCA模块的结构 16位PCA定时器/计数器是3个模块的公共时间基准。 PCA运行控制位 图7-9 PCA定时器/计数器结构
CIDL=0,空闲时PCA工作 PCA运行控制位 图7-9 PCA定时器/计数器结构
77
7.3.1 PCA模块的结构 PCA定时器/计数器结构图说明 寄存器CH和CL的内容是自动递增计数的16位PCA 定时器的值。
PCA定时器的时钟源有以下几种:1/12振荡频率、 1/8振荡频率、1/6振荡频率、1/4振荡频率、1/2振荡 频率、振荡频率、定时器0溢出或ECI脚输入 (P1.2) (CCP / PCA计数器的外部脉冲(时钟)输入脚)。 定时器的计数源可通过设置特殊功能寄存器CMOD 的CPS2、CPS1和CPS0位选择其中一种。
78
7.3.1 PCA模块的结构 PCA定时器/计数器结构图说明 CMOD中的CIDL位用于控制空闲模式下是否允许停 止PCA;
CIDL=0时, 空闲模式下PCA计数器继续计数; CIDL=1时, 空闲模式下PCA计数器停止计数。 CMOD中的ECF位用于中断控制,置位时,使能 PCA中断。 当PCA定时器溢出时,PCA计数溢出标志CF置位。 CCON中的CR位是PCA的运行控制位。CR=1时, 运行PCA。CR=0时,关闭PCA。
79
7.3.1 PCA模块的结构 PCA定时器/计数器结构图说明
CCON中还包括PCA定时器标志(CF)以及各个模块的 标志 (CCF2/CCF1/CCF0)。 当PCA计数器溢出时, CF位置位, 若CMOD寄存器的 ECF位置位, 就产生中断。CF位只能通过软件清0。 CCON寄存器中CCF0是PCA模块0的中断标志, CCF1 是模块1的标志, CCF2是模块2的标志。当发生匹配或 比较时由硬件置位。这些标志也只能通过软件清0。 所有模块共用一个中断向量,可以在中断服务程序中 判断CCF0, CCF1和CCF1,以确定到底是哪个模块产 生了中断。
80
PCA比较/捕获工作模式寄存器CCAPMn PCA模块PWM寄存器PCA_PWMn PCA的16位计数器--低8位CL和高8位CH
PCA工作模式寄存器(CMOD) PCA控制寄存器(CCON) PCA比较/捕获工作模式寄存器CCAPMn PCA模块PWM寄存器PCA_PWMn PCA的16位计数器--低8位CL和高8位CH PCA捕捉/比较寄存器CCAPnL, CCAPnH
81
7.3.2 PCA模块的特殊功能寄存器 1、PCA工作模式寄存器(CMOD)
CMOD(地址为D9H, 复位值为0XXX0000B)各位定义: 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 CIDL - CPS2 CPS1 CPS0 ECF 1)CIDL: 空闲模式下是否停止PCA计数的控制位。 CIDL=0时,空闲模式下PCA计数器继续计数; CIDL=1时,空闲模式下PCA计数器停止计数。 2)ECF: PCA计数器溢出中断使能位。 ECF=1时,允许寄存器CCON中CF位的中断。 ECF=0时,禁止寄存器CCON中CF位的中断。 3)CPS2, CPS1, CPS0: PCA计数脉冲源选择控制位。
82
3) CPS2,CPS1,CPS0: PCA计数脉冲源选择控制位。
1、PCA工作模式寄存器(CMOD) 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 CIDL - CPS2 CPS1 CPS0 ECF 3) CPS2,CPS1,CPS0: PCA计数脉冲源选择控制位。 表7-3 CPS2 CPS1 CPS0 PCA时钟源输入选择 SYSclk/12 1 SYSclk/2 定时器0溢出脉冲。由于定时器0可以工作在1T方式,所以可达到计一个时钟就溢出,从而达到最高频率CPU工作时钟SYSclk,通过改变定时器0的溢出率,可实现可调频率的PWM输出 ECI/P1.2 (P4.1或P2.4,或P3.4) 脚输入的外部时钟(最大速率= CPU工作时钟/2) SYSclk SYSclk/4 SYSclk/6 SYSclk/8
83
3)CPS2、CPS1、CPS0:PCA计数脉冲源选择控制位。
1、PCA工作模式寄存器(CMOD) 3)CPS2、CPS1、CPS0:PCA计数脉冲源选择控制位。 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 CIDL - CPS2 CPS1 CPS0 ECF 例如,CPS2/CPS1/CPS0=(100) 2时,PCA/PWM的时 钟源是SYSclk。 若要用SYSclk/3作为PCA 时钟源, 应让T0工作在1T 模式,计数3个脉冲即产生溢出。用T0的溢出可对系统 时钟进行1~256级分频(T0工作方式2: 8位自重装方式), CPS2/CPS1/CPS0=(010) 2 。
84
7.3.2 PCA模块的特殊功能寄存器 2、PCA控制寄存器(CCON) CCON(地址为D8H,复位值为00XXXX00B) 位号 D7
位名称 CF CR - CCF2 CCF1 CCF0 1)CF:PCA计数器溢出标志位。 当PCA计数器溢出时, CF位由硬件置位。若CMOD寄 存器的ECF位置位, CF标志可用来产生中断。CF位可 通过硬件或软件置位,但只能通过软件清0。
85
2、PCA控制寄存器(CCON) 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 CF CR - CCF2 CCF1 CCF0
2)CR:PCA计数器的运行控制位。 置位CR位时,启动PCA计数器计数; 清零CR位时,关闭PCA计数器。 3)CCF2/CCF1/CCF0:PCA模块的中断标志位(CCF0 对应模块0, CCF1对应模块1 , CCF2对应模块2 )。 当发生匹配或捕获时由硬件置位。这些标志位必须 通过软件清0。
86
7.3.2 PCA模块的特殊功能寄存器 3、PCA模块工作模式寄存器CCAPMn( n=0,1, 2 )
地址分别为DAH, DBH和DCH, 复位值均为x B 位号 D7 D6 D5 D4 D3 D2 D1 D0 名称 - ECOMn CAPPn CAPNn MATn TOGn PWMn ECCFn 1)ECOMn:允许比较器功能控制位。 ECOMn=1时,允许比较器功能。 2)CAPPn:正捕获控制位。 CAPPn=1时,允许上升沿捕获。 3)CAPNn:负捕获控制位。 CAPNn=1时, 允许下降沿捕获。若CAPPn=1, 同时 CAPNn=1, 则允许上升沿和下降沿都捕获。
87
3、PCA模块工作模式寄存器CCAPMn(n=0,1, 2)
位号 D7 D6 D5 D4 D3 D2 D1 D0 名称 - ECOMn CAPPn CAPNn MATn TOGn PWMn ECCFn 4)MATn:匹配控制位。 若MATn=1, 则PCA计数值与模块的比较/捕获寄存器的 值匹配时, 将置位CCON寄存器的中断标志位CCFn。 5)TOGn:翻转控制位。 当TOGn=1时, PCA工作于高速输出模式, PCA计数器值 与模块的比较/捕获寄存器值匹配时,使CCPn脚翻转。 6)PWMn:脉宽调制模式。 当PWMn=1时,CCPn脚用作脉宽调制输出。 7)ECCFn:使能CCFn中断。 寄存器CCON的比较/捕获标志CCFn用来产生中断。
88
7.3.2 PCA模块的特殊功能寄存器 4、PCA模块PWM寄存器PCA_PWMn(n=0,1,2)
地址分别为F2H、F3H和F4H,复位值均为xxxx xx00B 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 EBSn_1 EBSn_0 - EPCnH EPCnL 1)EBSn_1, EBSn_0: PCA模块n在PWM模式的功能选择位。 0 0: PCA模块n工作于8位PWM功能; 0 1: PCA模块n工作于7位PWM功能; 1 0:PCA模块n工作于6位PWM功能; 1 1:无效,PCA模块n仍工作于8位PWM模式。
89
7.3.2 PCA模块的特殊功能寄存器 4、PCA模块PWM寄存器PCA_PWMn(n=0,1,2)
地址分别为F2H、F3H和F4H,复位值均为xxxx xx00B 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 EBSn_1 EBSn_0 - EPCnH EPCnL 1)EBSn_1, EBSn_0: PCA模块n在PWM模式的功能选择位。 0 0: PCA模块n工作于8位PWM功能; 0 1: PCA模块n工作于7位PWM功能; 1 0:PCA模块n工作于6位PWM功能; 1 1:无效,PCA模块n仍工作于8位PWM模式。 PCA_PWMn
90
7.3.2 PCA模块的特殊功能寄存器 4、PCA模块PWM寄存器PCA_PWMn(n=0,1,2) 位号 D7 D6 D5 D4 D3
位名称 EBSn_1 EBSn_0 - EPCnH EPCnL 2)EPCnH:在PWM模式下与CCAPnH组成9位数。 3)EPCnL:在PWM模式下与CCAPnL组成9位数。 5、PCA的16位计数器--低8位CL和高8位CH (地址分别为E9H和F9H, 复位值均为00H)。它们用于 保存PCA的装载值。
91
7.3.2 PCA模块的特殊功能寄存器 6、PCA捕捉/比较寄存器——CCAPnL(低位字节)和 CCAPnH(高位字节)
PCA模块当用于捕获或比较时, 它们保存各模块的16位 捕捉计数值; 当用于PWM模式时,它们控制输出占空比。 其中, n=0, 1, 2, 分别对应模块0和模块1和模块2。 复位值均为00H。它们对应地址分别为: 模块0捕捉/比较寄存器: CCAP0L—EAH, CCAP0H—FAH 模块1捕捉/比较寄存器: CCAP1L—EBH、CCAP1H—FBH 模块2捕捉/比较寄存器: CCAP2L—ECH、CCAP2H—FCH:
92
PCA模块的工作模式 PCA每个模块可编程工作在4种模式: 捕获模式: 用捕获模式可测量脉冲宽度 16位软件定时器模式 高速脉冲输出模式 脉宽调节模式
93
7.3.3 PCA模块的工作模式 1、捕获模式 PCA模块工作于捕获模式的结构图如图7-10所示。 用捕获模式可测量脉冲宽度 引脚
(CCP0/P1.1, CCP1/P1.0, CCP2/P3.7) 至少有一位须置1 ECCFn 图7-10 PCA模块捕获模式结构图
94
PCA模块的工作模式 说明 要使PCA 模块工作在捕获模式,寄存器CCAPMn的两位 (CAPNn和CAPPn)中至少有一位必须置1。 PCA模块工作于捕获模式时,对外部输入CCPn引脚的 跳变进行采样。 当采样到有效跳变时,PCA硬件将PCA计数器阵列寄存 器( CH和CL )的值装载到模块的捕获寄存器(CCAPnH 和CCAPnL)中。 如果CCON中的CCFn位和CCAPMn中的ECCFn位被置位, 将产生中断。可在中断服务程序中判断是哪一个模块 产生了中断,并注意中断标志位的软件清0问题。
95
图7-11 PCA模块的16位软件定时器模式/PCA比较模式结构
2、16位软件定时器模式 16位软件定时器模式的结构图如图7-11所示。 ECOMn=0,停止比较 ECOMn=1,恢复比较 图7-11 PCA模块的16位软件定时器模式/PCA比较模式结构
96
2、16位软件定时器模式: 说明 置位寄存器CCAPMn的ECOMn和MATn位, 可使 PCA模块用作软件定时器。
2、16位软件定时器模式: 说明 置位寄存器CCAPMn的ECOMn和MATn位, 可使 PCA模块用作软件定时器。 PCA定时器的值与模块捕获寄存器的值相比较, 当二 者相等时, 若CCFn位和ECCFn位都置位, 将产生中断。 [CH, CL]每隔一定时间自动加1, 时间间隔取决于选择 的时钟源。 例, 当时钟源为FOSC/12时, 每12个时钟[CH, CL]加1。 当[CH, CL]增加到等于[CCAPnH, CCAPnL]时, 置 CCFn=1, 产生中断请求。
97
2、16位软件定时器模式: 说明 若每次PCA模块中断后, 在中断服务程序中给[CCAPnH, CCAPnL]增加一个相同值, 则下次中断来临的时间间隔 T也相同, 从而实现了软件定时功能。 定时时间长短, 取决于时钟源选择及PCA计数器计数值: 假设时钟频率SYSclk = MHz, 选择的时钟源为 SYSclk/12, 定时时间T为5ms, 则PCA计数器计数值为: T/((1/SYSclk)×12 )= 0.005/ ( (1/ )×12 ) = 7680 = 1E00H 即, PCA 计数器计数1E00H次, 定时时间是5ms。这也就 是每次给[CCAPnH, CCAPnL]增加的数值(步长)。
98
7.3.3 PCA模块的工作模式 3、高速脉冲输出模式 需在中断服务程序中修改CCAPnH, CCAPnL
高速输出模式结构图如图7-12所示。 需在中断服务程序中修改CCAPnH, CCAPnL ECOMn=0,停止比较 ECOMn=1,恢复比较 图7-12 PCA模块的高速输出模式结构图
99
3、高速脉冲输出模式 说明 该模式中,当PCA计数器的计数值与模块捕获寄存器 的值相匹配时,PCA模块的输出CCPn将发生翻转。
3、高速脉冲输出模式 说明 该模式中,当PCA计数器的计数值与模块捕获寄存器 的值相匹配时,PCA模块的输出CCPn将发生翻转。 要激活高速输出模式,CCAPMn寄存器的TOGn, MATn和ECOMn位必须都置位。 CCAPnL中的值决定了PCA模块n输出脉冲的频率?。 当PCA时钟源是SYSclk/2时,输出脉冲的频率f为: f = SYSclk / (4×CCAPnL) ,其中,SYSclk为系统时 钟频率。由此,可以得到CCAPnL的值为: CCAPnL = SYSclk / (4×f) 注:若在中断服务程序中CH/CL连续计数, CCAPnH/CCAPnL需加上递增步长(即上面计算出的CCAPnL), 若在中断服务程序中CCAPnH=0, CCAPnL保持不变, 则CH/CL的值需清0(停止?),
100
PCA模块的工作模式 如果计算出的结果不是整数,则进行四舍五入取整, 即 CCAPnL =INT( SYSclk / (4×f) + 0.5)其中, INT( ) 为取整数运算, 直接去掉小数。 例如,假设SYSclk=20MHz,要求PCA高速脉冲输 出125KHz的方波,则CCAPnL中的值应为: CCAPnL = INT( /4/ ) = INT( ) = 40= 28H
101
PCA模块的工作模式 4、脉宽调节模式 脉宽调制(Pulse Width Modulation, PWM)是一种使用 程序来控制波形占空比、周期、相位波形的技术,在 三相电机驱动、D/A转换等场合有广泛的应用。 占空比是指高电平在一个周期之内所占的时间比率。 STC15F2K60S2单片机PCA模块可用程序设定各自寄 存器PCA_PWMn(n=0,1,2)中的位EBSn_1及EBSn_0, 使其工作于8位PWM或7位PWM或6位PWM模式。 所有PCA模块都可用作PWM输出,输出频率取决于 PCA定时器的时钟源。因所有模块共用PCA定时器, 所 以它们输出频率相同, 各模块的输出占空比独立变化。
102
4、脉宽调节模式 当某个I/O口作为PWM使用时,该口状态如表7-5所示。 表7-5 I/O口作为PWM使用时的状态 PWM之前的状态
弱上拉/准双向口 强推挽输出/强上拉输出,要加输出限流电阻1KΩ-10KΩ 强推挽输出/强上拉输出 仅为输入/高阻 PWM无效 开漏
103
4、脉宽调节模式 (1)8位脉宽调节模式(PWM)
当[EBSn_1, EBSn_0]=[0, 0]或[1, 1]时,PCA模块n工作 于8位PWM模式; 此时将{0,CL[7:0]}与捕获寄存器[EPCnL,CCAPnL[7:0]] 进行比较。 PCA模块PWM寄存器PCA_PWMn(n=0,1,2) 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 EBSn_1 EBSn_0 - EPCnH EPCnL
104
(1)8位脉宽调节模式(PWM) 8位PWM模式时的结构如图7-13所示。 图7-13 PCA模块的8位PWM输出模式结构图
105
(1)8位脉宽调节模式(PWM) 当PCA模块工作于8位PWM模式时,输出占空比与使 用的捕获寄存器{EPCnL, CCAPnL[7:0]}有关。 当{0, CL[7:0]} < {EPCnL, CCAPnL[7:0]}时, 输出为低; 当{0, CL[7:0]} ≥ {EPCnL,CCAPnL[7:0]}时,输出为高。 当CL值由FF变为00溢出时,{EPCnH, CCAPnH[7:0]} 内容装载到{EPCnL,CCAPnL[7:0]}中。 这样可实现无干扰地更新PWM。要使能PWM模式, 模块CCAPMn寄存器的PWMn和ECOMn位须置位。 位号 D7 D6 D5 D4 D3 D2 D1 D0 名称 - ECOMn CAPPn CAPNn MATn TOGn PWMn ECCFn
106
(1)8位脉宽调节模式(PWM) 当PWM是8位时: PCA时钟输入源有8种:
SYSclk/12, SYSclk /8, SYSclk /6, SYSclk /4, SYSclk /2, SYSclk, 定时器0的溢出, ECI/P1.2输入。 例如, 要求PWM输出频率38KHz, 选SYSclk为PCA时钟 输入源, 则输入源晶振频率SYSclk: SYSclk =38000×256= 若要实现可调频率的PWM输出, 可选定时器0的溢出或 ECI脚的输入作为PCA的时钟输入源。 当EPCnL=0且ECCAPnL=00H时,PWM固定输出高; 当EPCnL=1且CCAPnL=0FFH 时,PWM固定输出低。
107
(1)8位脉宽调节模式(PWM) PWM的典型应用是用于D/A输出, 应用电路如图所示。
R1, C1和R2, C2构成滤波电路, 对单片机输出PWM波 形进行平滑滤波, 从而在D/A输出端得到稳定的电压。 图7-14 PWM用于D/A时的典型电路
108
4、脉宽调节模式 (2)7位脉宽调节模式(PWM)
当[EBSn_1, EBSn_0]=[0, 1] 时,PCA模块n工作于7位 PWM模式; 此时将{0,CL[6:0]}与捕获寄存器[EPCnL,CCAPnL[6:0]] 进行比较, 寄存器CL中不用的位CL.7应被置为1 。 PCA模块PWM寄存器PCA_PWMn(n=0,1,2) 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 EBSn_1 EBSn_0 - EPCnH EPCnL
109
(2)7位脉宽调节模式(PWM) 7位PWM模式的结构如图所示。 图7-15 PCA模块的7位PWM输出模式结构图
110
(2)7位脉宽调节模式(PWM) 当PCA模块工作于7位PWM模式时,输出占空比与使 用的捕获寄存器{EPCnL, CCAPnL[6:0]}有关。 工作过程与8位PWM相似。 当PWM是7位时 PCA时钟输入源有8种: SYSclk/12, SYSclk /8, SYSclk /6, SYSclk /4, SYSclk /2, SYSclk, 定时器0的溢出, ECI/P1.2输入。
111
7.3.4 PCA模块的应用 与定时器使用方法类似, PCA模块应用编程主要有两点: 正确初始化,包括写入控制字、捕捉常数的设置等;
按任务要求编中断服务程序, 注意中断请求标志的清0。 PCA模块的初始化部分大致如下: 设置PCA模块工作方式(见表7-4), 控制字写入CMOD, CCON, CCAPMn和PCA_PWMn寄存器。 设置捕捉寄存器CCAPnL(低字节)和CCAPnH(高字节) 初值。 开放PCA中断, ECF/ECCF0/ECCF1/ECCF2按需置1, EA置1。 启动PCA 计数器(CH,CL)计数(使CR=1)。
112
7.3.4 PCA模块的应用 【例7-6】利用PCA模块扩展外部中断。
将P1.1/CCP0 (PCA模块0的外部输入)扩展为下降沿触 发的外部中断 将P1.0/CCP1(PCA模块1的外部输入)扩展为上升沿/下 降沿都可触发的外部中断 当P1.1/CCP0出现下降沿时产生中断,对 P1.5 取反; 当P1.0/CCP1出现下降沿或上升沿时都产生中断, 对 P1.6取反。 (P1.5和P1.6可连接LED指示灯指示状态。)
113
【例7-6】利用PCA模块扩展外部中断。 解:当PCA模块工作在捕获模式时,对外部输入CCPn 的跳变进行采样。
当采样到有效跳变, 硬件将PCA计数器阵列寄存器(CH 和CL)值装载到捕获寄存器(CCAPnH和CCAPnL)中。 若CCON中CCFn位和CCAPMn中ECCFn位被置位, 将 产生中断。由此, 可将PCA模块作为扩展外部中断使用。 按要求,设置控制字时,PCA模块0应设为下降沿捕获 (即CCAPMn中CAPP0=0且CAPN0=1), PCA模块1应设 为上升沿和下降沿都能捕获的方式(即CAPP1=1且 CAPN1=1)。
114
$INCLUDE (STC15.INC) ;包含STC15F2K寄存器定义文件 LED_PCA0 EQU P1.5
ORG H LJMP MAIN ;转主程序 ORG 003BH ;PCA中断 LJMP PCA_ISR ORG H MAIN:MOV SP, #70H ;初始化 PCA MOV CMOD, # B ;空闲模式停止PCA计数器工作 ;PCA时钟源SYSclk /12, 禁止PCA计数器溢出中断 MOV CCON, #00H ;PCA计数器溢出中断请求标志CF清0 ;CR=0,不许PCA计数器计数; PCA各模块中断请求标志位CCFn清0
115
【例7-6】利用PCA模块扩展外部中断 MOV CL, #00H ; PCA计数器清0 MOV CH, #00H MOV CCAPM0, #11H ;设置PCA模块0下降沿触发捕捉功能, ECCF0=1 MOV CCAPM1, #31H ;模块1上升/下降沿均触发捕捉功能, ECCF1=1 SETB EA ;开整个单片机所有中断共享的总中断控制位 SETB CR ;启动PCA计数器(CH,CL)计数 SJMP $ ;循环等待中断
116
【例7-6】利用PCA模块扩展外部中断 ; PCA中断服务程序 PCA_ISR: JNB CCF0, Not_PCA0 ;CCF0≠1,非PCA模块0中断 ;则直接去判是否为PCA模块1中断 ;下面是PCA模块0中断服务程序 CPL LED_PCA0 ;表示PCA模块0发生了一次中断 CLR CCF0 ;清PCA模块0中断标志 Not_PCA0: JNB CCF1, PCA_Exit ;CCF1≠1,非PCA模块1中断,退出 ;PCA模块1中断服务程序 CPL LED_PCA1 ; 表示PCA模块1发生了一次中断 CLR CCF1 ;清PCA模块1中断标志 PCA_Exit: RETI END
117
#include “stc15.h” //包含STC15F2K60S2寄存器定义文件 sbit LED_PCA0=P1^5; sbit LED_PCA1=P1^6; void main (void) { CMOD=0x80; //空闲模式下停止PCA 计数器工作 //PCA时钟源SYSclk /12, 禁止PCA 计数器溢出中断 CCON=0; //PCA计数器溢出中断请求标志位CF清0 //CR=0, 不许PCA计数器计数;PCA模块中断请求标志CCFn清0 CL=0; //PCA 计数器清0 CH=0; CCAPM0=0x11; //设置PCA模块0下降沿触发捕捉 CCAPM1=0x31; //设置PCA模块1上升/下降沿均触发捕捉 EA=1; //开放单片机所有中断共享的总中断控制位 CR=1; //启动 PCA 计数器(CH,CL)计数 while(1); //等待中断 } 【例7-6】利用PCA模块扩展外部中断 C语言程序
118
【例7-6】利用PCA模块扩展外部中断 void PCA_ISR(void) interrupt 7 //PCA中断服务程序 { if(CCF0) //PCA模块0中断服务程序 LED_PCA0=! LED_PCA0; //表示PCA模块0发生中断 CCF0=0; //清PCA模块0中断标志 } else if(CCF1) //PCA模块1中断服务程序 LED_PCA1=!LED_PCA1; //表示PCA模块1发生中断 CCF1=0; //清PCA模块1中断标志
119
【例7-7】利用PCA 模块做定时器使用。 利用PCA模块的软件定时功能,实现在P1.6输出脉冲 宽度为1s的方波。假设晶振频率SYSclk = MHz。 解: 选择PCA模块0实现定时功能。通过置位CCAPM0 寄存器的ECOM0位和MAT0位, 使PCA模块0工作于 软件定时器模式。 ECOMn=1, 允许比较器功能。 位号 D7 D6 D5 D4 D3 D2 D1 D0 名称 - ECOMn CAPPn CAPNn MATn TOGn PWMn ECCFn 若MATn=1, 则PCA计数值与模块的比较/捕获寄存器值 匹配时, 将置位CCON寄存器的中断标志位CCFn。 定时时间长短, 取决于时钟源及PCA计数器计数值设置。 高速脉冲输出模式和PWM模式的定时达不到1S要求
120
【例7-7】利用PCA 模块做定时器使用 时钟频率SYSclk=18.432MHz, 可选择PCA模块时钟源 SYSclk/12, 基本定时单位T为5ms, 对5ms计数200次, 即 可实现1s定时。 PCA计数值: 5*18432/12=1E00H, 在中 断服务程序中, 将该值赋给[CCAP0H, CCAP0L]。 $INCLUDE (STC15.inc) ;STC15F2K60S2寄存器定义文件 COUNTER EQU 30H ;声明一个计数器, 计数中断次数 LED_1s EQU P1.6 ORG H LJMP MAIN ;转主程序 ORG 003BH ;PCA中断入口地址 LJMP PCA_ISR ORG H MAIN: MOV SP, #70H MOV COUNTER, # ;置COUNTER计数器初值
121
MOV CMOD, #10000000B ;空闲模式停止PCA计数器 MOV CCON, #00H ; PCA计数器溢出中断标志CF清0
;选择PCA的时钟源fOSC/12,禁止PCA计数器溢出时中断 MOV CCON, #00H ; PCA计数器溢出中断标志CF清0 ;CR = 0, 禁PCA 计数器计数; PCA模块中断标志CCFn清0 MOV CL, #00H ; PCA 计数器清0 MOV CH, #00H MOV CCAP0L, #00H ;给PCA模块0的CCAP0L置初值 MOV CCAP0H, #1EH ;给PCA模块0的CCAP0H 置初值 MOV CCAPM0, #49H ;置PCA模块0为16位软件定时器 ;ECCF0=1允许PCA模块0中断, [CH,CL]=[CCAP0H,CCAP0L]时 ;产生中断, CCF0=1, 请求中断 SETB EA ;开整个单片机所有中断共享的总中断控制位 SETB CR ;启动PCA计数器(CH,CL)计数 SJMP $ ;循环等待中断
122
【例7-7】利用PCA 模块做定时器使用 PCA_ISR: ;PCA中断服务程序 PUSH ACC ;保护现场 PUSH PSW MOV A, #00H ;给[CCAP0H, CCAP0L]增加一个数值 ADD A, CCAP0L;每5mS中断一次 MOV CCAP0L, A ; 每中断一次增加一个步长值 MOV A, #1EH ADDC A, CCAP0H MOV CCAP0H, A CLR CCF0 ;清 PCA 模块0 中断标志 DJNZ COUNTER, PCA_EXIT ;中断计数没减到0,退出 MOV COUNTER, #200 ;恢复中断计数初值 CPL LED_1s ;LED_1S输出脉宽为1秒钟方波 PCA_EXIT: POP PSW ;恢复现场 POP ACC RETI END 本题不需要 ; COUNTER计数器, 计数中断次数
123
#include “stc15.h” //包含寄存器定义文件 sbit LED_1s=P1^6;
unsigned char cnt; //中断计数变量 void main (void) { cnt=200; //设置COUNTER计数器初值 CMOD=0x80; //# B 空闲模式停止PCA计数器 //选择PCA时钟源为SYSclk /12,禁PCA计数器溢出时中断 CCON=0; //清0PCA计数器溢出中断请求标志位CF //CR = 0, 禁PCA 计数器计数; PCA 模块中断标志CCFn清0 CL=0; //清0PCA 计数器 CH=0; CCAP0L=0; //给PCA模块0的CCAP0L置初值 CCAP0H=0x1e; //给PCA模块0的CCAP0H 置初值 CCAPM0=0x49; //PCA模块0: 为16位软件定时, ECCF0=1→ //允许中断, [CH,CL]=[CCAP0H,CCAP0L]时,CCF0=1,产生中断 EA=1; //开单片机所有中断共享的总中断控制位 CR=1; //启动PCA计数器(CH,CL)计数 while(1); //等待中断 } 【例7-7】利用PCA 模块做定时器使用
124
void PCA_ISR(void) interrupt 7 //PCA中断服务程序
{ union{ unsigned int num; //定义联合,以进行16位加法 struct{unsigned char Hi, Lo; //联合中定义一结构 }Result; }temp; //每5ms中断一次 temp.num=(unsigned int)(CCAP0H<<8)+CCAP0L+0x1e00; CCAP0L=temp.Result.Lo; //取计算结果的低8位 CCAP0H=temp.Result.Hi; //取计算结果的高8位 CCF0=0; //清 PCA 模块0 中断标志 cnt--; //修改中断计数 if (cnt==0) { cnt=200; //恢复中断计数初值 LED_1s =!LED_1s; //P1.6输出脉宽1秒钟的方波 } 【例7-7】利用PCA 模块做定时器使用 从联合中取结果
125
[例7-8] 利用PCA模块进行PWM输出。PWM脉冲由P1.1/CCP0输出, 设晶振频率SYSclk=18.432MHz。
解: PWM无需中断支持, 只需根据需要设置PCA模块的 参数, 并通过指令进行输出即可。 PWM脉冲输出频率: SYSclk/256=18.432MHz/256=72kHz。 PWM的占空比(高电平占一个周 期的时间比率)为: 占空比=(pulse_width/256)*100% 假设用8位PWM输出模式 P1.1/CCP0输出低电平时灯亮。占 空比值越大, 灯越暗,占空比值越 小, 灯越亮。 图7-16 PWM测试电路图
126
【例7-8】利用PCA模块进行PWM输出 $INCLUDE (STC15.INC) ;STC15F2K60S2寄存器定义文件
;pulse_width_MAX = pulse_width_MIN 时, 输出脉冲宽度不变。 pulse_width_MAX EQU 0F0H ;低脉宽最大值占空比 93.75% pulse_width_MIN EQU 10H ;PWM脉宽最小值占空比6.25% step EQU 38H ;PWM 脉宽变化步长 pulse_width EQU 30H ;定义变量 ORG H LJMP MAIN ORG H MAIN: MOV SP, #70H MOV CMOD, #80H ;PCA空闲模式停止 PCA 计数器工作 ;PCA 时钟模式为FOSC/12,禁止 PCA 计数器溢出中断 MOV CCON, #00H ;禁PCA计数器,清中断标志,计数溢出标志 MOV CL, #00H ;清0计数器 MOV CH, #00H 注意本题的占空比是指: 低电平脉宽占空比
127
【例7-8】利用PCA模块进行PWM输出 ;置模块0为8位PWM输出模式,脉冲在P1.1 /CCP0引脚输出 MOV CCAPM0, #42H ;允许比较功能, 脉宽调制模式 MOV PCA_PWM0, #00H ;设置8位PWM输出模式 ; MOV PCA_PWM0, #03H ; PWM 输出一直 0, 无脉冲。 SETB CR ;启动PCA 计数器 MAIN_LOOP: LCALL PWMOUT LJMP MAIN_LOOP PWMOUT: ;可用示波器观察P1.1的波形 ;下面程序先使连接到P1.1 /CCP0的LED逐渐变亮, 最亮后再渐暗 MOV A, #pulse_width_MIN ;为输出(低电平)脉宽设置初值 MOV pulse_width, A ;pulse_width变量值越大,正脉宽越窄, LED越亮 LED长亮 ;MOV pulse_width, #pulse_width_MIN ;以上两行可合并为一行
128
【例7-8】利用PCA模块进行PWM输出 PWM_LOOP1: ;连接到P1.1 /CCP0的LED逐渐变亮 MOV A, pulse_width ;低电平宽送A, 为判是否到达最大值 CLR C SUBB A, #pulse_width_MAX ;减低电平最大宽度F0H JNC PWM_A ;到达最大值就转到逐渐变暗 程序 MOV A, pulse_width ;设置低电平宽, 值越大,正脉宽越窄,LED越亮 MOV CCAP0H, A ;核心语句 MOV CCAP1H0L, A ;计数值<pulse_width, 则输出低电平 ;MOV A, pulse _width ADD A, #step MOV pulse_width, A LCALL DELAY ;一段时间内保持输出脉宽不变 LJMP PWM_LOOP1 ;下次循环修改低电平宽度, 变占空比 PWM_A: ;连接到P1.1的LED达到最亮后, 再逐渐变暗 或;MOV CCAP0H, pulse_width ;计算下一次输出低电平宽度数值 PWM输出频率72kHz,在没改变CCAP0L值前,脉宽占空比不变
129
; 连接到P1.1 /CCP0的LED达到最亮后, 再逐渐变暗 MOV A, #pulse_width_MAX ;为输出低电平脉宽设置初值 MOV pulse_width, A ;pulse_width 越大,正脉宽越窄, LED越亮 PWM_LOOP2: MOV A, pulse_width ;低电平宽送A, 为判是否到达最小值 CLR C SUBB A, #pulse_width_MIN ;减低电平最小宽度10H JC PWM_B ;到达最小值就返回。 JZ PWM_B ;到达最小值就返回。 MOV A, pulse_width ;设置脉宽, 值越大,脉宽越窄,LED 越亮 MOV CCAP0H, A ;核心语句 MOV CCAP1H0L, A ;计数值<pulse_width, 则输出低电平 MOV A, pulse_width ;计算下一次输出低电平宽度数值 SUBB A, #step MOV pulse_width, A LCALL DELAY ;一段时间内保持输出脉冲宽度不变 LJMP PWM_LOOP2 PWM_B: RET 【例7-8】利用PCA模块进行PWM输出 PWM输出频率72kHz,在没改变CCAP0L值前,脉宽占空比不变
130
【例7-8】利用PCA模块进行PWM输出 DELAY: ;延时子程序 CLR A MOV R1, A MOV R2, A MOV R3, #80H DELAY_LOOP: NOP ; 1T时钟 DJNZ R1, DELAY_LOOP ; 4T时钟 DJNZ R2, DELAY_LOOP ; 4T时钟 DJNZ R3, DELAY_LOOP ; 4T时钟 RET END 初值R1=0, R1减1后是0FFH, 若R1≠0则转DELAY_LOOP, 所以该层循环执行256次 延时时间大约为: ((256*7+4)*256+4)*128/18.432MHz≈ 3.193s
131
【例7-9】利用PCA模块1进行高速脉冲输出。
假设晶振频率SYSclk =20MHz。 从P1.0 /CCP1输出 125.0KHz的方波脉冲。 解:可用PCA模块实现高速脉冲输出功能。 要激活高速 脉冲输出模式, CCAPM1寄存器的TOG1, MAT1和 ECOM1位必须都置位。 CCAP1L中的值应设为40HD (28H) : CCAPnL =INT(SYSclk / (4×f) + 0.5 CCAPnL=INT( /4/ )=INT(40+0.5) = 40= 28H
132
MOV CMOD, #00000010B ;CIDL= 0, 空闲模式计数继续,
汇编语言程序如下: $INCLUDE (STC15.INC) ;STC15F2K60S2寄存器定义文件 CCAPnL_Value EQU 28H ; SYSclk=20MHz,输出125KHz ORG 0000H LJMP MAIN ORG 003BH ;PCA中断入口地址 LJMP PCA_ISR ORG 0060H MAIN:MOV SP, #70H ;设置堆栈指针 例7-9利用PCA模块1进行高速输出。 ;PCA模块初始化 MOV CMOD, # B ;CIDL= 0, 空闲模式计数继续, ;PCA计数脉冲源FOSC/2; ECF = 0,禁止PCA计数器计数溢出中断
133
MOV CCON, #00H ;清除PCA计数器计数溢出中断标志CF MOV CH, #00H ;清零 PCA 计数器高8位
;停止PCA计数器计数, CR=0;清除 中断标志, CCFn=0 MOV CH, #00H ;清零 PCA 计数器高8位 MOV CL, #00H ;清零PCA 计数器低8位 ;设置模块1为高速脉冲输出模式, 脉冲在P1.0 /CCP1引脚输出 MOV CCAPM1, # B ;模块1高速输出,允许触发中断 MOV CCAP1L, #CCAPnL_Value ;给模块 1置初值28H MOV CCAP1H, #0 ;给模块 1置初值(0028H), 此句不可少 ;其它中断服务可能会使模块1高速脉冲输出的某个周期变得很大, 因此, 须将PCA中断优先级设为唯一最高级, 其它中断优先级都低。 MOV IP, # B ;PCA 中断的优先级设置为最高级 SETB EA ;开总中断 SETB CR ;将PCA 计数器打开 SJMP $ ;循环等待中断
134
PCA_ISR: ;PCA中断服务程序 PUSH ACC ;4 Clock PUSH PSW ;4 Clock CLR CCF1 ;1 Clock, 清PCA模块1中断标志 MOV A, #CCAPnL_Value ;2 Clock ADD A, CCAP1L ;3 Clock , 被比较数加步长(计数值) MOV CCAP1L, A ;3 Clock CLR A ;1 Clock ADDC A, CCAP1H ;3 Clock , 加低字节加法的进位 MOV CCAP1H, A ;3 Clock POP PSW ;3 Clock POP ACC ;3 Clock RETI ;4 Clock END 【例7-9】利用PCA模块1进行高速输出。
135
[例7-10]定时器0溢出作为PCA模块时钟输入源实例
假设晶振频率SYSclk=18.432MHz, 使用STC15F2K60S2 定时器0的溢出作为PCA模块的时钟源, PCA模块0的PWM功能实现可调频率的PWM输出 (P1.1/CCP0引脚); 使用PCA模块1的16位软定时器功能实现定时,在P1.6 引脚上输出脉冲宽度5ms的方波; 在P1.5引脚上输出脉冲宽度为1秒钟的方波。 为观察程序执行效果, 可在相应输出引脚上连接发光 二极管。
136
[例7-10]定时器0溢出作为PCA模块时钟输入源实例
解: PCA模块可用定时器0溢出作为时钟源, 此时, CMOD 寄存器中CPS2, CPS1和CPS0设置为(010)2。 PCA模块用作定时器时, PCA计数值的计算方法: 用定时器0溢出作PCA计数器(CH,CL)时钟源时, 可设 置定时器0每12时钟脉冲加1, 定时器0每加10次后产生1 次溢出, 即每120时钟脉冲PCA计数器[CH,CL]加1。 当[CH,CL]增到等于[CCAP1H, CCAP1L]时, CCF1=1, PCA模块1产生中断请求。 若每次PCA模块1中断后, 在中服程序中给[CCAP1H, CCAP1L]增加一个相同数值, 那么下一次中断来临的 间隔时间T也是相同的。 这个“相同的数值”就是需要计算的计数常数。 对应5ms方波定时
137
[例7-10]定时器0溢出作为PCA模块时钟输入源实例
本程序, 时钟频率SYSclk =18.432MHz时, 要使PCA定时 5ms, 则PCA计数器的计数次数为: 计数次数=T/((1/ SYSclk)×120) = 0.005/((1/ ) ×120)= 768 = 300H 即每次给[CCAP1H, CCAP1L]增加数值(步长) 300H。 汇编语言程序如下: $INCLUDE (STC15.INC) ; STC15F2K60S2寄存器定义文件 CH1_5MS_H EQU 03H ;PCA模块1定时5ms常数300H高位 CH1_5MS_L EQU 00H ;PCA模块1的5ms定时常数低位 T0_ EQU 0F6H ;T0重装数值1(计数10个后溢出) T0_ EQU 0ECH ;T0重装数值2(计数20个后溢出)
138
[例7-10]定时器0溢出作为PCA模块时钟输入源实例
PWM_WIDTH EQU 0FFH ;数字越大脉宽越窄,占空比越小 PWM_PULSE_WIDTH EQU 0FFH;值越大脉宽越窄(占空 比越小) COUNTER EQU 30H ;声明计数器变量,计数中断次数 LED_5MS EQU P1.6 ;5毫秒指示灯 LED_1S EQU P1.5 ;1秒钟指示灯 ORG H LJMP MAIN ORG 003BH ;PCA中断入口地址 LJMP PCA_ISR ORG H MAIN:MOV SP, #70H ;设置堆栈指针 MOV COUNTER, # ;置COUNTER计数器初值
139
[例7-10]定时器0溢出作为PCA模块时钟输入源实例
MOV CMOD, # B ;PCA 在空闲模式停止 计数器 ;PCA时钟源为定时器0的溢出,禁止PCA计数器溢出时中断 MOV CCON, #00H ; PCA计数器溢出中断请求标志位CF清 0 ,CR = 0, 禁PCA计数器计数, PCA模块中断标志CCFn清0 MOV CL, #00H ; PCA 计数器清0 MOV CH, #00H ;设置模块0为 8 位 PWM 输出模式, PWM无需中断支持。脉冲在 P1.1/CCP0引脚输出 MOV CCAPM0, #42H ;设置模块0为8位PWM输出模式 MOV PCA_PWM0, #00H ; PWM 模式第9位EPC0L(H)清0 MOV CCAP0H, #PWM_PULSE_WIDTH ;设置脉宽0FFH
140
[例7-10]定时器0溢出作为PCA模块时钟输入源实例
MOV CCAP1L, #CH1_5mS_L ;PCA模块1置初值CCAP1L MOV CCAP1H, #CH1_5mS_H ;PCA模块1置初值CCAP1H MOV CCAPM1, #49H ;置PCA模块1为16位软件定时器 ;ECCF1=1, 允许PCA模块1中断, ;[CH,CL]=[CCAP1H,CCAP1L] 时,产生中断请求,CCF1=1,请求中断 SETB EA ;开单片机所有中断共享的总中断控制位 SETB CR ;设置CCON启动PCA计数器[CH, CL]计数 ;初始化T0, 其溢出脉冲作PCA计数器(CH,CL)的时钟源 MOV TMOD, #02H ;置定时器0 为8位自动重装工作模式 MOV TH0, #T0_1 ;T0重装数值(计数值10溢出) MOV TL0, #T0_1 ;T0重装数值(计数值10溢出) SETB TR ;设置TCON启动定时器0 不特别设置AUXR的T0x12=0, 因其初始化默认为12分频。
141
[例7-10]定时器0溢出作为PCA模块时钟输入源实例
MAIN_LOOP: MOV TH0, #T0_1 ;T0溢出率时间常数(计数值10) MOV TL0, #T0_1 MOV A, #PWM_WIDTH ;PCA模块0是8位PMM,脉宽0FFH MOV CCAP0H, A LCALL DELAY MOV TH0, #T0_2 ;修改T0溢出率时间常数(计数值20) MOV TL0, #T0_2 LCALL DELAY ;P1.1/CCP0的LED较亮 MOV TH0, #T0_1 ;T0 溢出率高(计数值10) MOV TL0, #T0_1 MOV A, #PWM_WIDTH ;PCA模块0是8位PMM,脉宽0FFH LCALL RR_A ; A带C=0循环右移, A=7FH,改变 PWM占空比 LCALL RR_A ; A带进位C清0循环右移, A=3FH MOV CCAP0H, A ;值越大,PWM占空比越小,P1.1的LED越亮 LCALL DELAY [例7-10]定时器0溢出作为PCA模块时钟输入源实例 ;T0溢出率变低,接定时器脉冲的LED闪烁速度变慢, 而PWM的LED亮度未改变
142
[例7-10]定时器0溢出作为PCA模块时钟输入源实例
MOV TH0, #T0_2 ;T0溢出率低(计数值20) MOV TL0, #T0_2 LCALL DELAY MOV CCAP0H, A ;值越大,PWM占空比越小,P3.5LED越亮 LCALL DELAY ;下面减小A(正脉宽),连接P1.1/CCP0的LED暗 MOV TH0, #T0_1 ;T0 溢出率高(计数值10) MOV TL0, #T0_1 MOV A, #PWM_WIDTH ;脉宽0FFH LCALL RR_A ; A带C=0循环右移, A=7FH,改变 PWM占空比 LCALL RR_A ; A带进位C清0循环右移, A=3FH LCALL RR_A ; A带进位C清0循环右移, A=1FH LCALL RR_A ; A带进位C清0循环右移, A=0FH MOV TH0, #T0_2 ;T0 溢出率低 MOV TL0, #T0_2 LJMP MAIN_LOOP ;循环 RR_A: CLR C ;下面 是循环右移子程序 RRC A RET [例7-10]定时器0溢出作为PCA模块时钟输入源实例
143
[例7-10]定时器0溢出作为PCA模块时钟输入源实例
PCA_ISR: ;PCA模块1的16位软定时中断服务程序 PUSH ACC PUSH PSW CPL LED_5MS ;模块1每5ms中断一次,将P1.6灯状态取反 MOV A, #CH1_5MS_L ;[CCAP1H,CCAP1L]增加一数值 ADD A, CCAP1L ;模块1捕捉/比较寄存器与步长低字节加 MOV CCAP1L, A MOV A, #CH1_5MS_H ADDC A, CCAP1H ;模块1比较寄存器与步长高字节带进位加 MOV CCAP1H, A CLR CCF1 ;清PCA模块1中断标志 DJNZ COUNTER, PCA_EXIT ;是否中断了100 次(0.5秒) MOV COUNTER, #100 ;中断100 次后, 重置COUNTER CPL LED_1S ; LED_1S(P1.5)取反, 输出脉宽 0.5 秒钟方波 PCA_EXIT: POP PSW POP ACC RETI 方波周期1秒
144
[例7-10]定时器0溢出作为PCA模块时钟输入源实例
DELAY: ;延时子程序 CLR A MOV R1, A MOV R2, A MOV R3, #80H DELAY_LOOP: NOP DJNZ R1, DELAY_LOOP DJNZ R2, DELAY_LOOP DJNZ R3, DELAY_LOOP RET END 延时时间大约为: ((256*7+4)*256+4)*128/18.432MHz≈ 3.193s
Similar presentations