【自學微控制器】5 --- 邏輯運算子、邏輯電路符號、定時器和數碼管介紹

2020-08-12 10:31:03

1、邏輯運算和邏輯電路

  • 引入邏輯概念:在生活中,邏輯存在 ‘真’‘假’ 兩個邏輯值,而邏輯對應到C語言和數位電路中, ‘真’ 對應C語言或數位電路中的一切 ‘非0值’,而 ’假‘ 對應爲 ’0值‘

1.1 C語言邏輯運算子

  假定兩個位元組變數A和B,兩者進行某種邏輯運算後結果爲F。

  以下爲邏輯運算子(按變數整體值進行運算)

  • && 邏輯與:F = A && B,當 A、B 的值都爲真(即非 0 值,下同)時,其運算結果 F
    爲真(具體數值爲 1,下同);當 A、B 值任意一個爲假(即 0,下同)時,結果 F 爲假(具體數值爲 0,下同)。
  • || 邏輯或:F = A || B, A、B 值任意一個爲真, F 爲真; A、B 值都爲假, F 爲假。
  • ! 邏輯非:F = !A,A 值爲假, F 爲真; A 值爲真, F 爲假。

 以下爲按位元運算子(按變數的每一個位進行運算)

  • & 按位元與:F = A & B,將 A、B 兩個位元組中的每一位都進行與運算,得到的每一位結果組合爲總結果 F,例如 A = 0b00111100,B = 0b11011101,則結果 F 就等於0b00011100。
  • | 按位元或: F = A | B,例如 A = 0b00111100,B = 0b11011101, F 就等於 0b11111101。
  • ~ 按位元取反: F = ~A,就是將 A 位元組內的每一位進行非運算(就是取反),例如 A = 0b00111100, F 就等於 0b11000011;
  • ^按位元互斥或:互斥或的意思是,如果運算雙方的值不同(即相異)則結果爲真,雙方值相
    同則結果爲假。F = A ^ B,A = 0b00111100,B = 0b11011101 , 結果 F 就等於 0b11100001。

1.2 邏輯電路符號

以下圖爲數位電路常用電路符號,重點認識國外流行符號,通過查閱來記住即可。

逻辑电路符号

2、定時器學習(重點非難點)

2.1 時鐘週期和機器週期的介紹

  • 時鐘週期:是時序中最小的時間單位,計算方法:時鐘週期 = 1 / 時鐘源頻率。(注:1. 單位爲秒  2.時間源頻率就是微控制器的晶振,STC89C52RC晶振:11.0592M)
  • 機器週期:微控制器完成一個操作的最短時間。標準架構下的51微控制器的一個機器週期等於12個時鐘週期(12 / 時鐘週期 S),有的增強型51微控制器一個機器週期等於4個時鐘週期或等於1個時鐘週期,以下講解標準框架下的51微控制器。

2.2 定時器的介紹

微控制器中定時器和計數器是內部的同一模組,計數器功能讀者自己去瞭解,我們來介紹定時器功能。
定時器用於定時,標準51微控制器有T0和T1兩個定時器。定時器內部有一個暫存器,該暫存器的值每通過一個機器週期自動加1,可以把機器週期理解爲定時器的計數週期,如同鐘錶,每經過一秒,數位自動加1,而暫存器每通過12/11059200秒,數值自動加1。當鐘錶加到60秒後,秒自動跳爲0,這種情況在微控制器和計算機中叫溢位,定時器不同工作模式,溢位的情況也不同,假如16位元定時器,加到65535後,再加1就溢位,溢位後值直接變爲0。

2.2.1 定時器暫存器介紹

 定時器這模組有6個暫存器,下面 下麪來一一介紹,讀者用到這些暫存器查手冊即可。

  • 定時值儲存暫存器
    定时值存储寄存器
     表5-1中有四個暫存器,用於儲存定時器的計數值,其中TH0和TL0用於定時器0,TH1和TL1用於定時器1。
  • TCON–定時器控制暫存器
    位分配
    (注:可位定址指的是可以對該暫存器的每個位單獨操作,比如該暫存器的一位TR1,可以直接用程式進行TR1 = 1操作)
    位描述
    (注:只要寫到硬體置 1 或者清 0 的,就是指一旦符合條件,微控制器將自動完成的動作,只要寫軟體置 1 或者清 0 的,是指我們必須用程式去完成這個動作)

 表 5-2 是定時器控制暫存器 TCON 的位分配,表 5-3 是則是對每一位的具體含義的描述。TCON暫存器中TF0和TR0用於定時器0,TF1和TR1用於定時器1。我們以定時器1爲例講解,定時器0同理,TR1等於1,定時器值每過一個機器週期加1,若等於0,則停止加1。 TF1的作用是告訴們定時器溢位了,比如定時器16位元模式下,每經過一個機器週期會使TL1加1,加到255後,再加1後,TL1變爲0,而TH1加1,如此回圈,待TL1和TH1爲255後,再加1就會溢位,此時TL1和TH1變爲0,TF1自動變成1,提供給讀者一個溢位信號。

  • TMOD–定時器模式暫存器

位分配
(注:不可位定址指的是不可以對該暫存器的每個位單獨操作,對 TMOD 裡的位比如M1 (T1)= 1 這樣的操作就是錯誤的。我們要操作就必須一次操作這整個位元組,也就是必須一次性對 TMOD 所有位元運算)
 上表爲TMOD的位分配。

位描述
 表5-5爲TMOD的位描述,GATE位讀者自行瞭解,C/T位爲選擇定時器或計數器功能,T=0爲選擇定時器功能,C/T=1爲選擇計數器功能。


 表5-6爲TMOD4中模式介紹,模式0和3現在很少應用,讀者自行瞭解,下面 下麪介紹模式1和2。
模式1: 是 THn 和 TLn 組成了一個 16 位的定時器,計數範圍是 0~65535,溢位後,只要不對 THn 和 TLn 重新賦值,則從 0 開始計數。
模式2: 是 8 位自動重灌載模式,只有 TLn做加 1 計數,計數範圍 0~255,THn 的值並不發生變化,而是保持原值,TLn 溢位後,TFn就直接置 1 了,並且 THn 原先的值直接賦給 TLn,然後 TLn 從新賦值的這個數位開始計數。 比如該模式下,TH1 = 0x66,TL1=0x00,每經過一個機器週期TL1加1,當TL1=0xFF時,再加1後TF1就會變爲1,並且TL1會被賦值爲TH1的值後計數,即TL1從0x66開始計數,而TH1的值保持不變。

2.2.2 定時器模式工作電路邏輯圖

  • 定時器模式一工作電路邏輯圖

模式一
講解:以定時器1爲講解,定時器0同理,OSC爲時鐘源頻率,d爲微控制器機器週期對於時鐘週期的倍數。

  1. 當C/T = 0開啓定時器功能,C/T = 1開啓計數器功能。
  2. 要達到控制效果,TR1和或門構成的電路要進行與運算,與運算兩個爲真才爲真,所以TR1要爲1,並且或門構成的電路進行或運算後結果要爲1,
  3. 或門輸出爲1的方式有兩種9:(1).當INT1引腳爲1時,不過GATA位爲什麼,或運算後結果都爲1,定時器1模式1開啓。(2). 當GATA爲0時,經過非運算後爲1,不管INT1爲什麼,進行或運算結果都爲1,定時器1模式1開啓。
  • 定時器模式二工作電路邏輯圖
    模式二
    講解: 模式二的電路邏輯圖和模式一的相似,就不進行詳細講解,此模式下定時器作爲可自動重灌載的8位元計數器(TLn), TLn的溢位,不僅置爲TFn,而且將THn的內容重新裝載到TLn,THn內容由軟體預置,重灌時THn內容不變。

2.3 定時器的應用

2.3.1 使用定時器的步驟

下面 下麪以使用定時器0爲例,定時器1同理。

  1. 設定定時器模式暫存器TMOD,選擇好定時器工作模式。
  2. 設定計數暫存器TH0和TL0的初值。
  3. 設定定時器控制暫存器TCON,使TR0 置1讓定時器開始計數。
  4. 通過判斷TCON中的TF0位,監測定時器的溢位情況。

2.3.2計算如何用定時器定時時間

 我們知道標準51微控制器機器週期爲12個時鐘週期,以STC89C52RC微控制器爲例,它的機器週期爲:12/11059200秒,如果定時0.02s,設要經過x個機器週期,那麼 x* (12/11059200) =0.02, 通過計算x等於18432,因16位元定時器溢位值爲65536,那麼先讓TH0和TL0等於初值y,經過18432個機器週期後溢位,這樣就實現了定時0.02s,y值通過65536- 18432計算出爲47104,轉換爲十六進制就是0xB800(鏈接:進位制轉換方法),即TH0 = 0xB8,TL0 = 0x00。

2.3.3通過定時器控制小燈的閃爍

  • 控制小燈進行0.5HZ頻率閃爍的程式
#include<reg52.h>

sbit LED = P0^7;
sbit ADDR3 = P1^3;
sbit ADDR2 = P1^2;
sbit ADDR1 = P1^1;
sbit ADDR0 = P1^0;
sbit ENLED = P1^4;

void main()
{
	unsigned char cnt = 0;//定義一個計數變數,記錄T1的溢位次數
	ENLED = 0;
	ADDR3 = 1;
	ADDR2 = 1;		
	ADDR1 = 1;
	ADDR0 = 0;
	TMOD = 0x10;//設定T1的工作模式
	TH1 = 0xB8;
	TL1 = 0x00;//爲T1賦初值
	TR1 = 1;//啓動T1

	while(1)
	{
		if(TF1 == 1)//判斷T1是否溢位
		{
			 cnt++;// 計數值自加1
			 TF1 = 0;//T1溢位後,清零中斷標誌
			 TH1 = 0xB8;//並在重新賦初值
			 TL1 = 0x00;
			 if(cnt >= 50)//判斷是否溢位50次
			 {
			 	LED = ~LED;//LED取反,1--->0、0--->1
				cnt = 0;//達到50次後計數值清零
			 }
		}	
	}

}
  • 通過定時器控制左右流水燈程式
#include<reg52.h>

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

void main()
{
	unsigned char cnt = 0;//定義計數變數,記錄溢位次數
	unsigned char dir = 0;//定義移位方向變數,用於改變流水燈流向
	unsigned char shift = 0x01;//定義回圈移位變數shift,並賦初值0x01	
	
	ENLED = 0;//使能U3
	ADDR3 = 1;
	ADDR2 = 1;
	ADDR1 = 1;
	ADDR0 = 0;
	TMOD = 0x10;//設定T1爲模式一
	TH1 = 0xB8;//爲T1賦初值
	TL1 = 0x00;
	TR1 = 1;//開啓T1

	while(1)//主回圈,程式無限執行該回圈
	{
		P0 = ~shift;//P0等於回圈移位變數shift取反,控制8個LED小燈
		while(TF1 == 0);//當TF1=0時回圈執行空語句,直到定時器溢位
		TF1 = 0;//TF1清零
		TH1 = 0xB8;//重新爲T1賦初值
		TL1 = 0x00;
		cnt++;//每溢位一次,cnt加一
		if(cnt >= 10)//判斷是否溢位10次
		{
			cnt = 0;//溢位次數置零
			if(dir == 0)//移位方向變數爲0時,左移
			{
				shift = shift << 1;//回圈移位變數shift左移一位
				if(shift == 0x80) //左移到最左端,改變移位方向變數
				{
					dir = 1;	
				}
			}else				//移位方向變數不爲零時,右移
			{
				shift = shift >> 1;//回圈移位變數右移一位
				if(shift == 0x01) //右移到最右端,改變移位方向變數
				{
					dir = 0;
				} 
			}
		}
	}

}

3、數碼管學習

3.1 數碼管介紹

 一個數碼管由8個LED小燈組成。數碼管分爲共陽數碼管和共陰數碼管,共陽數碼管的8個LED小燈陽極連在一起, 陽極爲公共端,由陰極控制單個小燈亮滅。共陰數碼管同理,數碼管內部結構見下圖5-4。
数码管内部结构
 下圖5-3爲數碼管的原理圖

数码管原理图
  com引腳爲公共端,圖中有兩個com公共端,爲什麼有兩個公共端呢? 一方面,爲了起對稱效果,剛好10個引腳,另一方面,因並聯電流之和等於總電流,可以降低單條線路承受的電流。

3.2 數碼管點亮原理

 下圖爲KST-51開發板中數碼管電路圖
数码管电路图
 從上圖可以知道數碼管每個LED小燈陽極都接在5v(VCC)上,所以上圖6個數碼管都是共陽數碼管,下面 下麪講解數碼管點亮原理。

  1. 首先根據分析點亮數碼管要先導通數碼管對應連線的三極管,即讓每個三極管的基極b輸出低電平,也就是控制三八譯碼器將對應Y編號的引腳輸出爲低電平即能導通三極管,我們第三章中已經介紹瞭如何應用三八譯碼器,使用時檢視晶片手冊即可,就不再介紹。
  2. P0的所有引腳對應連線DB編號引腳,控制P0引腳的輸出電平,即可讓數碼管顯示不同的數值。比如讓數碼管顯示8,那麼P0要爲0b10000000,轉換爲十六進制就爲0x80(鏈接:進位制轉換方法)。

3.3數碼管真值表

 數碼管的 8 個段,我們直接當成 8 個 LED 小燈來控制,那就是 a、b、c、d、e、f、g、dp 一共 8 個 LED 小燈。我們控制這8個小燈來讓數碼管顯示不同數值,而數碼管顯示的數位字元對應給 P0 的賦值,我們叫做數碼管的真值表。 數碼管真值表見下表5-7。

数码管真值表

3.4 數碼管的應用

  • 讓數碼管顯示字元程式
#include<reg52.h>

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

void main()
{
	ENLED = 0;//使能U3,導通三極管Q9,
	ADDR3 = 1;
	ADDR2 = 0;
	ADDR1 = 1;
	ADDR0 = 1;
	P0 = 0x80;//點亮數碼管DS4的a、b、c、d、e、f和g段,讓數碼管顯示字元8
	while(1);//讓數碼管DS4一直顯示字元8
}
  • 數碼管靜態顯示秒錶先計時後倒計時程式

 先介紹C51中的關鍵字code,前面定義變數時使用關鍵字unsigned char或unsigned int,這樣定義的變數都是放在微控制器RAM中,並且程式中可以隨意更改這些變數的值,而運用code關鍵字修飾下定義的變數,則可以儲存到程式空間FLASH中,大大節省微控制器RAM空間,但程式中不能更改這些變數的值。下面 下麪我們來看看運用了code關鍵字的程式。

#include<reg52.h>

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

//用陣列儲存數碼管真值表,陣列將在下一章詳細介紹
unsigned char code Ledchar[] = {
	0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
	0x80, 0x90,	0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};

void main()
{
	unsigned char cnt = 0;//定義溢位計數變數,記錄溢位次數
	signed char sec = 0;//記錄經過的秒數
	unsigned char dir = 0;//定義選擇變數,0代表秒錶,1代表倒計時	

	ENLED = 0;//使能U3,導通三極管Q8,準備點亮數碼管DS5
	ADDR3 = 1;
	ADDR2 = 1;
	ADDR1 = 0;
	ADDR0 = 0;

	TMOD = 0x01;//設定T0爲工作模式一
	TH0 = 0xB8;//爲T0賦初值
	TL0 = 0x00;
	TR0 = 1;//開啓定時器T0

	while(1)
	{
		if(TF0 == 1)//判斷T0是否溢位
		{
			TF0 = 0;//軟體將溢位標誌清零
			TH0 = 0xB8;//爲T0重新賦值
			TL0 = 0x00;
			cnt++;//計數值自加1,
			if(cnt >= 50)//判斷T0是否溢位50次
			{
				cnt = 0;//達到50次後計數值清零
				if(dir == 0)//選擇變數dir等於0,實現秒錶功能
				{
					 P0 = Ledchar[sec];//當前秒數對應的真值表中的值送到P0口
					 sec++;//秒數記錄自加一
					 if(P0 == 0x8E)//當P0值使數碼管顯示字元F時,
					 {
					 	dir = 1;//將選擇變數置爲1,準備實現倒計時功能
						sec = 14;//將秒數置爲14
					 }
				}else //實現倒計時功能
				{
					P0 = Ledchar[sec];//當前秒數對應的真值表中的值送到P0口
					sec--;//秒數記錄自減一
					if(sec < 0)//當秒數小於0後
					{
						dir = 0;//將選擇變數置爲0,準備實現秒錶功能
						sec = 1;//將秒數置爲1
					}
				}
			}

		}
			
	}

}

4、收穫

  重溫第五章對定時器的使用無疑更加熟悉了,程式設計上沒有啥問題,前幾天忙家裏的一些事耽誤了進度,一天一章的目標也啪啪打臉,接下來會加倍學習的。奧裡給奧裡給!!!

表情包