Berbagi teknologi

Mikrokontroler Puzhong 51: penjelasan detail dan penerapan timer dan counter (7)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Masukkan deskripsi gambar di sini

perkenalan

Pengatur waktu dan penghitung adalah modul perangkat keras yang digunakan untuk mengukur interval waktu atau menghitung peristiwa. Mereka dapat digunakan dalam banyak aplikasi seperti menghasilkan waktu tunda yang tepat, mengukur frekuensi, menghitung kejadian eksternal, dll. Pengatur waktu mikrokontroler 51 milik sumber daya internal mikrokontroler, dan koneksi serta pengoperasian rangkaiannya diselesaikan di dalam mikrokontroler. Artikel ini akan memperkenalkan secara rinci prinsip kerja, metode konfigurasi dan penerapan timer dan counter pada 51 mikrokontroler.

Bab ini akan membahas pengetahuan terkait interupsi.Penjelasan sistem interupsi

Catatan: Sumber daya pengatur waktu terkait dengan model mikrokontroler. Model mikrokontroler yang berbeda mungkin memiliki jumlah pengatur waktu dan metode pengoperasian yang berbeda, tetapi secara umum, metode pengoperasian T0 dan T1 umum untuk seluruh 51 mikrokontroler.

Cara kerja pengatur waktu

Pengatur waktu seperti jam alarm kecil di dalam mikrokontroler. Menurut sinyal keluaran jam, nilai satuan penghitung bertambah satu setiap "satu detik". Ketika nilai unit penghitung meningkat ke "setel waktu pengingat alarm", unit penghitung akan mengeluarkan permintaan interupsi ke sistem interupsi, menghasilkan "pengingat dering", dan menyebabkan program melompat ke fungsi layanan interupsi untuk dieksekusi .

Prinsip kerja timer/counter didasarkan pada pulsa clock. Dalam mode pengatur waktu, mereka menggunakan sumber jam internal untuk menghitung; dalam mode penghitung, mereka menggunakan sumber pulsa eksternal untuk menghitung. Setiap pengatur waktu/penghitung memiliki register yang menyimpan nilai hitungan saat ini.

Register mode operasi pengatur waktu/penghitung TMOD

Fungsi pengaturan waktu dan penghitungan dikendalikan oleh bit kontrol dari register fungsi khusus TMOD. CT Persegi{T}CT Untuk menentukan pilihan, informasi register TMOD tercantum pada tabel berikut. Terlihat bahwa 2 timer/counter memiliki empat mode operasi, dipilih melalui M1 dan M0 dari TMOD. Mode 0, 1 dan 2 dari kedua timer/counter tersebut sama, namun mode 3 berbeda.
Masukkan deskripsi gambar di sini

Mode kerja pengatur waktu

Dengan mengatur M1 dan M0 pada register TMOD register, timer/counter 0 dan 1 mempunyai empat mode operasi yang berbeda.

Mode 0 (pengatur waktu/penghitung 13-bit)

Masukkan deskripsi gambar di sini
Diagram mode kerja adalah sebagai berikut:
Masukkan deskripsi gambar di sini

Mode 1 (pengatur waktu/penghitung 16-bit)

Mode 1 sama persis dengan mode 0 kecuali 16 bit TH0 dan TL0 digunakan. Dalam mode ini, overflow 8-bit dari TL0 dibawa ke TH0, dan overflow dari TH0 menyetel flag overflow TF0 di TCON.

Ketika GATE=0(TMOD.3), jika TR0=1, pengatur waktu dihitung. Ketika GATE=1, input eksternal INTO diperbolehkan untuk mengontrol timer 0, sehingga pengukuran lebar pulsa dapat dicapai. TRO adalah bit kontrol pada register TCON. Untuk deskripsi fungsi spesifik setiap bit register TCON, lihat pengenalan register TCON di bagian sebelumnya.

Catatan: Pengatur waktu mikrokontroler seri STC89C51RC/RD+ memiliki dua kecepatan penghitungan: satu adalah mode 12T, menambahkan 1 setiap 12 jam, sama seperti mikrokontroler 8051 tradisional; yang lainnya adalah mode 6T, menambahkan 1 setiap 6 jam, kecepatannya Kecepatan T0, yang 2 kali lipat dari mikrokontroler 8051 tradisional, diatur di programmer STC-ISP saat membakar program pengguna.

Mode 2 (mode muat ulang otomatis 8-bit)

Dalam mode ini, timer/counter dapat secara otomatis memuat ulang counter 8-bit. Overflow TL0 tidak hanya menyetel TF0, tetapi juga memuat ulang konten TH0 ke TL0. (TH0 dapat diatur terlebih dahulu, dan konten TH0 tidak akan berubah selama instalasi ulang)
Masukkan deskripsi gambar di sini

Mode 3 (dua penghitung 8-bit)

Untuk Timer 0, dalam mode ini, Timer 1 berhenti menghitung, dan efeknya sama dengan menyetel TR1 ke 0.


Untuk timer 0, dalam mode ini, TL0 dan TH0 dari timer 0 berfungsi sebagai dua pencacah 8-bit yang independen. Gambar di bawah menunjukkan diagram logika timer 0 pada mode 3. TL0 menempati bit kontrol pengatur waktu 0: CT Persegi{T}CT , GERBANG, TRO, INTO dan TFO. THO terbatas pada fungsi pengatur waktu (penghitung periode) dan menempati TR1 dan TF1 pengatur waktu 1. Pada saat ini, TH0 mengontrol interupsi timer 1.

Mode 3 disediakan untuk menambahkan pengatur waktu/penghitung 8-bit tambahan, memberikan mikrokontroler tiga pengatur waktu/penghitung. Mode 3 hanya berlaku untuk pengatur waktu/penghitung 0. Ketika pengatur waktu T1 dalam mode 3, ini setara dengan TR1-0 dan berhenti menghitung, dan T0 dapat digunakan sebagai dua pengatur waktu.
Masukkan deskripsi gambar di sini

Proses konfigurasi pengatur waktu

  1. Tetapkan nilai ke TMOD untuk menentukan cara kerja T0 dan T1.
  2. Hitung nilai awal sesuai dengan waktu yang akan dihitung waktunya, dan tuliskan ke dalam TH0, TL0 atau TH1, TL1.
  3. Jika interupsi digunakan, tetapkan nilai ke EA dan buka total interupsi pengatur waktu.
  4. Atur TR0 atau TR1 untuk memulai pengatur waktu/penghitung waktu atau penghitungan.

Catatan: Alat pemrograman STC-ISP dilengkapi dengan nilai awal waktu yang akan dihitung. Anda dapat menyalin kode sesuai dengan mode yang Anda pilih.
Masukkan deskripsi gambar di sini

Demonstrasi kode - LED1 berkedip dengan interval 1 detik

Lampu indikator LED1 dikontrol untuk berkedip pada interval 1 detik melalui interupsi pengatur waktu 0. Diagram fisik terhubung: D1 terhubung ke pin P2_0. Jam 12.000MHz digunakan setiap kali. Fungsi pemicu interupsi digunakan untuk menghitung. Jika 1000, itu adalah satu detik.

#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)
	{
		
	}	
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

Demonstrasi kode - tombol 1 mengontrol status lampu LED yang menyala

Dalam demonstrasi ini, fungsi _crol_left shift dan _cror_right shift di perpustakaan INTRINS.H digunakan. Saat tombol KEY1 ditekan, lampu LED yang menyala akan mengubah status arah dan berkedip. Koneksi gambar fisik: K1 terhubung ke pin P0_0, dan delapan lampu LED dimasukkan ke pin P2.

  • mencabik(unsigned char val, unsigned char n): Memutar karakter ke kanan, dan memutar val ke kanan sebanyak n bit.
  • kroket(unsigned char val, unsigned char n): Putar karakter ke kiri, putar val ke kiri sebanyak n bit
#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;	
				}
			}
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95

Demonstrasi kode - Tampilan jam pengatur waktu LCD1602

Kode demonstrasi ini menggunakan modul LCD1602 sebagai tampilan. Modul LCD1602 tidak akan dijelaskan secara detail, dan instruksi bab khusus akan diberikan kemudian. Jika Anda memerlukan perpustakaan LCD1602, Anda dapat mengirim pesan kepada saya secara pribadi. Koneksi gambar fisik: Cukup colokkan modul LCD1602 ke papan.

#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);
	}	
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75