2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
1. Kideoskillaattori (kideoskillaattori) lähettää pulsseja ja tallentaa pulssien lukumäärän ajoitusta varten.
2. Pulssin taajuus on kellotaajuus ja tämän taajuuden käänteisluku on oskillaatiojakso (kellojakso), joka on myös tietokoneen pienin aikayksikkö.
Kuten kuvasta näkyy: kideoskillaattorin taajuus on 11,0592MHz, jolloin sen kellojakso on 1/11,0592MHz (sekunti), eli yksi pulssijakso kestää niin monta sekuntia.
3. Konesykli on CPU-sykli, ja perustoiminnon vaatimaa aikaa kutsutaan konejaksoksi. Yleensä konesykli koostuu useista kellojaksoista. Normaalisti se on 12 kertaa / 6 kertaa.
Konfiguroimalla asiaankuuluvat rekisterit: Seuraava kuva esittää ajastimen asiaankuuluvat rekisterit.
TF0:定时器T0溢出中断标志,当定时器0开始计数时,计数到规定的时间时,定时器产生了溢出。TF0自动由0变位1(由硬件置1)。
如果不用中断,需要手动清零。
TR0:定时器T0的控制位,当为1时,定时器T0才能计数,相当于T0的开关(由软件控制)。
GATE:门控制位,当GATE=0时:计数条件只有TR1一个(TR1=1就计数,TR1=0就不计数)。
当GATE=1时:是否计数不仅取决于TR1还取决于INT1引脚
C/T :时钟输入选择为,为1时,时钟从外部引脚P3.5口输入;为0时,时钟从内部输入
M1 M0
0 0 :13位定时器,使用高8位和低5位
0 1 :16位定时器,全用
1 0 :8位自动重装载定时器,当溢出时将TH1存放的值自动重装入TL1.
1 1 :定时器无效
Ajastimessa T0 on yhteensä 16 bittiä, jaettuna korkeaan 8-bittiseen TH0 ja matalaan 8-bittiseen TL0:aan. Siksi yhteensä 2^16 numeroa (65536) voidaan laskea, ja 1 numeron laskentajakso on 1,085us, joten oletusarvoisesti laskenta aloitetaan nollasta ja kumulatiivinen ajoitus on noin 71 ms.
Koodi ①:
#include <REGX52.H>
sbit LED1 = P3^7;
void main(void)
{
int cnt = 0;
LED1 = 1;//先让灯熄灭的状态
/*1、选择定时器T0,并配置为16位定时器*/
TMOD =0x01; // 0000 0001
/*
2、定一个10ms的时间,数1下需要1.085us
10ms需要数则需要数9216下,那从65536-9126=56320
从56320这里开始数,数9216下就到了65536。当超过了
65536时就报表了,控制寄存器TCON的TF0由0变为1
*/
TL0 = 0x00; //0000 0000
TH0 = 0xDC;//1101 1100
/*3、打开定时器T0*/
TR0 = 1;
TF0 = 0;//先个溢出标志清零
while(1)
{
if(TF0 == 1)//10ms报表了
{
TF0 = 0;//软件清零,现在不使用中断
TL0 = 0x00; //重新给初值
TH0 = 0xDC;
cnt++;
if(cnt == 100)//数100次,相当于1s
{
cnt = 0;
LED1 = !LED1;
}
}
}
}
【Huomautus】
Koodin optimointi②:
#include <REGX52.H>
sbit LED1 = P3^7;
void Timer0_Init_10ms(void)//定时器初始化10ms
{
TMOD =0x01;
TL0 = 0x00; //0000 0000
TH0 = 0xDC;//1101 1100
TR0 = 1;
TF0 = 0;
}
void main(void)
{
int cnt = 0;
LED1 = 1;//先让灯熄灭的状态
Timer0_Init_10ms();
while(1)
{
if(TF0 == 1)//10ms报表了
{
TF0 = 0;//软件清零,现在不使用中断
TL0 = 0x00; //重新给初值
TH0 = 0xDC;
cnt++;
if(cnt == 100)//数100次,相当于1s
{
cnt = 0;
LED1 = !LED1;
}
}
}
}
Kapseloi ajastimen T0 alustus funktioksi ja kutsu sitä tarvittaessa suoraan.
Mutta käyttämällä TMOD = 0x01, tällaisessa alustuksessa on myös puutteita:
假如定时器T1正在使用,且为16位定时器。则TMOD的高4位应该为:0x1(0001)
而我们使用定时器T0时TMOD初始为0x01,则TMOD的高4位为0x0(0000),则把定时器T1变为一个13位定时器了。所以还需要改进
Koodin optimointi ③:
#include <REGX52.H>
sbit LED1 = P3^7;
void Timer0_Init_10ms(void) //10毫秒@11.0592MHz
{
//AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0xDC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
void main(void)
{
int cnt = 0;
LED1 = 1;//先让灯熄灭的状态
Timer0_Init_10ms();
while(1)
{
if(TF0 == 1)//10ms报表了
{
TF0 = 0;//软件清零,现在不使用中断
TL0 = 0x00; //重新给初值
TH0 = 0xDC;
cnt++;
if(cnt == 100)//数100次,相当于1s
{
cnt = 0;
LED1 = !LED1;
}
}
}
}
Havaitsemme, että TMOD:n alustus on:
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
Mitä hyötyä tällaisesta alustamisesta on?
假如定时器T1正在使用,且为16位定时器。则TMOD的高4位应该为:0x1(0001),而要使用定时器T0,且也为16位定时器,则TMOD = 0x11;
TMOD &= 0xF0;表示TMOD = TMOD & 0xf0,则与出来的TMOD = 0x10,由此可见,这一步就是让TMOD的高4位不变,低4位清零。
TMOD |= 0x01;表示TMOD = TMOD | 0x01,则或出来的TMOD = 0x11,由此可见,这一步就是让TMOD的高4位不变,低4位初始化。
通过这样初始化,既保证了TMOD的高4位不变(不改变定时器T1的初始化),由对低4位进行了改变(对定时器T0初始化)。
当然:也可以直让TMOD = 0x11;