采用定时器/计数器实现1s定时,单片机使用晶振频率为12MHz,请计算TH0和TL0赋
时间: 2024-02-19 13:59:36 浏览: 14
值。
在晶振频率为12MHz的情况下,计数器每计数一次所需要的时间为:
1 / (12MHz / 12) = 1us
为了实现1s定时,需要计数器计数的次数为:
1s / 1us = 1000000
由于定时器/计数器的计数范围为0~65535,因此需要使用两个8位寄存器TH0和TL0来装载计数初值,使得计数器可以计数到1000000。
则TH0和TL0的初值应为:
65536 - 1000000 = 55136
即TH0 = 0xD7,TL0 = 0x30。
相关问题
设单片机晶振频率为6MHz,选定用定时器/计数器T0工作方式1,定时100ms产生一次中断,使接在P1.0上的发光二极管间隔1S亮一次,亮10后得止,请计算T0的计数初值并编程。
根据工作方式1的定义,定时器/计数器T0每计数一次需要的时间为:
$$
T_{T0} = \frac{1}{f_{OSC}} \times 2^{\text{SMOD}} \times 2^{\text{TCLK}} = \frac{1}{6 \text{MHz}} \times 2^0 \times 2^0 = 166.67 \text{ ns}
$$
为了产生100ms的定时,需要计数的次数为:
$$
N = \frac{T}{T_{T0}} = \frac{100 \text{ ms}}{166.67 \text{ ns}} = 600000
$$
因为计数器是8位的,所以计数的初值为:
$$
\text{TH0} = \frac{N}{256} = \frac{600000}{256} \approx 2343
$$
$$
\text{TL0} = N \mod 256 = 600000 \mod 256 = 112
$$
因为需要让接在P1.0上的发光二极管间隔1S亮一次,所以需要再设置一个计数器,每隔1S计数一次,当计数到10时停止闪烁。计数器每计数一次需要的时间为:
$$
T_{1s} = \frac{1}{f_{OSC}} \times 2^{\text{SMOD}} \times 2^{\text{PS}} = \frac{1}{6 \text{MHz}} \times 2^0 \times 2^3 = 1 \text{ ms}
$$
计数器的初值为:
$$
\text{TH1} = \frac{T_{1s}}{256} = \frac{1 \text{ ms}}{256} \approx 4
$$
$$
\text{TL1} = T_{1s} \mod 256 = 1 \text{ ms}
$$
完整的代码如下:
```c
#include <reg52.h>
sbit LED = P1^0;
void main() {
TMOD = 0x11; // 设置T0和T1为工作方式1
TH0 = 0x09;
TL0 = 0x30; // 设置T0的计数初值为2343
TH1 = 0x04;
TL1 = 0x00; // 设置T1的计数初值为4
ET0 = 1;
ET1 = 1; // 开启T0和T1的中断允许
TR0 = 1;
TR1 = 1; // 启动T0和T1计数器
EA = 1; // 开启总中断允许
while (1); // 始终循环等待中断
}
void T0_ISR() interrupt 1 {
static unsigned char count = 0;
TH0 = 0x09;
TL0 = 0x30; // 重新设置T0的计数初值
count++;
if (count == 100) {
count = 0;
LED = ~LED; // 翻转P1.0口的电平
}
}
void T1_ISR() interrupt 3 {
static unsigned char count = 0;
TH1 = 0x04;
TL1 = 0x00; // 重新设置T1的计数初值
count++;
if (count == 10) {
TR0 = 0;
TR1 = 0; // 停止T0和T1计数器
LED = 0; // 熄灭P1.0口的电平
while (1); // 始终循环等待
}
}
```
设单片机晶振频率为6MHz ,选用定时器/计数器T0工作方式1,定时100ms产生一次中断,使接在P1.0上的发光二极管间隔1S亮一次,(亮1S,灭1S),亮10后停止。请计算T0的计数初值并编程。(10分)
根据定时器/计数器T0工作方式1的计数公式可得:
计数初值 = 65536 - (所需计数次数 × 每次计数所需的机器周期数)
其中,所需计数次数为:
所需计数次数 = 定时时间 / 计数器溢出时间
其中,定时时间为100ms,计数器溢出时间为 1 / (晶振频率 / 12),因为工作方式1时,T0的时钟源为晶振频率 / 12。
将上述值代入计算公式可得:
所需计数次数 = 100ms / (1 / (6MHz / 12)) = 600
计数初值 = 65536 - (600 × 12) = 58336
因此,T0的计数初值为58336,编程如下:
```c
#include <reg52.h>
#define LED P1_0
void main() {
TMOD = 0x01; // T0工作方式1
TH0 = 0xE3; // 计数初值为58336
TL0 = 0xC0;
TR0 = 1; // 启动T0
ET0 = 1; // 允许T0中断
EA = 1; // 开启总中断
LED = 0; // 初始时关闭LED
while (1); // 等待中断
}
void T0_ISR() interrupt 1 {
static unsigned char cnt = 0; // 计数亮灭次数
static bit led_state = 0; // LED状态,0表示灭,1表示亮
cnt++;
if (cnt == 20) { // 亮灭10次
TR0 = 0; // 停止T0
ET0 = 0; // 禁止T0中断
} else {
if (led_state) {
LED = 0;
led_state = 0;
TH0 = 0xE3; // 重新设置计数初值
TL0 = 0xC0;
} else {
LED = 1;
led_state = 1;
TH0 = 0xE2;
TL0 = 0x9C;
}
}
TF0 = 0; // 清除T0中断标志
}
```