【單片機】— {STC15}—{期末複習筆記}

二、編程題

(二)中斷

      外部中斷

(一)定時器

可能是定時器T1/T0方式0(16位可自動重裝初值)或者定時器T2(只有16位可自動重裝初值)
T1/T0與T2除了控制寄存器的配置有些不一樣,其餘定時初值等都是一樣的.

1、定時器T2(16位可自動重裝初值)

(1)、查詢法
(2)、中斷法
①定時器初始化函數流程:

在這裏插入圖片描述

//---------------定時器2初始化函數-----&中斷方法------//
void T2_Init(void)   //50毫秒@12Hz
{
	AUXR &= 0xFB;		//定時器時鐘12T模式
	T2L = 0xB0;		 //設置定時初值
	T2H = 0x3C;		 //設置定時初值
	EA = 1;        //開總中斷
	IE2 |= 0X04;    //開定時器2中斷允許控制位 
	AUXR |= 0x10;	//定時器2開始計時
}
②定時初值計算

  ●12分頻:

t=(2na)12fsyst=\frac{(2^n-a)*12}{f_{sys}}

  ●不分頻:

t=(2na)1fsyst=\frac{(2^n-a)*1}{f_{sys}}

時間t的單位位秒; (舉例爲50ms)
定時器應該只會考16位的,所以n=16;
系統時鐘fsysf_{sys}應該是12MHz,即 12×10612×10^6Hz
若採用12分頻,可算得計數初值十進制數a=15536,換算成二進制數位a=(11110010110000)2a=(‭‭11 1100 1011 0000‬‬)_2
在這裏插入圖片描述

③系統時鐘fsysf_{sys}

課本P31
系統時鐘fsysf_{sys} =主時鐘foscf_{osc} / N
N爲分頻係數,可以通過時鐘分頻寄存器CLK_DIV進行改變,默認爲1.

  ●
在這裏插入圖片描述
在這裏插入圖片描述
  ●方法一:
    代碼:

#include<STC15.H>

#define uchar unsigned char
#define uint unsigned int
	
uchar i=0;
uchar j;

void GPIO(void);  //IO口初始化函數
void T2_Init(void); //定時器2初始化函數50毫秒@12Hz
	
void main(void)
{
	GPIO();  //IO口初始化
	T2_Init();//定時器2初始化
	while(1); //用原地踏步模擬主程序
}

void GPIO(void)  //IO口初始化函數
{
	P0M1=0;
	P0M0=0;
	P1M1=0; 
	P1M0=0;
	P2M1=0;
	P2M0=0;
	P3M1=0;
	P3M0=0;
}

//---------------定時器2初始化函數-----&中斷方法------//
void T2_Init(void)   //50毫秒@12Hz
{
	AUXR &= 0xFB;		//定時器時鐘12T模式
	T2L = 0xB0;		 //設置定時初值
	T2H = 0x3C;		 //設置定時初值
	EA = 1;        //開總中斷
	IE2 |= 0X04;    //開定時器2中斷允許控制位 
	AUXR |= 0x10;	//定時器2開始計時
}
//------定時器二中斷服務函數0----------//
void T2_ISR(void) interrupt 12 
{
	i++;
	j=i/20;
	if(j==0||j==1) 
	{
		P46=0;
	}
	if(j==2)
	{
		P46=1;
	}
	if(j==3) i=0;
}

運行結果:
(波形圖佔空比,週期符合要求,但不是水平的原因可能是IO口內部RC充放電)
在這裏插入圖片描述
  ●方法二:
方法二改變了系統時鐘fsysf_{sys} ,來獲得較長的時間.定時初值的計算方法與上邊所說一樣,只是需要提前將系統時鐘fsysf_{sys}按照公式算出.可以得到定時初值a=(3036)10(3036)_{10}

 #define x 3036  //定時1秒的初值

老師在程序中直接將3036用#define宏定義爲x,(不加前綴聲明數字類型時,默認爲10進制數,編輯器在運行時統一將數字轉化爲二進制)

    T2L = x;		   //設置定時初值
	T2H = x>>8;		 //設置定時初值

T2L和T2H都是8位狀態寄存器,只有8位,只能存8個數.上邊第一句將x賦值給T2L,運行時編輯器自動將x轉化爲二進制數1011 1101 1100‬,T2L寄存器只能保存二進制數的低八位.
x右移8位,高位用0補齊,x>>8的結果位0000 1011,再將右移的結果賦值給T2H.
這種通過宏定義來賦值,是爲了後續該程序容易改,考試沒太有必要用,直接對T2L和T2H賦十六進制值就行.

#define uchar unsigned char
#define uint unsigned int
#define x 3036  //定時1秒的初值	
uchar i=0;

void GPIO(void);  //IO口初始化函數
void T2_Init(void); //定時器2初始化函數50毫秒@12Hz

void main(void)
{
	GPIO();  //IO口初始化
	T2_Init();//定時器2初始化
	while(1); //用原地踏步模擬主程序
}
void GPIO(void)  //IO口初始化函數
{
	P0M1=0;
	P0M0=0;
	P1M1=0; 
	P1M0=0;
	P2M1=0;
	P2M0=0;
	P3M1=0;
	P3M0=0;
}

//---------------定時器2初始化函數-----&中斷方法------//
void T2_Init(void)   //50毫秒@12Hz
{
	CLK_DIV=0x04;    //系統時鐘爲主時鐘的16分頻
	AUXR &= 0xFB;		//定時器時鐘12T模式
	T2L = x;		   //設置定時初值
	T2H = x>>8;		 //設置定時初值
	EA = 1;        //開總中斷
	IE2 |= 0X04;    //開定時器2中斷允許控制位 
	AUXR |= 0x10;		//定時器2開始計時
}

void T2_ISR(void) interrupt 12
{
	i++;
	if(i==1||i==2)
	{
		P46=0;
	}
	if(i==3)
	{
		P46=1;
		i=0;
	}
}
	

運行結果:
多次改變時鐘分頻寄存器CLK_DIV的值,運行結果並未產生肉眼可見的變化.不知道是代碼問題還又是仿真的BUG.
在這裏插入圖片描述
  ●方法一,二對比
方法一是先定時一個比較小的時間,之後定時器溢出,觸發中斷,進入定時器中斷服務函數,循環變量i再中斷函數裏累加.判斷循環變量i是否達到預定值,多次執行中斷服務函數,產生誤差時間.如果定時器定時時間比較小,需要較多次數地執行中斷服務函數,誤差時間就會肉眼可見.
所以在使用方法一時定時器定時時間應該儘可能的大,以減小誤差.
方法二,多配置一個寄存器,增加犯錯概率.😷
可提前將常用定時時間準備好

2、定時器T1/T0方式0(16位可自動重裝初值)

(1)、查詢法
(2)、中斷法
①定時器T1/T0初始化函數流程:

在這裏插入圖片描述

#include<STC15.H>

#define uchar unsigned char
#define uint unsigned int
	
void GPIO(void);  //IO口初始化函數
void T1_Init(void);   //定時器1初始化函數10毫秒@12MHz
	
void main(void)
{
	GPIO();   //IO口初始化
	T1_Init();//定時器1初始化
}

void GPIO(void)  //IO口初始化函數
{
	P0M1=0;
	P0M0=0;
	P1M1=0; 
	P1M0=0;
	P2M1=0;
	P2M0=0;
	P3M1=0;
	P3M0=0;
}

//---------------定時器1初始化函數-----&中斷方法------//
void T1_Init(void)   //10毫秒@12MHz
{
	AUXR &= 0xBF;	  //定時器時鐘12T模式
	TMOD &= 0x0F;	  //設置定時器模式
	TL1 = 0xF0;		 //設置定時初值
	TH1 = 0xB8;		  //設置定時初值
	TF1 = 0;		  //清除TF1標誌
	EA = 1;          //開總中斷
	ET1 = 1;        //開定時器1中斷允許控制位 
	TR1 = 1;		 //定時器1開始計時
}

void T1_ISR(void) interrupt 3
{
	
}

一、選擇題

在這裏插入圖片描述

 ●第一章、(2)

1、在系統編程(In System Programming,ISP)
  在應用編程(In Application Programming,IAP)P14
2、STC單片機命名規則P15
 ●工作電壓:F、L、W
 ●程序空間大小(程序儲存器)

 ●第三章、(6)

1、任何一箇中央處理單元CPU都包含有控制器運算器兩大基本模塊
2、通過程序計數器(Program Counter,PC)從程序存儲器中源源不斷地取出所要執行的代碼。因此,程序計數器PC是CPU中最基本的控制部分。PC的特點就是總是指向下一條所要執行的指令的地址空間。P22
3、程序計數器的寬度爲16位。也就是說,地址深度爲216,地址的範圍爲0~65535,即64K。因此,程序存儲器的深度最大爲64K。
4、數據指針(Dual Data Pointer,DPTR)是一個16位的專用寄存器。
由DPL(低8位)和DPH(高8位)組成,其地址爲82H(DPL,低字節)和83H(DPH,高字節)。DPTR是8051中唯一可以直接進行16位操作的寄存器。此外,也可以按照字節分別對DPH和DPL進行操作。P25
5、在STC單片機中,用於控制指向存儲空間位置的是一個堆棧指針(Stack Pointer,SP)它實際上就是一個8位的專用寄存器。該寄存器的內容就是棧頂的地址,也就是用於表示當前棧頂在內部RAM塊中的位置。其作用主要用於保存現場先進後出,後進先出P25
6、指針類寄存器3個,SP;DPTR;PC
7、運算器:8位算術邏輯單元ALU(核心);累加器ACC;B寄存器;程序狀態字PSW P21
8、指令通道???
9、在這裏插入圖片描述
10、程序存儲器16位的PC指向下一條要執行的指令。
CPU只能通過使用MOVC指令,從程序空間讀取數據。
當單片機復位後,程序計數器(PC)的內容爲0x0000。
因此,從程序存儲器地址爲0x0000的地方開始執行程序。另外,中斷服務程序的入口地址(也稱爲中斷向量)也放在程序存儲單元。
11、STC系列單片機內部提供了大容量的數據Flash存儲器,用於實現電可擦除的**只讀存儲器(EEPROM)**功能。
數據Flash存儲器和程序Flash存儲器空間是分開的。
12、在這裏插入圖片描述

 ●第五章、(4)

1、中斷請求,中斷響應,中斷服務,中斷返回
2、在這裏插入圖片描述
3、在這裏插入圖片描述
4、在這裏插入圖片描述
5、在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章