내 연락처 정보
우편메소피아@프로톤메일.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
타이머와 카운터는 시간 간격을 측정하거나 이벤트를 계산하는 데 사용되는 하드웨어 모듈입니다. 정확한 시간 지연 생성, 주파수 측정, 외부 이벤트 계산 등과 같은 다양한 응용 분야에서 사용할 수 있습니다. 51 마이크로 컨트롤러의 타이머는 마이크로 컨트롤러의 내부 리소스에 속하며 회로의 연결 및 작동은 마이크로 컨트롤러 내부에서 완료됩니다. 이 기사에서는 51 마이크로 컨트롤러의 작동 원리, 구성 방법 및 타이머 및 카운터 적용에 대해 자세히 소개합니다.
이 장에서는 인터럽트 관련 지식을 다룹니다. 특정 내용은 다음을 참조하세요.인터럽트 시스템 설명
참고: 타이머 리소스는 마이크로 컨트롤러 모델과 관련이 있습니다. 서로 다른 마이크로 컨트롤러 모델에는 타이머 수와 작동 방법이 다를 수 있지만 일반적으로 T0 및 T1의 작동 방법은 모든 51개의 마이크로 컨트롤러에 공통됩니다.
타이머는 마이크로 컨트롤러 내부의 작은 알람 시계와 같습니다. 시계의 출력 신호에 따라 계산 단위의 값이 "1초"마다 1씩 증가합니다. 카운팅 유닛의 값이 "설정된 알람 알림 시간"까지 증가하면 카운팅 유닛은 인터럽트 시스템에 인터럽트 요청을 발행하고 "링 알림"을 생성하며 프로그램이 실행을 위해 인터럽트 서비스 기능으로 점프하도록 합니다. .
타이머/카운터의 작동 원리는 클럭 펄스를 기반으로 합니다. 타이머 모드에서는 내부 클럭 소스를 사용하여 계산하고, 카운터 모드에서는 외부 펄스 소스를 사용하여 계산합니다. 각 타이머/카운터에는 현재 카운트 값을 저장하는 레지스터가 있습니다.
타이밍 및 카운팅 기능은 특수 기능 레지스터 TMOD의 제어 비트에 의해 제어됩니다. CT Csqrt{T}씨티 선택을 하기 위한 TMOD 레지스터의 정보는 다음 표와 같습니다. 2개의 타이머/카운터에는 TMOD의 M1 및 M0을 통해 선택된 4개의 작동 모드가 있음을 알 수 있습니다. 두 타이머/카운터의 모드 0, 1, 2는 동일하지만 모드 3은 각 모드의 기능이 다릅니다.
TMOD 레지스터에 M1과 M0을 설정하면 타이머/카운터 0과 1은 4가지 다른 작동 모드를 갖게 됩니다.
작업 모드 다이어그램은 다음과 같습니다:
모드 1은 TH0 및 TL0의 16비트가 모두 사용된다는 점을 제외하면 모드 0과 완전히 동일합니다. 이 모드에서는 TL0의 8비트 오버플로가 TH0으로 전달되고, TH0의 오버플로는 TCON에 오버플로 플래그 TF0을 설정합니다.
GATE=0(TMOD.3)일 때 TR0=1이면 타이머가 카운트됩니다. GATE=1일 때 외부 입력 INTO는 타이머 0을 제어할 수 있으므로 펄스 폭 측정이 가능합니다. TRO는 TCON 레지스터의 제어 비트입니다. TCON 레지스터의 각 비트에 대한 구체적인 기능 설명은 이전 섹션의 TCON 레지스터 소개를 참조하세요.
참고: STC89C51RC/RD+ 시리즈 마이크로컨트롤러의 타이머에는 두 가지 계산 속도가 있습니다. 하나는 12T 모드로, 기존 8051 마이크로컨트롤러와 동일하게 12클럭마다 1을 추가합니다. 다른 하나는 6T 모드로, 6클럭마다 1을 추가합니다. 기존 8051 마이크로컨트롤러의 2배인 T0 속도는 사용자 프로그램을 레코딩할 때 STC-ISP 프로그래머에서 설정됩니다.
이 모드에서 타이머/카운터는 8비트 카운터를 자동으로 다시 로드할 수 있습니다. TL0의 오버플로는 TF0을 설정할 뿐만 아니라 TH0의 내용을 TL0으로 다시 로드합니다. (TH0을 먼저 설정할 수 있으며, 재설치 시 TH0의 내용은 변경되지 않습니다.)
타이머 0의 경우 이 모드에서는 타이머 1이 카운트를 중지하며 효과는 TR1을 0으로 설정하는 것과 같습니다.
타이머 0의 경우 이 모드에서는 타이머 0의 TL0 및 TH0이 두 개의 독립적인 8비트 카운터로 작동합니다. 아래 그림은 모드 3의 타이머 0의 논리 다이어그램을 보여줍니다. TL0은 타이머 0의 제어 비트를 차지합니다. CT Csqrt{T}씨티 , GATE, TRO, INTO 및 TFO. THO는 타이머 기능(카운터 주기)으로 제한되며 타이머 1의 TR1과 TF1을 점유합니다. 이때 TH0은 타이머 1 인터럽트를 제어합니다.
추가 8비트 타이머/카운터를 추가하기 위해 모드 3이 제공되어 마이크로컨트롤러에 3개의 타이머/카운터를 제공합니다. 모드 3은 타이머/카운터 0에만 적용 가능합니다. 타이머 T1이 모드 3에 있을 때 TR1-0과 동일하며 카운트를 중지하고 T0은 두 개의 타이머로 사용할 수 있습니다.
참고: STC-ISP 프로그래밍 도구에는 계산할 시간의 초기 값이 함께 제공됩니다. 선택한 모드에 따라 코드를 복사할 수 있습니다.
LED1 표시등은 타이머 0 인터럽트를 통해 1초 간격으로 깜박이도록 제어됩니다. 물리적 다이어그램은 D1이 P2_0 핀에 연결되어 있으며 1밀리초 간격으로 인터럽트가 트리거됩니다. 인터럽트 트리거 기능은 1000일 때 1초입니다.
#include <REGX52.H>
sbit LED1 = P2^0;
void External0_ISR(void) interrupt 1
{
static unsigned int count = 0;
TL0 = 0x18; //需要手动复原
TH0 = 0xFC; //需要手动复原
// 中断处理代码
if(count == 1000)
{
count = 0;
LED1 = !LED1;
}
count++;
}
void Timer0_Init(void) //1毫秒@12.000MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
ET0 = 1;//打开T0中断
EA = 1;//打开总中断
TR0 = 1; //定时器0开始计时
}
void main()
{
Timer0_Init();
while(1)
{
}
}
이 데모에서는 INTRIS.H 라이브러리의 _crol_left Shift 및 _cror_right Shift 기능이 사용됩니다. KEY1 버튼을 누르면 LED 주행등이 방향 상태를 전환하고 깜박입니다. 물리적인 그림 연결: K1은 P0_0 핀에 연결되고 8개의 LED 조명은 P2 핀에 삽입됩니다.
#include <REGX52.H>
#include <INTRINS.H>
sbit KEY1 = P0^0;
sbit KEY2 = P0^1;
unsigned char LEDMode;
void DelayXms(unsigned int xms) //@12.000MHz
{
unsigned char data i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void Timer0_Init(void) //1毫秒@12.000MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
ET0 = 1;//打开T0中断
EA = 1;//打开总中断
TR0 = 1; //定时器0开始计时
}
void External0_ISR(void) interrupt 1
{
static unsigned int count = 0;
TL0 = 0x18; //需要手动复原
TH0 = 0xFC; //需要手动复原
// 中断处理代码
if(count == 1000)
{
count = 0;
if(LEDMode == 0)
P2 = _crol_(P2,1);
if(LEDMode == 1)
P2 = _cror_(P2,1);
}
count++;
}
unsigned char Getkey()
{
unsigned char keyNumber = 0;
if(KEY1 == 0)
{
DelayXms(5);
while(KEY1 == 0);
DelayXms(5);
keyNumber = 1;
}
if(KEY2 == 0)
{
DelayXms(5);
while(KEY2 == 0);
DelayXms(5);
keyNumber = 2;
}
return keyNumber;
}
void main()
{
unsigned char keyNum = 0;
P2 = 0xfe;
Timer0_Init();
while(1)
{
keyNum = Getkey();
if(keyNum)
{
if(keyNum == 1)
{
LEDMode++;
if(LEDMode>=2)
{
LEDMode = 0;
}
}
}
}
}
이 데모 코드에서는 LCD1602 모듈을 디스플레이로 사용합니다. LCD1602 모듈은 자세히 설명하지 않으며 나중에 특별한 장 지침이 제공됩니다. LCD1602 라이브러리가 필요하시면 저에게 개인적으로 메시지를 보내주세요. 물리적 사진 연결: LCD1602 모듈을 보드에 연결하기만 하면 됩니다.
#include <REGX52.H>
#include "LCD1602.h"
unsigned char Sec=55,Min=59,Hour;//秒分时
void DelayXms(unsigned int xms) //@12.000MHz
{
unsigned char data i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void Timer0_Init(void) //1毫秒@12.000MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
ET0 = 1;//打开T0中断
EA = 1;//打开总中断
TR0 = 1; //定时器0开始计时
}
void External0_ISR(void) interrupt 1
{
static unsigned int count = 0;
TL0 = 0x18; //需要手动复原
TH0 = 0xFC; //需要手动复原
// 中断处理代码
if(count == 1000)
{
count = 0;
Sec++;
if(Sec == 60)
{
Sec = 0;
Min++;
if(Min == 60)
{
Min = 0;
Hour++;
if(Hour == 24)
{
Hour = 0;
}
}
}
}
count++;
}
void main()
{
Timer0_Init();
LCD_Init();
LCD_ShowString(1,1,"Time:");
LCD_ShowString(2,1,"00:00:00");
while(1)
{
LCD_ShowNum(2,1,Hour,2);
LCD_ShowNum(2,4,Min,2);
LCD_ShowNum(2,7,Sec,2);
}
}