TMOD的字节地址位89H, 不能位寻址, TMOD共八位, 高四位控制T1工作方式, 低四位控制T0工作方式
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|
GATE | C/T’ | M1 | M0 | GATE | C/T’ | M1 | M0 |
M1 M0 | 工作方式 |
---|---|
0 0 | 方式0, 13位定时器/计数器 |
0 1 | 方式1, 16位定时器/计数器 |
1 0 | 方式2, 8位的常数自动重新装载的定时器/计数器 |
1 1 | 方式3, 仅适用于T0, 此时T0分为2个八位计数器, T1停止计数 |
TCON的字节地址为88H, 可位寻址
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|
TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
其低四位与外部中断有空
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | |
---|---|---|---|---|---|---|---|---|
ICON | TF1 | TR1 | TF0 | TR0 | IET | IT1 | IE0 | IT0 |
位地址 | 8FH | – | 8DH | – | 8BH | 8AH | 89H | 88H |
若使用定时器T0, 采用方式2定时, 输出周期为400us占空比位25%的矩形脉冲(晶振频率为12MHz)
定时时间 = 计数值 * 机器周期
所以, 100us = n * 1us -> n = 100
计数值 = 最大计数值 - 计算初值
所以, 100 = 256 - x, 解得x = 256 - 100
综上, TH0 = TL0 = 256 - 100;
工作方式2为自动恢复初值(初值自动装入)的8为定时器/计数器, TLx(x = 0, 1)作为常数缓冲器, 当TLx计数溢出时, 在溢出标志位TFx置1的同时, 还自动将THx中的初值发送至TLx, 使TLx从初值开始重新计数.
/*
* 功能实现: 使用T0, 采用方式2定时中断, 在P1.0引脚上输出周期为400us, 占空比为25%的矩形脉冲
* 编写环境: Neovim + Keil5
* 硬件仿真: Proteus 8 Professional
* 日期: 2022-11-15
*/
#include
sbit Pluse = P1^0; // 定义P1.0口为Pulse
unsigned char count = 0;
int main(void)
{
TMOD = 0x01; // 定时器T0为方式1
TH0 = 256 - 100; // 设置定时器初值
TL0 = 256 - 100;
Pluse = 0; // P1.1输出低电平
EA = 1; // 总中断开
ET0 = 1; // T0中断开
TR0 = 1; // 启动T0
while(1) // 循环等待
{
;
}
return 0;
}
void timer0() interrupt 1 // T0中断程序
{
TH0 = 256 - 100; // 重新赋值
TL0 = 256 - 100;
count++;
if (1 == count) // 100us过后, 高电平持续时间结束, 需将P1.1变为低电平
{
Pluse = 0;
}
else if (4 == count) // (4-1) * 100us过后, 低电平持续时间结束, 需将P1.1变为高电平
{
Pluse = 1;
count = 0; // 一个脉冲周期结束, 将count清零
}
return;
}