第七章 定时/计数器
任课教师:刘忠国 山东大学课程中心网站: http://course.sdu.edu.cn/G2S/stcmcu.cc 宏晶官方网站:http://www.stcmcu.com STC单片机编译(汇编)/编程(烧录)/仿真工具说 明书; stc15系列单片机器件手册等 keil μvision软件下载及指导手册(Help→μvision Help) http://www.keil.com/ Keil Software –Cx51 编译器用户手册: Cx51编译 器--对传统和扩展的8051微处理器的优化的C 编译器和库参考
第七章 定时/计数器 本章学习目标 掌握定时计数器的应用 掌握可编程时钟输出模块的应用
第七章 定时/计数器 7.1 定时/计数器及其应用 7.2 可编程时钟输出模块及其应用 7.1.1 定时/计数器的结构及工作原理 第七章 定时/计数器 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 可编程时钟输出的编程实例
第七章 定时/计数器 IAP15W4K58S4单片机内部集成了五个16位的定 时/计数器(T0、T1、T2、T3和T4),不仅可以方便 地用于定时控制,而且还可以用作分频器和用于事件 记录; 另外,可以设置使用可编程时钟输出功能,用于 给外部器件提供时钟。
§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 x =0, 1时的引脚与控制标志位 图7-1 定时/计数器的结构框图(x =0, 1, 2, 3,4,下同)
7.1.1定时/计数器的结构及工作原理 图中有两个模拟位开关, TMOD.C/T决定工作方式: 是 定时还是计数。 控制信号(由TCON.TR0(1)等形成) 决定计数器开启与 关闭。 用户可对特殊功能寄存器TMOD, TCON相应位设置, 从而选择不同工作方式(计数或定时)或是否启动计数器。 AUXR中T0x12, T1x12决定是否对振荡时钟进行12分频。 TCON.TR0(1) 开启运行 AUXR.T0(1)x12 TMOD 由TCON.TR0(1)等形成 图7-1 定时/计数器的结构框图( x =0,1,2,3,4, 下同)
7.1.1、定时/计数器的结构及工作原理 当脉冲源为时钟振荡器(等间隔脉冲序列)时, 每个时钟 周期计数器加1, 因计数脉冲为一时间基准, 所以脉冲数 乘以脉冲间隔时间即定时时间, 因此有定时功能。 当脉冲源为外部脉冲(通常间隔不等) 时, 就是外部事件 计数器, 当外输入端上有1→0的跳变时计数器加1。 外部输入信号的速率是不受限制的,但必须保证给出 的电平在变化前至少被采样一次。 TMOD TCON.TR0(1) 图7-1 定时/计数器的结构框图(x =0,1,2,3,4, 下同)
7.1.1定时/计数器的结构及工作原理 计数器对这两个脉冲源之一进行输入计数,每输入一 个脉冲,计数值加1。 当计数到计数器全1时, 再输入一个脉冲就使计数值回 零, 同时从最高位溢出一个脉冲使寄存器TCON的TF0 或TF1置1, 作为计数器的溢出中断标志。 如果定时/计数器工作于定时状态,则表示定时时间到; 若工作于计数状态,则表示计数回零。 TCON.TF0(1) 溢出中断标志 TMOD TCON.TR0(1)
7.1.2 定时/计数器的相关寄存器 单片机的CPU和各个特殊功能寄存器之间的关系 7.1.2 定时/计数器的相关寄存器 单片机的CPU和各个特殊功能寄存器之间的关系 定时 计数 时钟 定时 计数 时钟 定时 计数 时钟 定时 计数 时钟 定时 计数 时钟 原手册中名称: T2H, T2L, T3H, T3L, T4H, T4L 图7-2 CPU与定时/计数器相关特殊功能寄存器的关系图 图中, TH0(地址为8C)为T0重装值寄存器高字节, TL0(地址为8A)为 T0重装值寄存器低字节; TH1(地址为8D)为T1重装值寄存器高字节, TL1(地址为8BH)为T1重装值寄存器低字节; TH2(地址为D6H)为T2 重装值寄存器高字节, TL2(地址为D7H)为T2重装值寄存器低字节;、 TH3(地址为D4H)为T3重装值寄存器高字节,TL3(地址为D5H)为T3 重装值寄存器低字节;TH4(地址为D2H)为T4重装值寄存器高字节, TL4(地址为D3H)为T4重装值寄存器低字节; 这些寄存器复位值均 为00H。
7.1.2 定时/计数器的相关寄存器 为了与定时/计数器T0和T1的描述保持一致, 本书对T2、 T3和T4相关寄存器的名称和相关位的名称进行了修改。原 手册中的名称分别为T2H、T2L、T3H、T3L、T4H和T4L。 在对应的头文件STC15.INC和stc15.h中分别做了定义,读 者可以直接使用。 其他相关的特殊功能寄存器及其控制位如表7-1所示。 其中,带有C/ 符号的控制位用于选择计数功能或定时 功能,TRx用于启动或停止定时/计数器。Txx12用于设置 是否12分频。TxCLKO用于设置是否允许时钟输出功能。 sfr T4H = 0xD2; //0000,0000 T4高字节 sfr TH4 = 0xD2; //0000,0000 T4高字节 sfr T4L = 0xD3; //0000,0000 T4低字节 sfr TL4 = 0xD3; //0000,0000 T4低字节 sfr T3H = 0xD4; //0000,0000 T3高字节 sfr TH3 = 0xD4; //0000,0000 T3高字节 sfr T3L = 0xD5; //0000,0000 T3低字节 sfr TL3 = 0xD5; //0000,0000 T3低字节 sfr T2H = 0xD6; //0000,0000 T2高字节 sfr TH2 = 0xD6; //0000,0000 T2高字节 sfr T2L = 0xD7; //0000,0000 T2低字节 sfr TL2 = 0xD7; //0000,0000 T2低字节 sfr TH0 = 0x8C; //0000,0000 T0高字节 sfr TH1 = 0x8D; //0000,0000 T1高字节 sfr TL0 = 0x8A; //0000,0000 T0低字节 sfr TL1 = 0x8B; //0000,0000 T1低字节 对T2,T3,T4, TRx在原手册中名称为TxR
7.1.2 定时/计数器的相关寄存器 表7-1 与定时/计数器有关的特殊功能寄存器 对T2,T3,T4, TRx在原手册中名称为TxR 7.1.2 定时/计数器的相关寄存器 表7-1 与定时/计数器有关的特殊功能寄存器 寄存器 地址 D7 D6 D5 D4 D3 D2 D1 D0 复位值 TMOD 89H GATE M1 M0 00000000B TCON 88H TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 AUXR 8EH T0x12 T1x12 UART_M0x6 TR2 T2_C/T T2x12 EXTRAM S1ST2 INT_CLKO 8FH - EX4 EX3 EX2 T2CLKO T1CLKO T0CLKO x000x000B T4T3M D1H TR4 T4x12 T4CLKO TR3 T3x12 T3CLKO 对T2,T3,T4, TRx在原手册中名称为TxR 以上位域除TCON寄存器的各位可位寻址操作之外, 其他位都不能位寻址
7.1.2 定时/计数器的相关寄存器 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
1、TMOD:定时器工作方式控制寄存器 位号 D7 D6 D5 D4 D3 D2 D1 D0 定时器名 定时器1 定时器0 位名称 GATE C/ M1 M0 1)M1和M0:方式选择控制位 表7-2 定时/计数器的方式选择 M1 M0 工作方式 功能说明 0 0 16位自动装载的定时器/计数器 0 1 1 16位定时器/计数器 1 0 2 可自动装入的8位计数器 1 1 3 对T0是不可屏蔽中断的16位自动重装定时器 对T1定时器/计数器1此时无效(停止计数)
1、TMOD:定时器工作方式控制寄存器 对于方式0~2, 定时/计数器0和定时/计数器1的结构和 工作过程是相同的。 对于方式0~2, 定时/计数器0和定时/计数器1的结构和 工作过程是相同的。 当T0工作于方式3(不可屏蔽中断的16位自动重装载模 式)时, 不需要EA=1, 只需ET0=1就能打开T0的中断。 此模式下, T0中断与总中断使能位EA无关, 一旦T0中断 被允许后, T0中断的优先级就是最高的, 它不能被其它 任何中断所打断; 而且该中断允许后既不受EA的控制, 也不再受ET0的控 制, 清零EA或ET0都不能关闭T0的中断。 工作于该方式的T0可用于实时操作系统的节拍定时器.
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)不能进行位寻址,设置 时只能对整个寄存器赋值。
门控位GATE参考图7-3 图7-3 定时器0和1的工作方式0原理框图 定时器的16位计数器 TCON .4 /.6 x =0, 1 图7-3 定时器0和1的工作方式0原理框图 定时器的16位计数器 TCON .4 /.6 x =0, 1 TMOD. 7(GATE): 门控位。GATE用于选通控制。 GATE=0: 每当TRx置位1时, 就启动定时器工作(非GATE选通方式)。 GATE=1: INTx (x =0, 1)为高电平且TRx置位1时, 启动定时器工作。 当GATE=1, 允许由外部INTx高电平控制计数, 可实现脉宽测量。
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相似。
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相似。
3、AUXR:辅助寄存器 辅助寄存器AUXR主要用来设置定时器的速度和定时 器2的功能以及串口UART的波特率控制。 IAP15W4K58S4单片机是1T 的8051单片机, 为兼容传 统8051单片机, 定时器复位后仍然是传统8051的速度, 即12分频, 但此时指令执行速度仍然是1T的速度。 通过设置特殊功能寄存器AUXR中相关的位, 定时器 也可不进行12分频,实现真正的1T速度。 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 T0x12 T1x12 UART_M0x6 T2R T2_C/ T2x12 EXTRAM S1ST2
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。
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位自动重装载模式。不用设置工作方式。
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:禁止使用。 对STC15F2K60S2而言 对IAP15W4K58S4而言是3840字节
4、外部中断使能和时钟输出寄存器INT_CLKO T2CLKO、T1CLKO、T0CLKO是与时钟输出有关的位。 参看:§7.2.1 可编程时钟输出的相关寄存器 外部中断使能和时钟输出寄存器INT_CLKO 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 - EX4 EX3 EX2 LVD_WAKE T2CLKO T1CLKO T0CLKO 当位T0CLKO (INT_CLKO.0)=1时, 将引脚T1/P3.5 /T0CLKO配置为定时器0的时钟输出T0CLKO。 当位T1CLKO (INT_CLKO.1)=1时, 将引脚T0/P3.4 /T1CLKO配置为定时器1的时钟输出T1CLKO。 当位T2CLKO (INT_CLKO.2)=1时, 将引脚P3.0 /T2CLKO 配置为定时器2的时钟输出T2CLKO。
5.T4和T3控制寄存器T4T3M 1) TR4:T4运行控制位。TR4=0时, 不允许T4运行; TR4=1时, 允许T4运行。 地址 D7 D6 D5 D4 D3 D2 D1 D0 复位值 T4T3M D1H TR4 T4x12 T4CLKO TR3 T3x12 T3CLKO 0H 1) TR4:T4运行控制位。TR4=0时, 不允许T4运行; TR4=1时, 允许T4运行。 2) T4_C/T: 控制T4用作定时器或计数器。T4_C/T =0时, 用 作定时器(计数脉冲从内部系统时钟输入); T4_C/T =1时, 用作计数器(计数脉冲从P0.7/T4引脚输入)。 对T2,T3,T4, TRx在原手册中名称为TxR 3) T4x12:T4速度控制位。T4x12=0时, T4的速度是传统 8051单片机定时器的速度, 即12分频。T4x12=1时, T4的速 度是传统8051单片机定时器速度的12倍, 即不分频。 4) T4CLKO:是否允许将P0.6脚配置为T4的时钟输出T4CLKO。 1: 允许将P0.6脚配置为T4的时钟输出T4CLKO, 输出时钟频率 =T4溢出率/2; 0: 不允许将P0.6脚配置为T4的时钟输出T4CLKO。
5.T4和T3控制寄存器T4T3M 5) TR3: T3运行控制位。TR3=0时, 不允许T3运行; TR3=1时, 允许T3运行。 地址 D7 D6 D5 D4 D3 D2 D1 D0 复位值 T4T3M D1H TR4 T4x12 T4CLKO TR3 T3x12 T3CLKO 00000000B 5) TR3: T3运行控制位。TR3=0时, 不允许T3运行; TR3=1时, 允许T3运行。 6) T3_C/T: 控制T3用作定时器或计数器。T3_C/T =0时, 用 作定时器(计数脉冲从内部系统时钟输入); T3_C/T =1时, 用 作计数器(计数脉冲从P0.5/T3引脚输入)。 7)T3x12:T3速度控制位。T3x12=0时, T3的速度是传统 8051单片机定时器的速度, 即12分频。T3x12=1时, T3的速 度是传统8051单片机定时器速度的12倍, 即不分频。 8) T3CLKO: 是否允许将P0.4脚配置为T3的时钟输出T3CLKO。 对T2,T3,T4, TRx在原手册中名称为TxR
7.1.3 定时/计数器的工作方式 通过对寄存器TMOD中M1、M0的设置,定时/计数器 T0和T1有4种不同的工作方式: 7.1.3 定时/计数器的工作方式 通过对寄存器TMOD中M1、M0的设置,定时/计数器 T0和T1有4种不同的工作方式: 方式0: 16位自动重装方式 方式1: 16位定时/计数器方式 方式2: 8位自动重装方式 方式3: (本书置以方式0为例介绍) 对T0是不可屏蔽中断的16位自动重装定时器 对T1定时器/计数器1此时无效(停止计数) 位号 D7 D6 D5 D4 D3 D2 D1 D0 定时器名 定时器1 定时器0 位名称 GATE C/ M1 M0
1、定时/计数器0和1的工作方式0 (16位自动重装方式) 图7-3 定时器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高电平控制计数, 可实现脉宽测量。
1、定时/计数器0和1的工作方式0 (16位自动重装方式) IAP15W4K58S4的定时器有两种计数速率:一种是 12T模式,每12个时钟加1;另一种是1T模式,每个 时钟加1。 T0和T1的速率分别由特殊功能寄存器AUXR中的 T0x12 (AUXR.7)和T1x12 (AUXR.6)决定。 T0x12=0,T0工作在12T模式; T0x12=1,T0工作在1T模式。 T1x12=0,T1工作在12T模式; T1x12=1,T1则工作在1T模式。 AUXR寄存器 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 T0x12 T1x12 UART_M0x6 T2R T2_C/ T2x12 EXTRAM S1ST2
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中。
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
1、定时/计数器0和1的工作方式0 (16位自动重装方式) 掌握工作方式0即可满足一般工程应 用需求。 其他工作方式可参考手册。
T2、T3和T4的工作模式固定为16位自动重装载模式。 它们的内部结构和使用方法相同。下面以T2为例介绍。 AUXR.2 T2中断标志位对用户不可见 AUXR.3 定时器2的16位计数器 T2/P3.1引脚 INT_CLKO内 AUXR.4 引脚输出 P3.0 /T2CLKO 定时器2的16位重装载寄存器 图7-4 定时/计数器T2的原理框图
7.1.4 定时/计数器量程的扩展 实际中需要的定时时间常数超过定时器的定时能力, 特 别当单片机系统时钟频率较高时, 定时时长就更有限。 为满足需要, 经常需对单片机的定时能力进行扩展。 1、定时器的最大定时能力 定时状态时,定时器是对时钟周期进行计数, 若对时钟 进行12分频,则每12个时钟周期计数一次。 当晶振频率为11.0592MHz, 用12分频时, 计数的单位时间为: 单位时间为:Tu= = s 定时时间为:Tc=XTu。其中,Tu为单位时间, Tc为定时时间,X为所需计数的次数值。
计数次数与计数初值 1、定时器的最大定时能力 单位时间: 定时时间: Tc=XTu , X为所需计数次数。 IAP15W4K58S4单片机的定时/计数器是加1计数器。 因此, 不能直接将实际的计数次数值X作为计数初值送 入计数寄存器THx、TLx中。 当使用工作方式0时, 必须将实际计数次数值以216为 模求补, 以补码作为计数初值送入THx和TLx。 即应装入定时/计数器的计数初值N为: X: 计数次数值
1、定时器的最大定时能力 计数次数与计数初值 例如: 已知 , 要求定时Tc=10ms, 晶振频率为11.0592MHz, 用12分频时 则: 对方式0, 计数初值(时间常数): 216 - 9216= 56320 =0DC00H (THx装入DCH, TLx装入00H)。 当系统时钟频率为11.0592MHz,12分频时: 16位定时器最大定时能力为: T = 216 × ≈71.11ms 计数初值= 216 -计数次数
2、定时量程的扩展 定时量程的扩展分为软件扩展和硬件扩展两种方法。 (1)软件扩展方法 软件扩展方法是在定时器中断服务程序中对定时器中 断请求次数进行计数,当中断请求次数达到要求值时 才进行相应的处理。 例如,某事件的处理周期为1s, 由于受到最大定时时间 (71.11ms)的限制,无法一次完成定时。 可将定时器的定时时间设为10ms,启动定时器后,每 一次定时器溢出中断将产生10ms的定时。 在中断服务程序中对定时器中断次数进行计数,每计 数100次进行一次事件处理,则可实现1s的定时效果。
2、定时量程的扩展 (2)硬件扩展方法 硬件扩展方法可以使用外接通用定时器芯片对单片 机的定时能力进行扩展。 也可以利用单片机自身的资源对定时能力进行扩展。 例如, 将两个定时器串联起来使用 (一个用于定时方 式, 另一个用于计数方式, 请分析其最大定时时间)。 当系统时钟频率为11.0592MHz,12分频时: 16位定时器最大定时能力为: T ≈71.11ms 两个串联最大定时时间: T = 216 ×71.11ms ≈ 4660.26 s 由于该扩展方法占用较多的资源,较少采用。
7.1.5 定时/计数器编程举例 定时/计数器的应用一般用中断方式, 编程需考虑两点: 正确初始化: 包括写入控制字, 时间常数计算并装入; 7.1.5 定时/计数器编程举例 定时/计数器的应用一般用中断方式, 编程需考虑两点: 正确初始化: 包括写入控制字, 时间常数计算并装入; 中断服务程序的编写: 编写需定时完成的任务代码。 在定时/计数器初始化部分的一般步骤大致如下: 设置工作方式,将控制字写入TMOD寄存器 (对T0和 T1)或AUXR(对T2)或T4T3M寄存器(对于T3和T4)。 设置分频方式, 即Tx×12控制位, 将控制字写入AUXR 或T4T3M寄存器。默认的情况是12分频(兼容传统8051 单片机), 若使用传统8051单片机模式, 无需设置。 T2,T3,T4固定为16位自动重装载模式, 只设置定时/计数和分频。
在定时/计数器初始化部分的一般步骤大致: 计算定时/计数初值, 并将其装入TLx、THx寄存器 (对于T0和T1), 或TxL、TxH寄存器(对于T2,T3,T4 在原手册中的名称)。 置位ETx和EA允许定时/计数器中断(若需要)。 置位TRx (对于T0和T1) 或TxR (对于T2,T3,T4在原 手册中的名称) 以启动定时/计数。 ④⑤可交换顺序, 对系统无影响。 在中断服务程序中, 要注意计数初值的重新装入问题。 对T2,T3,T4, TRx在原手册中名称为TxR
利用STC-ISP工具可生成定时器的初始化代码
7.1.5 定时/计数器编程举例 【例7-1】设系统时钟频率为11.0592 MHz,利用T0定 时,每隔0.5s将P2.7的状态取反。 7.1.5 定时/计数器编程举例 【例7-1】设系统时钟频率为11.0592 MHz,利用T0定 时,每隔0.5s将P2.7的状态取反。 解: 所要求定时时间0.5s超过了定时器的定时能力 (时钟 频率为11.0592 MHz, 12分频时, 16位定时器的最长定 时时间为71.11ms), 所以无法采用定时器直接实现0.5s 定时。 将定时器定时时间设为50ms, 在中断服务程序中对 定时器溢出中断请求进行计数, 当计够10次时, 将 P2.7状态取反, 否则返回主程序, 从而达到0.5s定时。
【例7-1】每隔0.5s将P2.7的状态取反 $INCLUDE (STC15.INC) ;包含IAP15W4K58S4寄存器定义文件 选择T0工作于方式0, 方式字TMOD为00H。系统时钟频率 为11.0592MHz, 12分频时, 定时时间为50ms的计数初值为: 计数次数 →TH0,TL0 汇编程序: $INCLUDE (STC15.INC) ;包含IAP15W4K58S4寄存器定义文件 ORG 0000H LJMP MAIN ;转主程序 ORG 000BH ;T0中断服务程序入口地址 LJMP T0_ISR ORG 0100H MAIN: MOV SP, #7F60H ;设置堆栈指针 LCALL TIMER0INIT ;调用T0初始化子程序
【例7-1】 (续) LCALL TIMER0INIT ;调用T0初始化子程序 MOV A, #10 ; A置初值10, 计数定时中断次数 SETB ET0 ;允外T0中断 SETB EA ;CPU开中断 SJMP $ ;等待 头文件有定义: TF0 BIT 8DH TR0 BIT 8CH ET0 BIT 0A9H EA BIT 0AFH TIMER0INIT: ;定时50毫秒@11.0592MHz ANL AUXR, #7FH ;定时器时钟12T模式 ANL TMOD, #0F0H ;设置定时器模式 MOV TL0, #00H ;设置定时初值 MOV TH0, #4CH CLR TF0 ;清除TF0标志 SETB TR0 ;T0开始计时 RET 可利用STC-ISP 工具生成定时器 的初始化代码 T0_ISR: DEC A ; 累加器A内容减1 JNZ T0_END CPL P2.7 ;计时0.5s到, 将P2.7的状态取反 MOV A, #10 ;累加器A重载10 T0_END: RETI END T0中断服务程序入口 头文件有定义: P2 DATA 0A0H ; P2.7(或P2^7)可直接用, C语言不能直接用
【例7-1】每隔0.5s将P2.7的状态取反。C语言程序: #include “stc15.h” //包含IAP15W4K58S4寄存器定义文件 sbit P20=P2^7; //声明P2.7的引脚位变量, 不能直接用P2^7 unsigned char i; //声明计数变量。C程序中尽量不要用ACC void main (void) { //SP=0x60; //用C语言设计程序,可不设置堆栈指针 Timer0Init(); //调用T0初始化子函数 i=10; //定时中断次数计数变量赋初值, 中断服务程序中减一计数 ET0=1; //允许T0中断 EA = 1; //开放总的中断 while(1); //等待中断 } 头文件有定义: sfr P2 0xA0; 头文件有定义: sfr IE = 0xA8; sbit ET0=IE^1 sbit EA=IE^7 sbit TR0=TCON^4
【例7-1】每隔0.5s将P2.7的状态取反。C语言程序: void Timer0Init(void) //50毫秒@11.0592MHz { AUXR &= 0x7F; //定时器时钟12T模式 TMOD &= 0xF0; //设置定时器模式(方式0) TL0 = 0x00; //设置定时初值 TH0 = 0x4C; //设置定时初值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 } 头文件有定义: sfr AUXR =0x8E; sfr TMOD=0x89; sfr TL0=0x8A; sfr TH0=0x8C; sbit TF0=TCON^5 sbit TR0=TCON^4 可利用STC-ISP 工具生成定时器 的初始化代码
【例7-1】每隔0.5s将P2.7的状态取反。C语言程序: (或用头文件定义的符号常数)interrupt T0_VECTOR void T0_ISR (void) interrupt 1 //定时器T0中断服务函数 { i--; //定时中断次数计数变量(初值10)减1 if(i==0) { //若减到0,则将P2.7取反 P27 = !P27; //将P2.7取反, 不能直接用P2^7 (P2.7) i =10; //重新给计数变量赋值 }
[例7-2] 设时钟频率为11.0592 MHz, 用定时器T2定时, 使连接P2.7的指示灯亮0.2s,灭0.8s 。 所要求定时时间超过了定时器的定时能力 (时钟 频率为11.0592 MHz, 12分频时, 16位定时器的最 长定时时间为71.11ms), 所以无法采用定时器直接 实现0.2s和0.8s的定时。 将定时器定时时间设置为10ms, 在中断服务程序 中对定时器溢出中断请求进行初值为100次的减一 计数, 当减到80次时, 达到0.2s定时, 然后从80开始 减到0次时, 达到0.8s定时。
[例7-2] 设时钟频率为11.0592 MHz, 用定时器T2定时, 使连接P2.7的指示灯亮0.2s,灭0.8s 。 利用STC-ISP工具生成定时器的初始化代码 汇编代码如下: $INCLUDE (STC15.INC) ;包含IAP15W4K58S4寄存器定义文件 LED4 EQU P2.7 ;指示灯控制引脚定义 ORG 0000H LJMP MAIN ORG 0063H ;T2的中断服务程序入口地址 LJMP T2_ISR MAIN: MOV SP,#70H ;设置堆栈指针 MOV R2,#100 ;中服程序中减一计数器的初值为100 LCALL TIMER2INIT ;调用T2初始化子程序 ORL IE2, #04H ;允许T2中断 SETB EA ;开放CPU中断 SJMP $
[例7-2] 设时钟频率为11.0592 MHz, 用定时器T2定时, 使连接P2.7的指示灯亮0.2s,灭0.8s 。 TIMER2INIT: ;10毫秒@11.0592MHz ANL AUXR,#0FBH ;定时器时钟12T模式 MOV T2L,#00H ;设置定时初值 MOV T2H,#0DCH ;设置定时初值 ORL AUXR,#10H ;T2开始计时 RET 利用STC-ISP工具生成定时器的初始化代码
[例7-2] 设时钟频率为11.0592 MHz, 用定时器T2定时, 使连接P2.7的指示灯亮0.2s,灭0.8s 。 T2_ISR: DEC R2 ;初值R2=100 CJNE R2, #80, R2NOT80 ;若R2< 80, 则C置1, 否则C=0 R2NOT80: ;等于80的情况与大于80的情况一样处理, 此时Cy=0 JC R2LESS80 CLR LED4 ;P2.7=0即输出低电平时灯亮(0.2s) LJMP T2_END R2LESS80: SETB LED4 ;P2.7=1即输出高电平时灯灭(0.8s) CJNE R2, #0, T2_END ;R2减到0时重新赋值R2=100, 否则返回 MOV R2, #100 LJMP T2_END ;本行指令可去掉 T2_END: RETI END
[例7-2] 设时钟频率为11.0592 MHz, 用定时器T2定时, 使连接P2.7的指示灯亮0.2s,灭0.8s 。 对应的C语言代码如下: #include "stc15.h " //包含IAP15W4K58S4的寄存器定义文件 sbit LED4=P2^7; //指示灯控制引脚定义 unsigned char msnum; //10毫秒定时中断次数减一计数器变量 void Timer2Init(void); //T2初始化子函数声明 void main(void) { msnum=100; //减一计数器变量初值100 Timer2Init(); //调用T2初始化子函数 IE2 |= 0x04; //允许T2中断 EA = 1; //开放CPU中断 while (1); //循环等待中断 }
[例7-2] 设时钟频率为11.0592 MHz, 用定时器T2定时, 使连接P2.7的指示灯亮0.2s,灭0.8s 。 void Timer2Init(void) //10毫秒@11.0592MHz { AUXR &= 0xFB; //定时器时钟12T模式 T2L = 0x00; //设置定时初值 T2H = 0xDC; //设置定时初值 AUXR |= 0x10; //T2开始计时 } //T2中断服务函数 void t2_isr(void) interrupt T2_VECTOR msnum--; //减一计数器变量初值100(定时1s) if(msnum==0) msnum=100; //减到0时重新赋初值 if(msnum<80) LED4=1; //P2.7=1即输出高电平时灯灭(0.8s) else LED4=0; // P2.7=0即输出低电平时灯亮(0.2s) 利用STC-ISP工具生成 定时器的初始化代码
7.1.5 定时/计数器编程举例 [例7-3] 利用定时器的门控方式实现正脉冲的脉宽测量。 7.1.5 定时/计数器编程举例 [例7-3] 利用定时器的门控方式实现正脉冲的脉宽测量。 当GATE=1, TRx=1, 只有引脚INTx输入高电平时, Tx 才被允许计数, 利用这一特点, 就可以测量引脚INTx上 正脉冲的宽度。 Tx的启动(1)信号 以T0为例的门控法测 量示意图如下图所示。 x=0, 1 INT0 x=0 引脚P3.2/INT0 图7-6 利用门控法测量脉冲宽度
[例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 …… ;计算脉宽或送显示器显示
[例7-3] 利用定时器的门控方式实现正脉冲的脉宽测量。 思考: (1)当脉冲宽度超过定时器的最大定时时间应该如何 处理? (2)在动态读取运行中的定时/计数器的计数值时,如 果不加注意,就可能出错。这是因为不可能在同一时 刻同时读取TH0和TL0中的计数值。比如,先读TL0 后读TH0,因为定时/计数器处于运行状态,在读TL0 时尚未产生向TH0进位,而在读TH0前已产生进位, 这时读得的TH0就不对了;同样,先读TH0后读TL0 也可能出错。如何解决这个问题? 加定时中断 CLR TR0 ;关定时器T0
§7.2可编程时钟输出模块及其应用 在控制系统中, 有时需要为单片机外部的器件提供时 钟控制, 为此, IAP15W4K58S4单片机提供了6路可编程 时钟输出功能。 MCLKO/P5.4, T0CLKO/P3.5, T1CLKO/P3.4, T2CLKO/P3.0, SysClkO/P5.4 T3CLKO/P0.4, T4CLKO/P0.5。 以上2路STC15F2K60S2无 只有内部R/C时钟频率为12MHz以下时, MCLKO/P5.4 才能正常输出。
§7.2.1 可编程时钟输出的相关寄存器 表7-3 可编程时钟输出的相关寄存器及其控制位 寄存器 地址 D7 D6 D5 D4 D3 D2 §7.2.1 可编程时钟输出的相关寄存器 表7-3 可编程时钟输出的相关寄存器及其控制位 寄存器 地址 D7 D6 D5 D4 D3 D2 D1 D0 复位值 CLK_DIV 97H MCKO_S1 MCKO_S0 ADRJ TX_RX — CLKS2 CLKS1 CLKS0 0000x000B INT_ CLKO 8FH - EX4 EX3 EX2 T2CLKO T1CLKO T0CLKO x000x000B T4T3M D1H TR4 T4x12 T4CLKO TR3 T3x12 T3CLKO 00000000B
7.2.1 可编程时钟输出的相关寄存器 1、主时钟输出 主时钟可以是内部高精度R/C时钟,也可以是外部输入 的时钟或外部晶体振荡产生的时钟。 通过设置CLK_DIV寄存器的MCKO_S1和MCKO_S0 两位, 可将MCLKO/P5.4 管脚配置为主时钟输出, 同时, 还可设置输 出频率。 教材: IAP15W4K58S4(应为STC15F60S2)单片机的MCLKO/P5.4只可以对外输出内部RC时钟, IAP15W4K58S4手册上对外输出的是系统频率, 时钟输出引脚为SysClkO/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
1、主时钟输出 时钟分频寄存器CLK_DIV 主时钟的输出频率由MCKO_S1和MCKO_S0控制。 位号 D7 D6 D5 D4 D3 D2 D1 D0 名称 MCKO_S1 MCKO_S0 ADRJ TX_RX - CLKS2 CLKS1 CLKS0 主时钟的输出频率由MCKO_S1和MCKO_S0控制。 表7-4 主时钟的输出频率设置 MCKO_S1 MCKO_S0 主时钟的输出频率 无主时钟输出 1 主时钟输出频率= MCLK/1 主时钟输出频率= MCLK/2 主时钟输出频率= MCLK/4 (P5.4/MCLKO) /SysClkO/P5.4 SysClk/1 SysClk/2 SysClk/4 SysClk/16 其中, MCLK指主时钟频率:可以是内部高精度R/C时钟, 也可以是外部输入的时钟或外部晶体振荡产生的时钟。 教材: IAP15W4K58S4(应为STC15F60S2)单片机的MCLKO/P5.4只可以对外输出内部RC时钟, IAP15W4K58S4手册上对外输出的是系统频率, 时钟输出引脚为SysClkO/P5.4。 5V芯片对外可编程时钟输出速度最快不超过13.5MHz
时钟分频寄存器CLK_DIV (PCON2) 分频系数选择表 位号 D7 D6 D5 D4 D3 D2 D1 D0 名称 MCKO_S1 MCKO_S0 ADRJ Tx_Rx - CLKS2 CLKS1 CLKS0 CLKS2, CLKS1,CLKS0: 设置分频系数,如表 所示。 CLKS2 CLKS1 CLKS0 分频后CPU实际工作时钟(系统时钟) 主时钟频率/1,不分频 1 主时钟频率/2 主时钟频率/4 主时钟频率/8 主时钟频率/16 主时钟频率/32 主时钟频率/64 主时钟频率/128 补充参考 其中, MCLK指主时钟频率:可以是内部高精度R/C时钟, 也可以是外部输入的时钟或外部晶体振荡产生的时钟。
2. T4CLKO/P0. 5, T3CLKO/P0. 4, T2CLKO/P3. 0, T1CLKO/P3. 4, T0CLKO/P3 T4CLKO/P0.5、 T3CLKO/P0.4、 T2CLKO/P3.0、 T1CLKO/P3.4和T0CLKO/P3.5的时钟输出分别由T4和 T3控制寄存器T4T3M中的T4CLKO, T3CLKO位和外部 中断使能和时钟输出寄存器INT_CLKO (也称AUXR2) 的T2CLKO、T1CLKO和T0CLKO位控制。 当TxCLKO=0时, 不允许时钟输出功能; 当TxCLKO=1 时, 允许相应的时钟输出功能, 输出时钟频率为定时/计 数器的溢出率/2, 相应地, 定时器需要工作在自动重装模 式, 不允许定时器中断, 以免CPU反复进中断。 寄存器 地址 D7 D6 D5 D4 D3 D2 D1 D0 INT_CLKO 8FH - EX4 EX3 EX2 T2CLKO T1CLKO T0CLKO T4T3M D1H TR4 T4x12 T4CLKO TR3 T3x12 T3CLKO
7.2.2 可编程时钟输出的编程实例 IAP15W4K58S4时钟输出引脚为SysClkO/P5.4 STC15F60S2时钟输出引脚为MCLKO/P5.4 1、若要使用主时钟输出, 例, 从P5.4/MCLKO输出时钟信 号, 频率是SYSclk (系统时钟), 只需加入下面语句即可: MOV CLK_DIV, #40H ;汇编语言程序设置CLK_DIV CLK_DIV = 0x40; //在C语言程序中设置CLK_DIV 当CLK_DIV=40H时, SYSclk (系统时钟)就是主时钟, 也是输出时钟。 适用STC15F60S2
7.2.2 可编程时钟输出的编程实例 2. 若要从T4CLKO/P0.5, T3CLKO/P0.4, T2CLKO/P3.0, T1CLKO/P3.4或T0CLKO/P3.5输出时钟, 需要在用户 程序中进行下面的设置: ① 设置定时/计数器的工作方式(T0和T1设置为方式0); ② 设置16位重装载值(分别设置TLx和THx); ③ 启动定时/计数器工作(将TRx设置为1); ④ 将TxCLKO位置1, 让定时/计数器的溢出在对应引脚 上输出时钟。
7.2.2 可编程时钟输出的编程实例 下面以一个具体实例,说明如何使用IAP15W4K58S4单 片机的可编程时钟输出功能。 【例7-4】 设时钟频率SYSclk=11.0592MHz, 设计程序, 从T0 (P3.4/T1CLKO)引脚输出频率为19.2KHz的时钟; 从T1 (P3.5/T0CLKO)引脚输出频率为38.4KHz的时钟。 解: 使用IAP15W4K58S4的可编程时钟输出功能完成所 需要求。在下面的程序设计中 (C语言程序),T0和T1 均工作在1T模式。
例7-4 时钟11.0592MHz, T0脚输出19.2KHz; T1 输出38.4KHz #include "stc15.h" //包含IAP15W4K58S4寄存器定义头文件 void main(void) { TMOD = 0x00; //T0,T1工作方式0, 16位自动重装计数器 AUXR = AUXR | 0x80; //T0工作在1T模式 AUXR = AUXR | 0x40; //T1工作在1T模式 //设置T01的16位自动重装计数初值,输出频率=11059200/2/288=19200Hz TH01 = (65536-288)>>8; TL01 = (65536-288); //置T10的8位自动重装计数初值,输出11059200/2/144 = 38400Hz TH10 = (65536-144)>>8; TL10 = (65536-144); TR0 = 1; //启动T0计数, 对系统时钟进行分频输出 TR1 = 1; //启动T1计数, 对系统时钟进行分频输出 INT_CLKO =INT_CLKO|0x03; //允许时钟输出 //至此时钟已经输出, 可通过示波器看到输出时钟频率 while(1); } 例7-4 时钟11.0592MHz, T0脚输出19.2KHz; T1 输出38.4KHz 计数次数288 T0 (P3.4/T1CLKO)输出19.2KHz; T1 (P3.5/T0CLKO) 输出38.4KHz。
【例7-5】设时钟频率为11.0592MHz, 使用定时器2的时钟输出功能, 使P3.0/T2CLKO口输出38.4KHZ的方波。 $INCLUDE (STC15.INC) ;IAP15W4K58S4寄存器定义文件 T38_4KHz EQU 0FF70H ;(65536-11059200/ 38400/2) ;(65536-144)=65392= 0FF70H ;1T模式下的重装时间常数 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 计数次数144 Ax51 Assembler User's Guide → Writing Assembly Programs→ Expressions and Operators→ Operators
【例7-5】对应的C语言代码如下: #include "stc15.h" //包含IAP15W4K58S4寄存器定义头文件 #define T38_4KHz (65536-11059200/38400/2) //输出38.4KHZ方波的的计数初值(1T模式下) void main(void) { T2H= T38_4KHz>>8; //设置T2重装时间常数高字节 T2L = T38_4KHz; //设置T2重装时间常数低字节 AUXR = 0x10; //启动定时器T2 INT_CLKO |= 0x04; //允许T2时钟输出 while (1); //循环 }
第7章 作业 7.3,7.4,7.5 7.6-7.7涉及STC实验箱平台, 在综合训 练中参考训练用开发系统。