【單片機】— {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的單位位秒; (舉例爲50ms)
定時器應該只會考16位的,所以n=16;
系統時鐘應該是12MHz,即 Hz
若採用12分頻,可算得計數初值十進制數a=15536,換算成二進制數位
③系統時鐘
課本P31
系統時鐘 =主時鐘 / 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充放電)
●方法二:
方法二改變了系統時鐘 ,來獲得較長的時間.定時初值的計算方法與上邊所說一樣,只是需要提前將系統時鐘按照公式算出.可以得到定時初值a=
#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、