1: 脈沖累加器B使能。實際上PACB為PACl、PAC0級連形成,PACl為高位、而PAC0為低位字節(jié),這時寄存器ICPACR中的控制位PAlEN、PAOEN無效。
可在任何時候讀或?qū)憽?/div>
該寄存器只有一個標志位PBOVF,當16位的PACB從$FFFF回滾到$0000,或8位脈沖累加器3(PACl)從$FF回滾到$00時,該位置1。將$01寫入PBFLG清除該位。當寄存器TSCR($06)中的TFFCA位置位時,訪問PACNl和PACN0清除該標志。
2.21 脈沖累加器保持寄存器(PA3H-PA0H)PAC3H 寄存器偏移量:$0032
復位后:0 0 0 0 0 0 0 0
PA2H 寄存器偏移量:$0033
復位后:0 0 0 0 0 0 0 0
PA1H 寄存器偏移量:$0034
復位后:0 0 0 0 0 0 0 0
PA0H 寄存器偏移量:$0035
復位后:0 0 0 0 0 0 0 0
可在任何時候讀。寫不起作用。
當ICPACR($28)中PAnEN=1時,通道PAn使能,寄存器PA3H-PAOH用于為PAn提供鎖存功能。
2.22 模數(shù)遞減計數(shù)器工作寄存器(MCCNT)寄存器偏移量:$0036-$0037
復位后:1 1 1 1 1 1 1 1
MDC啟動后,MCCNT用來對定標器輸出的時鐘進行遞減計數(shù),也可作為定時基準。對該寄存器的訪問應在一個時鐘周期內(nèi)完成,即按字訪問。對高低位字節(jié)分別訪問可能得到錯誤的結果。如果MCCTL中的RDMCL=0,讀MCCNT寄存器返回計數(shù)器的當前值;反之如果RDMCL=1,返回每次重新加載所用的常數(shù)。
當寄存器ICSYS($2B)中的LATQ、BUFEN均為1時,如果將$0000寫入到MCCNT和模數(shù)計數(shù)器,輸入捕捉和脈沖累加寄存器將被鎖存。將$0000寫入到MCCNT后,模數(shù)計數(shù)器將保持為0,且不會將MCFLG中的MCZF標志置位。
如果模數(shù)方式允許(MODMC=1),對該地址進行寫操作將更新常數(shù)寄存器,但計數(shù)器不會立即更新,必須等到計數(shù)器回0后重新加載;如果希望立即加載,通過寄存器MCCTL ($26)中的FLMC位可以將新值立即加載到計數(shù)器。如果模數(shù)方式未允許(MODMC=0),寫該地址將清0定標器,并用寫入值立即更新計數(shù)器,然后開始一次遞減計數(shù),到0后停止。
2.23 IC保持寄存器(TC0H-TC3H)TCOH 寄存器偏移量:$0038-$0039
復位后:0 0 0 0 0 0 0 0
TC1H 寄存器偏移量:$003A-$003B
復位后:0 0 0 0 0 0 0 0
TC2H 寄存器偏移量:$003C-$003D
復位后:0 0 0 0 0 0 0 0
TC3H 寄存器偏移量:$003E-$003F
復位后:0 0 0 0 0 0 0 0
這些寄存器用于為相應的捕捉寄存器TC0-TC3提供鎖存功能。
定時器與I/O共享引腳的說明
定時器與PORTT共享8個I/O引腳,復位后各個引腳默認為通用輸兒輸出,當定時器相關功能使能后,將取代通用I/O功能。引腳PT0-3由IC/OC、PAC及通用I/O共享,引腳 PT4-7由IC/OC及通用I/O共享,此外引腳PT0、PT7還供16位脈沖累加器A、B作為輸入使用。其他請參看第6章TIM模塊有關說明,不再贅述。
不同模式下的定時器及模數(shù)計數(shù)器的運行狀況
(1)停止(STOP):因為PCLK和ECLK均已停止,定時器和模數(shù)計數(shù)器關閉。
(2)調(diào)試方式(BDM):只要不滿足TSBCK=1,定時器保持運行。
(3)中斷等待(WAIT):只要不滿足TSWAI=1,計數(shù)器保持運行。
(4)正常(Normal):只要不滿足TEN=0和MCEN(MCCTL中)=0,定時器保持運行。
(5)禁止(TEN=0):定時器和MDC停止,但寄存器可訪問。ECLK/64時鐘被禁止。
(6)禁止(PAEN=0):所有的脈沖累加器動作停止,但寄存器可以訪問。
(7)MCEN:0:模數(shù)計數(shù)器停止。
(8)PAEN:1:16位脈沖累加器A激活。
(9)PAEN:0:8位脈沖累加器3和2可以激活。
(10)PBEN:1:16位脈沖累加器B激活。
(11)PBEN:0:8位脈沖累加器1和0可以激活。
第三節(jié) ECT應用實例3.1 定時器編程步驟1、初始化:
設定預分頻系數(shù),設定工作方式,定時器溢出中斷使能,定時器使能
2、中斷函數(shù)
用戶自己的代碼,清標志位
void ECT_Init(void)
{
TSCR2_PR = 7; //預分頻系數(shù)為8
…………………..
TSCR2_TOI = 1; //定時器溢出中斷使能
TSCR1_TEN = 1; //定時器使能
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void TimerOverFlow(void)
{
//用戶自己的代碼
TFLG2_TOF = 1; //清楚定時器溢出中斷標志位
}
3.2 輸入捕捉IC:本試驗的輔助設備有:信號發(fā)生器、示波器。
試驗目的:通過連續(xù)記錄輸入信號的兩個上升沿,用該程序可以計算出輸入信號的頻率;同時,利用脈沖累加器可以記錄輸入脈沖數(shù)。
#include <hidef.h> /* common defines and macros */
#include <mc9s12dp256.h> /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dp256b"
int count=0;
float f;
double f1=2000000,first=0,second=0,n,N;
void main(void)
{
DisableInterrupts;
TSCR2=0X82;
PACTL=0X20;
TIOS=0XFE; //設定pt0輸入捕捉口
TCTL4=0X01;
ICSYS=0X0A;
PBCTL_PBEN=0X00;
ICPAR=0X01;
TIE=0X01;
TSCR1=0X80;
EnableInterrupts;
for(;;)
{; }
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED
interrupt void CH0IC(void)
{
first=TC0H;
second=TC0;
n=count*65535+second-first;
f=f1/n;
N=PA0H;
TFLG1=0X01;
count=0;
}
interrupt void TOI(void)
{
count++;
TFLG2_TOF=1;
}
3.3 通道6輸出比較本試驗的輔助設備有:示波器。
試驗目的:利用定時器溢出中斷產(chǎn)生脈沖周期,利用通道6輸出比較產(chǎn)生不同脈寬的波形,但此方法產(chǎn)生的波形其周期不能改變。
- double count,counter;
- void main(void) {
- DisableInterrupts;
- TSCR2=0X82;
- TIOS=0XFE;//設定pt6輸出捕捉口
- TCTL1=0X30;
- TC6=0X3333;
- TTOV=0X40;
- TIE=0X00;
- TSCR1=0X80;
- EnableInterrupts;
- for(;;)
- {; }
- }
- #pragma CODE_SEG __NEAR_SEG NON_BANKED
- interrupt void CH6OC(void)
- {
- counter++;
- if(counter==100)
- TC6=0X8888;
- if(counter==200)
- TC6=0XCCCC;
- if(counter==300)
- TC6=0XDEEE;
- TFLG2_TOF=1;
- }
復制代碼
3.4 通道7輸出比較本試驗的輔助設備有:示波器。
試驗目的:利用通道7輸出比較中斷產(chǎn)生脈沖周期,利用通道6、4輸出比較產(chǎn)生不同脈寬的波形,此方法產(chǎn)生的波形既可以改變周期同時也能夠改變脈寬。
- #include <hidef.h> /* common defines and macros */
- #include <mc9s12dp256.h> /* derivative information */
- #pragma LINK_INFO DERIVATIVE "mc9s12dp256b"
- double count,counter;
- void main(void) {
- DisableInterrupts;
- TIOS=0XF0;//設定pt6輸出捕捉口
- TSCR2=0X0a;
- TFLG1=0X00;
- TFLG2=0X00;
- TCTL1=0X62;
- ICSYS=0X0a;
- OC7M=0X50;
- OC7D=0X50;
- TC7=0X00C0;
- TC6=0X0060;
- TC4=0X0099;
- TIE=0X00;
- TSCR1=0X80;
- EnableInterrupts;
- for(;;)
- {; }
- }
復制代碼
3.5 模數(shù)遞減計數(shù)器本試驗的輔助設備有:連接導線若干。
試驗目的:利用模數(shù)遞減計數(shù)器回零中斷,控制五個小燈依次點亮,同時點亮的時間間隔由慢到快。
第三章 SCI模塊第一節(jié) SCI寄存器簡介SCI是一種采用NRZ格式的異步串行通信接口,它內(nèi)置獨立的波特率產(chǎn)生電路和SCI收發(fā)器,可以選擇發(fā)送8或9個數(shù)據(jù)位(其中一位可以指定為奇或偶校驗位)。
SCI是全雙工異步串行通信接口,主要用于MCU與其他計算機或設備之間的通信,幾個獨立的MCU也能通過SCI實現(xiàn)串行通信,形成網(wǎng)絡。
MC12里有兩個SCI(SCI0和SCI1)。設計SCI串口通信程序,主要是掌握八個寄存器,設置好初始化。
1.1 波特率控制寄存器(SCIBDH、SCIBDL)SCIBDH和SCIBDL一起構成了一個16位的波特率控制寄存器。SBR12~SBR0為波特率常數(shù),見表9-1。
表9-1 波特率控制寄存器
寄存器名:SCIBDH、SCIBDL;地址:$00C0、$00C1;復位默認值:00000000B、00000100B 讀操作:任意;寫操作:SBR12~SBR0任意,低位字節(jié)寫入后生效。SBR13~SBR15未定義 |
| | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
SCI的波特率由下述公式?jīng)Q定:
波特率:MCLK/(16×BR)
或BR:MCLK/(16×波特率)
其中BR是波特率常數(shù),設定時寫入到SBRl2~SBR0。復位后,在SCICR2寄存器中的 TE、RE位第一次置1前,波特率發(fā)生器是關閉的,而且,當SBRl2~
表9-2常用波特率及波特率常數(shù)
SBR0=0時,波特率發(fā)生器也會被關閉。
通常選用波特率為9600。
BTST、BSPL和BRLD保留用于檢測功能。
1.2 控制寄存器1(SCICR1)SCI的工作方式主要由該寄存器設置,包括回送、單線等方式選擇,幀格式、喚醒、空閑檢測類型以及奇偶校驗等,見表9-3。其各位意義如下:
表9-3 SCI控制寄存器1
寄存器名:SCICR1;地址:$00C2;復位默認值:00000000B;讀操作:任意;寫操作:任意 |
| | | | | | | | |
| | | | | | | | |
LOOPS: SCI回送模式/單線模式允許位,接收器的輸入由RSRC位選擇確定,發(fā)送器的輸出受相應的DDRS位(S口I/O方向控制位)控制。要使用回送或者單線模式,發(fā)送、接收器必須同時允許工作。在LOOPS=1期間,如果與TxD引腳對應的方向控制位被置1,那么TxD引腳就輸出SCI的信號;如果方向控制位被清0,那么這時若RSRC=0,TxD引腳就變成高電平(空閑狀態(tài)),反之若RSRC=1,TxD引腳就變成高阻態(tài)。
0:SCI發(fā)送和接收部分正常工作。
1:SCI接收部分與RxD引腳斷開,空出來的RxD引腳可以用作通用I/O。
SCISWAI:等待模式下SCI停止位
0:在等待模式下允許SCI
1:在等待模式下禁止SCI
RSRC:接收器信號源選擇位,當LOOPS=1時,RSRC決定接收器的內(nèi)部反饋信號路徑。
0:接收器的輸入在內(nèi)部連接到發(fā)送器輸出(并非TxD引腳)。
1:接收器的輸入連接到TxD引腳。
M:方式選擇位(選擇字符幀格式)。
0:1個起始位,8個數(shù)據(jù)位,1個停止位。
1:1個起始位,8個數(shù)據(jù)位,第9個數(shù)據(jù)位,1個停止位。
WAKE:喚醒選擇位。
0:介質(zhì)空閑喚醒。
I:地址標志(最后一個數(shù)據(jù)位為1)喚醒。
ILT:空閑檢測方式選擇位,該位在SCI接收器可以使用的兩種空閑檢測方式中選擇一種。
0:快速檢測,SCI在一個幀的開始位后立即開始對“1”計數(shù),因此,停止位以及停止位前面的任何“1”均被計算在內(nèi),這樣可以提前檢測到空閑狀態(tài)。
1:保守檢測,SCI在停止位后才開始對“1”計數(shù),因此最后一個字節(jié)的停止位以及該位以前的各個為“廣的位,對檢測的時間長短無影響。
PE:奇偶校驗允許位。
0:禁止奇偶校驗。
1:允許奇偶校驗。
PT:奇/偶校驗選擇位,如果奇偶校驗允許,該位決定收發(fā)器使用奇校驗還是偶校驗。如果選擇偶校驗,當數(shù)據(jù)中有偶數(shù)個“廣時,校驗位置0,否則校驗位置1。
0:選擇偶校驗。
1:選擇奇校驗。
1.3 控制寄存器2(SCICR2) 該寄存器主要控制收發(fā)器的使能、中斷允許及其他輔助操作,見表9-4。其各位意義如下:
表9-4 SCI控制寄存器2
寄存器名:SCICR2;地址:$00C3;復位默認值:00000000B;讀操作:任意值;寫操作:任意 |
| | | | | | | | |
| | | | | | | | |
TIE: 發(fā)送中斷允許位,清0時禁止TDRE產(chǎn)生中斷,若置1則允許TDRE位置1時產(chǎn)生SCI中斷請求。
TCIE:發(fā)送結束中斷允許位,清0時禁止TC產(chǎn)生中斷,若置1則允許TC位置1時產(chǎn)生SCI中斷請求。
RIE:接收中斷允許位,清0時禁止RDRF和OR產(chǎn)生中斷,若置1則允許RDRF或OR置1時產(chǎn)生SCI中斷請求。
ILIE:空閑中斷允許位,清0時禁止IDLE產(chǎn)生中斷,若置1則允許IDLE位置1時產(chǎn)生SCI中斷請求。
TE: 發(fā)送允許位。該位由0置1時可用來發(fā)送空閑報頭。
0: 發(fā)送器禁止。
1: 允許SCI發(fā)送部分工作,TxD引腳(PSl/PS3)用于發(fā)送。
RE: 接收允許位。
0: 接收器禁止。
1; 允許SCI接收器工作。 RWU: 接收器喚醒控制位。
RWU:接收器喚醒控制位
0:SCI接收器正常工作。
1:允許喚醒功能,禁止接收器中斷。通常,硬件通過自動清除該位來喚醒接收器。
SBK:中止符發(fā)送允許位。只要該位保持為1,發(fā)送器就不停地發(fā)出“0”;如果變?yōu)?,當前的全“0”幀發(fā)送結束后,TxD引腳將變成空閑狀態(tài)。如果SBK開關一次,發(fā)送器將只發(fā)出10(11)個“0”,然后復原,處于空閑或發(fā)送數(shù)據(jù)狀態(tài)。
0: 中止符產(chǎn)生器關閉。
1: 產(chǎn)生中止符,至少10或11個連續(xù)的“0”。
1.4 狀態(tài)寄存器1(SCISR1)該寄存器反映SCI運行過程中的各種狀態(tài),包括發(fā)送器和接收器的狀態(tài)信息和接收器的出錯信息,見表9-5。
表9-5 SCI狀態(tài)寄存器
寄存器名:SCISR1;地址:$00C4;復位默認值:11000000B;讀操作:任意;寫操作:無意義 |
| | | | | | | | |
| | | | | | | | |
當SCI硬件處于某些狀態(tài)時,SCISR1中的對應位置位,并通過特定的確認動作清除。先后對SCISR1和SCIDRL進行讀操作將清除與接收有關的標志位(RDRF、IDLE、OR、 NF、FE和PF),讀SCISR1然后寫SCIDRL將清除與發(fā)送有關的標志位(TDRE和TC)。
TDRE: 發(fā)送保持器空標志位。發(fā)送前必須讀SCISR1,并確認TDRE=1,然后將新的數(shù)據(jù)寫入發(fā)送保持器以開始發(fā)送過程。復位后該位為1。
0:SC0DR處于忙狀態(tài)。
1:發(fā)送保持器的數(shù)據(jù)已被傳送到發(fā)送移位器,這時可以向發(fā)送保持器寫入新的數(shù)據(jù)
TC: 發(fā)送結束標志。該位在發(fā)送器空閑(無發(fā)送動作)時置位。讀SCISRl,然后寫SCIDR將清除該位。
0:發(fā)送器忙。
1:發(fā)送器空閑。
RDRF:接收數(shù)據(jù)就緒標志。當收到的字符已經(jīng)在SCIDR中就緒時,RDRF置1,順次讀取SCISRl和SCIDR將會自動清除RDRF。該位被清除后,必須等到RxD線變?yōu)榛顒樱缓笾匦伦兂煽臻e以后,IDLE位才會被再次置1。
0:SCIDR空。
1:SCIDR中數(shù)據(jù)已就緒。
IDLE: 空閑標志。檢測到接收器RxD端空閑(收到10或者11個以上連續(xù)的“1”)。當RWU位為1時,空閑狀態(tài)不會使該位置1。該位被清除后,必須等到RDRF置位(RxD線變?yōu)榛顒,然后重新變成空閑),IDLE位才會被再次置1。
0:RxD線活動。
1:RxD線空閑。
OR:重疊錯誤標志。如果接收數(shù)據(jù)寄存器中的數(shù)據(jù)尚未讀取(RDRF=1),接受移位寄存器又準備向其傳送新的數(shù)據(jù),則稱為重疊錯誤,該位被置1。必須清除該位,才能使新的數(shù)據(jù)進入接收數(shù)據(jù)寄存器。
0:無重疊。
1:出現(xiàn)重疊錯誤。
NF:噪聲錯誤標志。噪聲錯誤出現(xiàn)時,該位與RDRF在同一個周器內(nèi)置位,但如果同時或已經(jīng)出現(xiàn)重疊錯誤,該位不置位。
0:采樣結果一致。
1:在起始位、數(shù)據(jù)位或停止位接收期間檢測到噪聲。
FE:幀格式錯誤。如果在應該出現(xiàn)停止位的時刻,檢測到0,則該位置位。順次讀取寄存器SCISRl和SCIDR將清除FE標志。
0:檢測到停止位。
1:在預期的停止位處檢測到0。
PF:奇偶錯誤標志。指示收到數(shù)據(jù)的奇偶性與校驗位是否一致。奇偶校驗允許(PE=1)時,該標志才有意義。所要求的奇偶性由SC0CR1中的PT位決定。
0:奇偶校驗正確。
1:奇偶校驗錯誤。
1.5 狀態(tài)寄存器2(SCISR2)表9-6 SCI狀態(tài)寄存器2
寄存器名:SCISR2;地址:$00C5;復位默認值:00000000B;讀操作:任意;寫操作:寫RAF無意義 |
| | | | | | | | |
| | | | | | | | |
BRK13:中止符長度控制位。
0:中止符長度為10或11位。
1:中止符長度為13或14位。
TXDIR:單線模式下發(fā)送管腳數(shù)據(jù)方向控制位。
0:單線模式下TxD腳用于輸入。
1:單線模式下TxD腳用于輸出。
RAF:接收器活動標志位。反映接收器是否處于活動狀態(tài)。在搜索起始位的RT1期間該位置1,當接收器器檢測到空閑狀態(tài)或者出現(xiàn)一個偽起始位(通常由于噪聲或波特率匹配錯誤引起)時,該位清0。該位由接收器前端控制,
1.6 數(shù)據(jù)寄存器(SCIDRH、SCIDRL) SCI內(nèi)部分別設有發(fā)送和接收兩個數(shù)據(jù)寄存器,其低位都通過SCIDRL訪問,讀操作返回接收數(shù)據(jù)寄存器RDR的內(nèi)容,寫操作數(shù)據(jù)置入發(fā)送數(shù)據(jù)寄存器TDR。當M=1即運行在9位數(shù)據(jù)模式時,SCIDRL和SCIDRH形成9位的SCI數(shù)據(jù)字,這時必須先寫入SCIDRH,以便與低位字節(jié)(SCIDRL)一起進入發(fā)送移位器。如果M=0即SCI只用于7位或8位的數(shù)據(jù)傳送,可以只訪問SCIDRL。當PE=1即奇偶校驗允許時,奇偶校驗位由硬件負責,無需軟件干預,見表9-7。
表9-7 SCI數(shù)據(jù)寄存器
寄存器名:SCIDRH、SCIDRL;地址:$00C6、$00C7;復位默認值;00000000B、00000000B; 讀操作:任意;寫操作:任意但寫R8無意義。 |
| | | | | | | | |
| | | | | | | | | |
| | | | | | | |
| | | | | | | | |
R8:接收到的位8,該位寫操作無效。當SCI設置成9位數(shù)據(jù)運行模式時,該位是從串行數(shù)據(jù)流中接收到的第9位。
T8:發(fā)送位8,任何時候可寫。當SCI設置成9位數(shù)據(jù)模式時,該位是送到串行數(shù)據(jù)流的第9位。該位不必為每個數(shù)據(jù)重新設置,每次發(fā)送可重復使用。 R7T7-ROT0: 收/發(fā)數(shù)據(jù)位7-0,讀操作返回只讀寄存器RDR的內(nèi)容,寫操作寫入只寫寄存器TDR。
第二節(jié) SCI應用示例下面看看實驗:
1、本實驗需軟件程序“穿口調(diào)試助手V2.0”。
2、實驗步驟:
1)保證單片機5V電源、串口通訊線與仿真板的連接無誤;
2)上電后建立新建文件,在main.c中輸入下面程序并寫如flash;
3)點擊圖標運行后,打開“助手”,在下面的發(fā)送框中輸入任意數(shù)字或字符,然后選擇自動或手動發(fā)送。
3、試驗結果
在“助手”下邊的發(fā)送框中輸入任意數(shù)字或字符,然后發(fā)送,接收到數(shù)據(jù)后,上面的顯示區(qū)就會將其以ASCII碼或十六進制的形式(可選)顯示出來。
4、源程序
- #include <hidef.h> /* common defines and macros */
- #include <mc9s12dp256.h> /* derivative information */
- #pragma LINK_INFO DERIVATIVE "mc9s12dp256b"
- byte sci_data;
- //發(fā)送子函數(shù)
- void SCI_Transmit(byte data){
- while(!SCI0SR1_TDRE);//SC0DR處于忙狀態(tài),等待。
- SCI0DRL=data;
- }
- //接收子函數(shù)
- void SCI_Receive(byte *data)
- {
- *data=SCI0DRL;
- }
- void main(void)
- { SCI0BDL=0x34; //總線為8M,波特率為9600
- SCI0CR2=0X2C; //允許中斷,允許發(fā)送,允許接受
- while(1)
- {
- while(!SCI0SR1_RDRF); //SCIDRL為空,等待數(shù)據(jù)就緒。
- SCI_Receive(&sci_data);
- SCI_Transmit(sci_data);
- }
- }
復制代碼
下面的源程序是利用SCI做的一個足球答題系統(tǒng),感興趣的同學可以看一下:
第四章 SPI模塊第一節(jié) SPI模塊介紹1.1 SPI的功能特點串行設備接口SPI主要用于同步串行通信,它使MCU具備了與外圍設備以及其他微處理器進行同步通信的能力,也能夠在多主系統(tǒng)中實現(xiàn)處理器間的通信?蛇B接的設備包括簡單的移位寄存器(例如74LSl65用作并行輸入口,或74LSl64用作并行輸出口等)、LCD顯示驅(qū)動器或AID轉換器的接口。MCU可選擇8種不同的位傳送頻率、兩種不同的時鐘極性、相位和位傳送順序,因此可直接與各個廠家生產(chǎn)的多種標準的串行外圍接口器件連接。在串行外圍接口中,數(shù)據(jù)和時鐘線是分開的,在SPI格式中,時鐘不包括在數(shù)據(jù)流中,它必須是另一個獨立的信號線。MC9S12DP256的SPI可定義為主機或從機方式,主要特性如下:(1)全雙工、三線同步傳送。
(2)單個數(shù)據(jù)引腳的雙向傳送方式。
(3)主機或從機工作方式。
(4)每一晶體頻率下可通過程序選擇八種不同的主機位傳送頻率。
(5)主機位傳送頻率最大4MHz,當MCU總線頻率=8MHz時最小為31.25kHz。
(6)從機位傳送頻率最大4MHz,允許頻率范圍為0-4MHz。
(7)可程控設置位時鐘極性、相位和數(shù)據(jù)位傳送順序,即可選高位在前或低位在前。
(8)發(fā)送完成中斷標志。
(9)多主機系統(tǒng)控制沖突保護中斷標志。
(10)寫沖突標志保護。
(11)可方便地與各種簡單擴展器件接口,如PLL、D/A、鎖存器、LCD顯示驅(qū)動器等。
SPI系統(tǒng)可在軟件控制下構成各種不同復雜程度的系統(tǒng),例如:
(1)一個主MCU和一個或者幾個從MCU。
(2)幾個MCU相互聯(lián)接構成多主機的系統(tǒng)(全分布式系統(tǒng))。
(3)一個主MCU和一個或者幾個從I/O設備。
(4)一個其他主微機系統(tǒng)和一個或者幾個從MCU。
1.2 SPl的組成與工作設置(一)SPl的結構與工作過程
1.SPI的結構組成
SPI系統(tǒng)主要由8位移位寄存器、時鐘控制邏輯、引腳控制邏輯、SPI控制邏輯和分頻器以及波特率寄存器SPIBR、狀態(tài)寄存器SPISR、控制寄存器1SPICR1、控制寄存器2SPICR2、數(shù)據(jù)寄存器SPIDR等5個寄存器組成,如圖1所示。
SPI的核心是一個8位移位寄存器。發(fā)送或接收時,引腳的數(shù)據(jù)流在時鐘信號SCK的作用下移出或移入該寄存器。該寄存器對用戶透明,CPU通過SPIDR與其聯(lián)系。發(fā)送時將數(shù)據(jù)寫入SPIDR將直接進入移位寄存器,即所謂單緩沖;而接受到的數(shù)據(jù)則通過讀數(shù)據(jù)緩沖器到達SPIDR,因此稱為雙緩沖,這樣可以保證移位寄存器正在接收時,CPU能正確讀取上一個收到的字節(jié)。
時鐘邏輯主要用于為移位寄存器提供工作時鐘。在主模式下,內(nèi)部波特率產(chǎn)生邏輯為其提供時鐘源,同時還通過SCK引腳輸出到外部從器件;在從模式下,外部主器件通過SCK引腳提供時鐘源。分頻器的時鐘頻率通過對SPIBD的設定來選擇,因而可以得到各種位傳送速率。時鐘控制邏輯將產(chǎn)生各種極性和相位的位時鐘(SCK)信號,還可以選擇傳送時數(shù)據(jù)高位在先還是低位在先,以適應各種不同的外圍器件。
控制寄存器SPICR1、SPICR2和SPIBR用來設置SPI的工作方式,包括主/從模式、數(shù)據(jù)位順序、時鐘極性、相位、波特率以及引腳邏輯等參數(shù)。狀態(tài)寄存器SPISR保存SPI的工作狀態(tài),包括傳送結束、寫沖突和模式錯誤等。
SPI0與PS口共享PS7-PS4引腳,SPI1與PP口共享PP7-PP4引腳, SPI2與PP口共享PP3-PP0引腳。當SPI系統(tǒng)使能時,四個引腳一般由通用I/O變?yōu)镾PI的有關引腳(

、SCK、MISO、MOSI)。但當 SPI工作在雙向模式時,個別引腳仍可用作通用I/O。
圖1 SPI接口的邏輯結構與寄存器設置
2.SPI引腳
對于SPI0,當SPE=1即SPI系統(tǒng)使能時,SPI使用PS口的四個引腳:串行位時鐘SCK、主機輸入/從機輸出數(shù)據(jù)線MISO、主機輸出/從機輸入數(shù)據(jù)線MOSI和低有效的從機選擇線

。在SPI系統(tǒng)關閉時,這四個引腳用作通用I/O線PS7-PS4。在通用I/O方式下,數(shù)據(jù)方向寄存器DDRS完全控制PS口引腳的數(shù)據(jù)方向,但SPI系統(tǒng)使能后,DDRS仍然參與對PS7-PS4引腳的控制,它與SPI控制寄存器共同決定相應引腳的功能。
從機選擇信號

:該信號總是由主機發(fā)給從機,低電平有效。
當 MSTR=0時,MCU的SPI被設置為從機方式,其

引腳為自身工作允許端(輸入狀態(tài)), SCK由外部主器件提供。若

引腳輸入為邏輯1,SPI不理會外部的SCK時鐘,并且MISO引腳為高阻抗狀態(tài)。當

輸入為邏輯0時,SPI被允許,在外部SCK的作用下接收或發(fā)送數(shù)據(jù)。在該方式下,

不受DDS7和SSOE的控制,固定為器件選擇輸入引腳。
若MSTR=1,SPI處于主機方式,其

引腳可選三種功能。
當DDS7=SSOE=0時,

引腳輸出從機選擇信號,SCK輸出SPI工作時鐘。若要選中外部從機,

引腳必須輸出邏輯 0,外部從機在SCK的作用下接收或發(fā)送數(shù)據(jù)。當

輸出邏輯1時,從器件被禁止。每一次傳送時,

輸出自動變低以選中外部器件,在傳送中間的空閑狀態(tài)回到高電平以釋放外部器件。
當DDS7=SSOE=1時,

引腳為SPI系統(tǒng)的工作方式?jīng)_突錯誤檢測輸入,正常情況下保持高電平。在分布式多主機系統(tǒng)中,多個器件均可能作為主機,但是同一時刻只能有一個主機。當已有一個器件作為主機并正在選擇從器件時,

引腳被其拉低到邏輯0,這時若 MCU將自身SPI設為主機,即置MSTR=1,SPI將會發(fā)現(xiàn)

已經(jīng)為邏輯0,表示已經(jīng)存在主機,于是發(fā)生了工作方式?jīng)_突錯誤,SPI自動置位MODF標志,并在SPIE=1時申請中斷,通知CPU處理。
當DDS7=1、SSOE=0時,

引腳為通用輸出引腳,與SPI系統(tǒng)無關。
當DDS7=0、SSOE=1時,

引腳為系統(tǒng)保留功能,用戶不能使用。
(2)串行數(shù)據(jù)線(MISO、MOSI)。MISO為主入/從出線,MOSI為主出/從入線,它們用于串行接收和發(fā)送數(shù)據(jù);數(shù)據(jù)高低位傳送順序由LSBF選擇。每個MOSI、MISO引腳都是雙向引腳,當SPICR寄存器的MSTR位由軟件置1時,SPI設置為主機方式,其MISO、 MOSI分別是數(shù)據(jù)輸入/輸出線,這時主機從它的MOSI腳輸出數(shù)據(jù),從它的MISO引腳輸入數(shù)據(jù)。當器件設置為從機方式時,其MISO變?yōu)閿?shù)據(jù)輸出線,而MOSI成為數(shù)據(jù)輸入線。在多主機系統(tǒng)中,無論主從,所有SCK引腳、MISO引腳和MOSI分別聯(lián)在一起。時鐘信號由主SPI的SCK引腳輸出,送到所有的從SPI的SCK引腳,主SPI的數(shù)據(jù)從其MOSI引腳輸出,送到所有從SPI的MOSI引腳;被選中的從SPI的數(shù)據(jù)從其MISO輸出,送到主SPI的MISO引腳。
(3)串行時鐘(SCK)。在SPI設置為主機方式時,SCK信號來自內(nèi)部MCU時鐘,并從其SCK引腳輸出。在主機起動一次傳送時,自動在SCK端產(chǎn)生8個SCK時鐘脈沖。對于從機,只有其

引腳為邏輯低電平時,才接收SCK時鐘信號,并與SCK同步發(fā)送或接收數(shù)據(jù)。無論是主SPI或從SPI,都是在SCK信號的一個跳變沿進行數(shù)據(jù)移位,在數(shù)據(jù)穩(wěn)定后的另一個跳變沿進行采樣。主機設備的SPIBR選擇時鐘頻率,與從機無關。主機和從機的SPI數(shù)據(jù)與位時鐘之間的傳送定時關系必須相同(由SPICR1的CPOL和CPHA位控制)。
另外,數(shù)據(jù)方向寄存器的DDRS4-DDRS6分別影響MISO、MOSI和SCK。若某一引腳作為輸出時,應使DDRS對應位置1,若作為輸入,則不受DDRS位影響。
3.SPI的雙向模式(MOMI或SISO)
當控制寄存器SPOCR2中的SPC0=1時,SPI進入一種雙向模式,事實上SPI原來就是雙向的,因此這里的雙向模式確切地說是單線雙向模式。在該模式下,SPI使用單一引腳與外部器件接口,具體引腳由MSTR控制位決定,在主模式下MOSI成為雙向引腳 MOMI,而在從模式下MISO成為雙向引腳SISO,引腳數(shù)據(jù)方向取決于相應的DDRS位。如表1所示。在使用雙向模式的系統(tǒng)中,所有需要雙向傳輸?shù)钠骷仨毠ぷ髟陔p向模式下。在雙向模式下,無論SPI作為主器件或從器件,均有一引腳重新獲得通用I/O功能。
表1 普通模式與雙向模式
4.SPI數(shù)據(jù)與位時鐘的各種時序關系
兩器件之間傳送信息,它們的時序必須一致。為了能與各種標準外圍設備接口,MCU提供了四種數(shù)據(jù)和位時鐘的時序關系,由CPOL和CPHA控制位選擇。將CPOL置1相當于在時鐘信號中串入一個反相器。除此以外,SPI還可以選擇數(shù)據(jù)位的傳送順序。時序相同時,將主機和從機的MISO、MOSI、SCK分別直接相聯(lián),即可構成一個主從系統(tǒng)。
圖2、圖3分別表示了CPHA為0、1時,單個字節(jié)數(shù)據(jù)傳送的時序。由圖可見,每個字節(jié)需要8個時鐘周期,傳送期間從器件選中信號

必須有效。這里以CPOL=O、LSBF=O為例,主機發(fā)送數(shù)據(jù)為例,對兩個時序圖簡單說明如下。
圖2 CHPA=O時的數(shù)據(jù)位與時鐘時間關系
圖3 CHPA=1時的數(shù)據(jù)位與時鐘時間關系
在圖2中,主機的

輸出邏輯0,選中從器件,同時MOSI輸出數(shù)據(jù)最高位,經(jīng)過半個時鐘周期后,在SCK的上升沿,從器件采樣MOSI線,保存結果。在SCK的下降沿,主機輸出下一個數(shù)據(jù)位,在下一個SCK的上升沿,從器件又采樣MOSI線,保存結果,如此循環(huán)八次,數(shù)據(jù)傳送結束,然后

再延遲半個時鐘周期后釋放,回到高電平,等待半個周期后可以開始下一次傳送過程。
在圖3中,

有效后,時鐘信號沒有立即輸出,因此傳送過程并沒有真正開始,而是半個周期后,時鐘和數(shù)據(jù)同時輸出,然后在時鐘的下降沿從器件采樣MOSI線,保存結果,其他與圖9-5類似。
5.SPI的工作過程
系統(tǒng)工作時,主機發(fā)送數(shù)據(jù)的同時也接收從機來的數(shù)據(jù),從機接收的同時也向主機發(fā)送數(shù)據(jù),這個過程就好像分別位于主從器件的兩個8位寄存器被“連接”在一起形成了一個分布式的16位寄存器。當進行數(shù)據(jù)傳輸時,該寄存器在主器件時鐘SCK控制下,連續(xù)循環(huán)移動8位,于是數(shù)據(jù)在主從器件之間實現(xiàn)了數(shù)據(jù)的有效交換。對于主器件來講,寫入SPIDR寄存器的數(shù)據(jù)成為送往從器件的輸出數(shù)據(jù),經(jīng)傳輸操作后,從SPIDR讀出的數(shù)據(jù)則是來自從器件的輸入數(shù)據(jù)。
當SPI控制寄存器SPICR1中的SPE=1時,SPI系統(tǒng)使能。SPICR1中的相位控制位CPHA和極性控制位CPOL用于決定當前的SPI系統(tǒng)使用的時鐘格式。CPOL只選擇正向還是反向時鐘,而CPHA則通過選擇是否將時鐘移相180度,來協(xié)調(diào)兩種不同的協(xié)議。
在主機方式中,CPU將數(shù)據(jù)寫入SPIDR時(寫入SPIDR的數(shù)據(jù)立即裝入8位移位寄存器中),起動一個傳送過程。SCK腳輸出8個位傳送時鐘,MOSI腳串行移位輸出數(shù)據(jù)到從機SPI。同時,數(shù)據(jù)也由從SPI通過MISO腳串行移位輸入到這個8位移位寄存器中。在傳送的第8次移位后,數(shù)據(jù)并行傳送到SPIDR,此后,CPU可讀出它的內(nèi)容。每完成一次數(shù)據(jù)傳送,SPRF狀態(tài)位置位,讀SPISR(SPRF為1時),訪問SPIDR,將SPIF位清0。
在從機方式中,CPU可先向SPIDR寫入需傳送到主機的數(shù)據(jù),該數(shù)據(jù)從內(nèi)部總線并行裝入8位移位寄存器中。與主機不同,該寫入不起動傳送,從機需等待主機的信號。當CPHA為0時,

腳的邏輯低電平,使數(shù)據(jù)的最高位輸出,在SCK的第一個跳變沿采樣輸入,在另一個跳變沿將數(shù)據(jù)的次高位輸出,當CPHA=1且

=0時,SCK引腳的第一個跳變沿啟動從機移位,將數(shù)據(jù)的最高位輸出,在下一個跳變沿采樣輸入,這使從機與主機同步。這時,來自主機的數(shù)據(jù)由從機的MOSI腳串行輸入,并移入8位移位寄存器,同時原來8位移位寄存器的數(shù)據(jù)由從機的MISO腳串行輸出至主機。在8次數(shù)據(jù)移位后,接收的數(shù)據(jù)并行傳送到SPIDR中,等待CPU讀出。同主機一樣,每完成一次數(shù)據(jù)的傳送,SPRF位置1,這時讀 SPSR隨后訪問SPIDR將SPRF位清0。
主機可發(fā)可收,從機可收可發(fā)。主機從機之間的數(shù)據(jù)傳送是雙向的。對于主機發(fā)、從機收的情況,主機由寫入SPIDR起動一次發(fā)送過程。對于主機收、從機發(fā)的場合,也由主機寫入SPIDR起動一次傳送過程,不過寫入SPIDR的數(shù)據(jù)與傳送無關。
正在傳送時,若寫入SPIDR,將引起寫沖突錯誤。對于主機,將打斷數(shù)據(jù)的傳送,對從機若寫入SPIDR,對數(shù)據(jù)的傳送無影響。
(二)波特率設置
P時鐘經(jīng)過一組級聯(lián)的分頻器形成SPI時鐘,分頻系數(shù)由SPIBR寄存器中的SPPR2~SPPR0和SPR2~SPR0共六位控制。波特率分頻因子的表達式為:
該波特率產(chǎn)生器必須滿足兩個條件才能激活:一是SPI為主器件,二是串行傳輸正在進行,否則處于關閉狀態(tài)以降低功率消耗。詳見波特率寄存器SPIBR的說明。
(三)中斷管理
SPI設置了兩種中斷,一是數(shù)據(jù)傳送結束中斷,另一個是模式?jīng)_突中斷,二者受同一個中斷允許位SPIE的控制,每次SPIF或MODF狀態(tài)標志置位時,若CCR中的全局中斷允許位I=1,則向CPU發(fā)出硬件中斷請求。讀SPOSR寄存器、然后讀或?qū)慡PI數(shù)據(jù)寄存器將清除標志位SPIF,讀SPOSR寄存器、然后寫SPI數(shù)據(jù)寄存器將清除標志位MODF。
第二節(jié) SPI寄存器簡介2.1 SPI控制寄存器1(SPICR1)SPI的工作方式主要由該寄存器設置,包括主從方式、單線雙向模式選擇,時鐘及位順序等,甚至包括引腳工作特性的設置,見表2。其各位意義如下:
表2 SPI控制寄存器1
寄存器名:SPICR1;地址:$00D0;復位默認值:00000100B;讀操作:任意; 寫操作:任意。 |
| | | | | | | | |
| | | | | | | | |
SPIE:SPI中斷允許位。
0: 禁止SPI中斷。
1: 每次SPRF或MODF狀態(tài)標志置位時發(fā)出硬件中斷請求。
SPE:SPI系統(tǒng)允許位。
當MODF=1時,SPE讀取結果總是0,SPOCR1的寫操作指令必須作為模式故障恢復序列的一部分嵌入其中。
0:SPI內(nèi)部硬件完成初始化,但SPI系統(tǒng)處于低功耗的禁止狀態(tài)。
1:SPI使能。
SPTIE:
0:SPTEF中斷不被允許。
1:SPTEF中斷允許。
MSTR:主、從模式選擇位,用于設定本機SPI以主器件還是從器件身份出現(xiàn)。
0:從模式。
1:主模式。
CPOL、CPHA: SPI時鐘極性、相位選擇位,這兩位用來指定SPI的時鐘格式。當無傳輸動作且CPOL=0時,主器件的SCK引腳處于低電平,而如果CPOL=1,SCK則閑置在高電平。參看圖9-6、圖9-7。
SSOE: 從器件選中輸出信號(

)允許位,

輸出功能只有在主模式下通過置位SSOE和DDRS7實現(xiàn)。
0: 禁止

輸出。
1: 允許

輸出,但同時DDRS7必須為1。
LSBF: SPI數(shù)據(jù)位傳輸順序選擇位,通常要求LSBF=0,即傳輸過程高位在先。該位只決定傳輸過程中各位的先后順序,不影響數(shù)據(jù)位在寄存器中的順序,因此讀寫操作正常進行,即高位(MSB)在第7位(BIT7)。對于僅由MC9S12DP256構成的互連系統(tǒng),只要各個SPI的LSBF相同,對傳輸結果無影響,但在與外圍設備或器件連接時,SPI必須根據(jù)該設備或器件所要求的位順序正確設置LSBF。
0: 數(shù)據(jù)傳輸高位(MSB)在先。
1: 數(shù)據(jù)傳輸?shù)臀?LSB)在先。
2.2 SPI控制寄存器2(SPICR2)表3 SPI控制寄存器2
寄存器名:SPICR2;地址:$00D1;復位默認值:00001000B;讀操作:任意;寫操作:任意。 |
| | | | | | | | |
| | | | | | | | |
MODFEN:模式錯誤使能位
0:禁止模式錯誤標志位置位。
1:允許模式錯誤標志位置位。
BIDIROE:雙向模式下輸出緩沖使能位
0:雙向模式下禁止輸出緩沖。
1:雙向模式下允許輸出緩沖。
SPISWAI:等待模式下SPI工作方式
0:等待模式下停止SPI時鐘。
1:等待模式下SPI時鐘正常工作。
SPC0:串行引腳控制,該位與MSTR位一起決定串行引腳功能設置。見表3
2.3 SPI波特率選擇寄存器該寄存器只有六個有效位SPPR2~SPPR0和SPR2~SPR0,用來確定SPI系統(tǒng)工作時鐘SCK的頻率,即波特率。復位默認值為0,。參看表9-11。
表4 SPI波特率選擇寄存器
寄存器名:SPIBDR;地址:$00D2;復位默認值為:00000000$;讀操作:任意;寫操作:任意。 |
| | | | | | | | |
| | | | | | | | |
SPPR2-SPPR0:波特率預選位;
SPR2-SPR0:波特率選擇位。
波特率分頻因子表達式為:
2.4 SPI狀態(tài)寄存器該寄存器反映SPI的工作狀態(tài),其中包括傳輸結束、寫沖突和模式故障三個標志位,程序可以檢查各位的狀態(tài),也可以通過特定的寄存器訪問序列將標志位清0,見表9—12。其各位意義如下:
表5 SPI狀態(tài)寄存器
寄存器名:SPISR;地址:$00D2;復位默認值:00100000B;讀操作:任意;寫操作:無意義。 |
| | | | | | | | |
| | | | | | | | |
SPIF:SPI中斷請求位,在數(shù)據(jù)傳輸過程中,SPRF在第8個SCK周期后置位,通過讀SPISR寄存器并隨后讀或?qū)憯?shù)據(jù)寄存器SPIDR清0。
0:傳輸正在進行或者根本沒有傳輸。
1:一次傳輸已經(jīng)結束。
SPTEF: 當SPIDR中的值送入移位寄存器中是,該位置1。同時如果SPTIE位為1,則向CPU發(fā)出中斷請求。讀SPISR然后寫SPIDR將清除該位。
0:SPI數(shù)據(jù)寄存器非空。
1:SPI數(shù)據(jù)寄存器空。
MODF:SPI模式錯誤中斷狀態(tài)位。當MSTR=1時,如果從選擇引腳

在外部被拉低成邏輯0,該位由SPI硬件自動置1。這時本機SPI已經(jīng)不能成功設定為主機,顯然這種情況在正常情況下是不允許的。當DDRS7=1時,PS7是通用輸出或

輸出引腳,而不是專用于SPI系統(tǒng)的

輸入引腳,在這種特殊情況下,模式故障功能被禁止,MODF保持為0。讀SPOSR隨后寫入SPOCR1將清0該位。
0:無異常。
1:系統(tǒng)中已經(jīng)出現(xiàn)另一個主機,并正在選中從器件。
2.5 SPI數(shù)據(jù)寄存器表6 SPI數(shù)據(jù)寄存器
寄存器名:SPIDR;地址:$00D5;復位默認值;讀操作:任意,一般在讀SPIF位后,寫操作:任意,讀SPTEF后 |
| | | | | | | | |
| | | | | | | | |
該8位寄存器是SPI數(shù)據(jù)寄存器,具有輸入、輸出雙重功能,見表6。對該寄存器進行讀操作時所訪問的輸入部分是雙緩沖的,但寫操作則直接將數(shù)據(jù)送到串行移位器。注意:某些簡單的從器件可能只有發(fā)送功能,只向主器件發(fā)送數(shù)據(jù)而不向主器件請求數(shù)據(jù),例如并行輸入串行輸出的TTL邏輯電路:或者只有接收功能,只從主器件接收而不返回數(shù)據(jù),例如串行輸入并行輸出的TTL邏輯電路。由于SPI的傳輸是一次交換過程,對于只發(fā)送數(shù)據(jù)的從器件,交換前主機可向SPODR寫入任何數(shù)據(jù);對于只接收數(shù)據(jù)的從器件,交換后主機 SPODR中的數(shù)據(jù)無意義。
第三節(jié) SPI應用實例利用單片機與顯示驅(qū)動芯片MC14489的SPI通訊實現(xiàn)計時器功能
(1)實驗設備:HCS12編程器、開發(fā)板、MC14489驅(qū)動芯片、數(shù)碼管
(2)軟件程序設計:串型外部通訊是單片機與外界設備聯(lián)系的重要方式。本例子利用HCS12單片機與MC14489芯片構成的具有串型通訊功能的電路,實現(xiàn)單片機與外部設備的串口通訊。并且利用程序的相應算法實現(xiàn)計時器的功能。
(3)源程序
#include <hidef.h> /* common defines and macros */
#include <mc9s12dp256.h> /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dp256b"
/*聲明變量*/
int n1,n2,n3,n4,n5,j=0;
word t1,t2,time;
byte mode=0;
/*SPI初始化*/
void SPI (void) {
SPI0CR1=0b01010000;
DDRS=0x60; //S5,S6為輸出,其余為輸入
SPI0BR=0x12;
SPI0CR2=0x00;
DDRT=0X01;//t0為輸出,其余為輸入
PTT=0X01;//T0=1
}
/*鍵盤中斷初始化*/
void PortInit(void){
DDRJ=0x00; //j腳數(shù)據(jù)方向寄存器為輸入
PIEJ=0X03; //j腳中斷允許寄存器
}
/*延時程序*/
void delay(word time){
for(t2=0;t2<time;t2++){
for(t1=0;t1<100;t1++){
}
}
}
/*將單字節(jié)數(shù)據(jù)寫入14489的配置寄存器*/
void DanZiJie(void) {
PTT=0X00;
delay(1);
SPI0DR=0b00000001;
while(!SPI0SR_SPTEF){;}
delay(3);
PTT=0X01;
}
/*發(fā)三字節(jié)數(shù)據(jù)*/
void SanZiJie (void) {
PTT=0X00;
delay(1);
SPI0DR=0x80+n1;
while(!SPI0SR_SPTEF){;}
SPI0DR=0x00+n2*16+n3;
while(!SPI0SR_SPTEF){;}
SPI0DR=0x00+n4*16+n5;
while(!SPI0SR_SPTEF){;}
delay(3);
PTT=0X01;
}
/*主程序*/
void main(void) {
SPI();
DanZiJie();
PortInit();
EnableInterrupts;
while(1){
n1=j/10000;
n2=j/1000%10;
n3=j/100%10;
n4=j/10%10;
n5=j%10;
j++;
SanZiJie();
delay(15600);
}
}
/*鍵盤中斷子程序*/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
interrupt void PortJISR(void){
switch(PIFJ){ //J腳中斷標志寄存器
case 0x01: mode=0; PIFJ_PIFJ0=1;
for (;;){
}
break;
}
}
(4)調(diào)試結果
程序運行,計時器開始工作,本計時器的工作范圍(1s—99999s)。按下Key1計時停止,記錄時間,按下Reset鍵,計時重新開始。
第五章 A/D轉換模塊第一節(jié) A/D模塊介紹1.1 A/D轉換原理模擬信號依次通過抽樣和保持(S/H)電路和模擬轉換器(A/D)后轉換為數(shù)字格式。
抽樣和保持電路以均勻間隔對模擬信號進行抽樣,并且在每個抽樣運算后在足夠的時間內(nèi)保持抽樣值恒定,以保證輸出值可以被A/D轉換器精確轉換。
下一步是通過模數(shù)轉換器將抽樣和保持電路的輸出轉換為數(shù)字形式。模數(shù)轉換器的輸出通常表示為二進制編碼的形式。
轉換精度由分辨率來表示,它由離散級數(shù)量決定。比如,對一個以二進制形式編碼的長度為N位的長的輸出,有效地離散級數(shù)量是2的N次方,分辨率為離散數(shù)量級的倒數(shù)。
1.2 A/D轉換原理的應用前景A/D轉換器是模擬信號源與計算機或其他數(shù)字系統(tǒng)之間聯(lián)系的橋梁,它的任務是將連續(xù)變化的模擬信號轉換為數(shù)字信號,以便計算機或數(shù)字系統(tǒng)進行處理、存儲、控制和顯示。在工業(yè)控制和數(shù)據(jù)采集及許多其他領域中,A/D轉換器是不可缺少的重要組成部分。
1.3 A/D轉換模塊12中A/D轉換共有兩個方塊,每個方塊各有8個輸入通道,使用時應以標頭ATD0或ATD1標識。
1.4 功能結構圖圖 2.1 功能結構圖
圖中所示的是A/D模塊的功能結構,這個功能模塊被虛線劃分成為圖示所示的虛線所隔離的三個部分:IP總線接口、轉換模式控制/寄存器列表,自定義模擬量。
IP總線接口負責該模塊與總線的連接,實現(xiàn)A/D模塊和通用I/O的目的,還起到分頻的作用;
轉換模式控制寄存器列表中有控制該模塊的所有的寄存器,執(zhí)行左右對齊運行和連續(xù)掃描。
自定義模擬量負責實現(xiàn)模擬量到數(shù)字量的轉換。包括了執(zhí)行一次簡單轉換所需的模擬量和數(shù)字量。
1.5 HCS12A/D特點8/10 位精度;7 us, 10-位單次轉換時間.;采樣緩沖放大器;可編程采樣時間;左/右對齊, 有符號/無符號結果數(shù)據(jù);外部觸發(fā)控制;轉換完成中斷;模擬輸入8通道復用;模擬/數(shù)字輸入引腳復用;1到8轉換序列長度;連續(xù)轉換模式;多通道掃描方式。
ATD模塊有模擬量前端、模擬量轉換、控制部分及結果存儲等四部分組成。其中模擬前端包括多路轉換開關、采樣緩沖器、放大器等,結果存儲部分主要有8個16位的存儲器和反映工作狀態(tài)的若干標志位。
第二節(jié) A/D寄存器簡介要完成ATD轉換的特定功能,必須對相關寄存器有所了解。在12ATD模塊中,ATDCTL2,3,4,5為常用的控制寄存器,ATDSTAT0,1為常用的兩個狀態(tài)控制器,ATDDR0-7為八個結果寄存器。
ATD工作時,由CPU發(fā)出啟動命令,然后經(jīng)采樣、模數(shù)轉換,最后將結果保存到相應的寄存器。
ATD每次啟動要進行若干個掃描循環(huán),每個掃描循環(huán)稱為一個轉換序列,每個轉換序列能包含1-8最多8次轉換,由控制寄存器ATDCTL3中的S8C/S4C/S2C/S1C等位來決定。
這些轉換序列可以針對某個單一通道,也可以針對幾個相鄰通道,每個通道可以使外部模擬輸入,也可以是參考電壓或其他保留信號,ATD可支持多種不同的通道信號組合。每次轉換包括哪些通道由ATDCTL5中的CC、CB、CA決定的。
對單一通道連續(xù)進行多次轉換有利于實現(xiàn)濾波,一次轉換多個通道則可以通過一次啟動命令快速瀏覽多個信號,中間無需CPU干涉,節(jié)約了CPU時間。
ATD的運行方式分為單次和連續(xù)運行兩種。
在單次方式下,每個轉換序列完成后,寄存器ATDSTAT中的SCF置位,然后ATD模塊暫停。
在連續(xù)方式下,轉換以轉換序列為單位連續(xù)進行,當?shù)谝粋轉換序列完成后,SCF置位,同時ATD模塊開始下一個轉換序列。
在上述兩種方式下,每個通道的轉換結果進入到對應結果寄存器后,寄存器ATDSTAT1種對應的CCF位置1,對存放轉換結果的寄存器進行讀操作后,CCF位將自動清0。轉換過程的啟動是通過寫入寄存器5ATDCTL5實現(xiàn)的。
ATD轉換所需要的時鐘周期數(shù)是固定不變的,但是采樣時間和時鐘頻率可以通過ATDCTL4在一定范圍內(nèi)選擇,因此轉換時間也可以選擇。
2.1 控制寄存器2(ATDCTL2)
ADPU - A/D 電源使能/禁止
1 = A/D模塊上電
0 = 禁止A/D,以減少功耗
AFFC - A/D 快速轉換完成標志位清零
1 = 快速標志位清零順序 每次讀取結果寄存器自動清零
0 = 正常標志位清零順序 需要手動對狀態(tài)標志位清零
AWAI - A/D 等待模式
1 = 等待模式下,轉換
0 = 等待模式下,禁止轉換
ASCIE - A/D 順序完成中斷使能
ETRIGLE | ETRIGP | ETRIGE | SCAN | 描述 |
x | x | 0 | 0 | 忽略外部觸發(fā),執(zhí)行一次轉換后停止 |
x | x | 0 | 1 | 忽略外部觸發(fā),執(zhí)行連續(xù)轉換后 |
0 | 0 | 1 | X | 下降沿觸發(fā),每次觸發(fā),執(zhí)行一次轉換 |
0 | 1 | 1 | X | 上升沿觸發(fā),每次觸發(fā),執(zhí)行一次轉換 |
1 | 0 | 1 | X | 低電平觸發(fā),每次觸發(fā),執(zhí)行連續(xù)轉換 |
1 | 1 | 1 | X | 高電平觸發(fā),每次觸發(fā),執(zhí)行連續(xù)轉換 |
2.2 控制寄存器3(ATDCTL3)FIFO – 結果寄存器 FIFO
1 = 結果寄存器映射到轉換序列
0 = 結果寄存器沒有映射到轉換序列
2.3 控制寄存器4(ATDCTL4)SRES8 - A/D 精度選擇
1 = 8 位
0 = 10位
5位 模數(shù)計數(shù)器預分頻器
- 由A/D控制寄存器中的PRS[4:0]控制
- 分頻系數(shù)從2到64
- 如果 PRS[4:0] = 0, 預分頻不起作用
注: 設置PRS[4:0]時, A/D Clock 不能大于 2 MHz.
SMP [1:0] | 采樣時間 |
00 | 2 A/D時鐘周期 |
01 | 4 A/D時鐘周期 |
10 | 8 A/D時鐘周期 |
11 | 16 A/D時鐘周期 |
轉換時間計算:
2.4 控制寄存器5(ATDCTL5)
2.5 狀態(tài)寄存器
SCF – 轉換序列完成標志
- 在單次轉換模式時,當轉換完成后置位 (SCAN = 0)
在連續(xù)轉換模式時,當?shù)谝淮无D換完成后置位 (SCAN = 1).
當 (AFFC = 0) ,寫1清零.
ETORF - 外部觸發(fā)覆蓋標志
- 如果在轉換過程中高/低電平出現(xiàn),置位FIFOR
–當結果寄存器在讀出之前已經(jīng)被寫入時,置位 ( CCF沒有清零)
CC[2:0]轉換計數(shù)器
3-位計數(shù)器指向下一個將要轉換的通道
CCF7 -CCF0–獨立通道轉換完成標志位
每個相應的通道轉換結束后置位, 當相應的A/D結果寄存器被讀出時,清零 ,注意當AFFC位不同時的情況
第三節(jié) A/D應用示例3.1 編程步驟要讓ATD開始轉換工作,必須經(jīng)過以下三個步驟:
1.將ADPU置1,使ATD啟動;
2.按照要求對轉換為數(shù)、掃描方式、采樣時間、時鐘頻率及標志檢查等方式進行設置;
3.發(fā)出啟動命令;
如果上電默認狀態(tài)即能滿足工作要求,那么只要將ADPU置1,然后通過控制寄存器發(fā)出轉換命令,即可實現(xiàn)轉換。
3.2 A/D程序示例—單通道查詢- #include <hidef.h> /* common defines and macros */
- #include <mc9s12dp256.h> /* derivative information */
- #pragma LINK_INFO DERIVATIVE "mc9s12dp256b"
- int ADValue;
- void AD_Init(void) //初始化
- {
- ATD0CTL2=0xc0; //定義寄存器2
- ATD0CTL3=0x20; //定義寄存器3
- ATD0CTL4=0xc3; //定義寄存器4
- ATD0CTL5=0xa6; //定義寄存器5
- ATD0DIEN=0x00; // 禁止數(shù)字輸入
- }
- int AD_GetValue(void) //讀取AD轉換結果
- {
- ADValue = ATD0DR0; //讀結果寄存器
- }
- void main(void)
- {
- AD_Init(); //AD初始化
- DDRB = 0xFF;//portB均為輸出通道
- PORTB = 0x00;
- for(;;)
- {
- while(!(ATD0STAT1&0x01)){;} //等待轉換結束
- AD_GetValue(); //讀取轉換結果
- PORTB = (int)ADValue; //在B口顯示轉換值
- }
- }
復制代碼
3.3 A/D程序示例—濾波12中A/D系統(tǒng)啟動一次A/D轉換,能對同一模擬量輸入連續(xù)執(zhí)行多次轉換。利用此功能,使用下面的程序,可在一次采樣中執(zhí)行四取二數(shù)字濾波,從而可濾除干擾,得到精度較高的A/D轉換結果。
- #include <hidef.h> /* common defines and macros */
- #include <mc9s12dp256.h> /* derivative information */
- #pragma LINK_INFO DERIVATIVE "mc9s12dp256b"
- static long ADValue0, ADValue1,ADValue2,ADValue3;
- long a,b,c,d;
- long m,n,sum;
- long max();
- long min();
- void AD_Init(void) //初始化
- {
- ATD0CTL2=0xc0; //定義寄存器2
- ATD0CTL3=0x20; //定義寄存器3
- ATD0CTL4=0xc3; //定義寄存器4
- ATD0CTL5=0x86; //定義寄存器5
- ATD0DIEN=0x00; // 禁止數(shù)字輸入
- }
- void AD_GetValue0(void) //讀取AD轉換結果
- {
- ADValue0 = ATD0DR0; //讀結果寄存器0
- a=ADValue0;
- }
- void AD_GetValue1(void) //讀取AD轉換結果
- {
- ADValue1 = ATD0DR1; //讀結果寄存器1
- b=ADValue1;
- }
- void AD_GetValue2(void) //讀取AD轉換結果
- {
- ADValue2 = ATD0DR2; //讀結果寄存器2
- c=ADValue2;
- }
- void AD_GetValue3(void) //讀取AD轉換結果
- {
- ADValue3 = ATD0DR3; //讀結果寄存器3
- d=ADValue3;
- }
- void main(void)
- {
- AD_Init(); //AD初始化
- DDRB = 0xFF;
- PORTB = 0x00;
- for(;;)
- {
- while(!(ATD0STAT1&0x01)){;} //等待轉換結束
- AD_GetValue0(); //讀取轉換結果
- while(!(ATD0STAT1&0x02)){;} //等待轉換結束
- AD_GetValue1(); //讀取轉換結果
- while(!(ATD0STAT1&0x04)){;} //等待轉換結束
- AD_GetValue2(); //讀取轉換結果
- while(!(ATD0STAT1&0x08)){;} //等待轉換結束
- AD_GetValue3(); //讀取轉換結果
- m=max(a,b,c,d);
- n=min(a,b,c,d);
- sum=(a+b+c+d-m-n)/2;
- }
- }
復制代碼
3.4 A/D程序示例—定時采樣在實際應用中,經(jīng)常需每隔一段時間對某個模擬量進行一次采樣。為實現(xiàn)定時A/D采樣,可使用12中的輸出比較功能來控制定時,其定時時間間隔可設定。在發(fā)生定時器輸出比較中斷時,進行啟動A/D轉換。然后等待A/D轉換完成,讀入數(shù)據(jù)。為了不浪費CPU時間去等待轉換的完成,可使用中斷方式。
本程序有兩部分組成:一為初始化和啟動程序,另一位定時器輸出比較中斷處理程序。CCF為標志字節(jié),它的最高位為1,表示完成一次A/D轉換,由程序可讀入的值,并應清零該位。TOF為定時器控制標志位,=0表示為處于啟動A/D狀態(tài);=1表示為等待定時時間到,以便下次采樣。
- #include <hidef.h> /* common defines and macros */
- #include <mc9s12dp256.h> /* derivative information */
- #pragma LINK_INFO DERIVATIVE "mc9s12dp256b"
- int ADValue0;
- unsigned int i=0;
- int counter=0;
- void AD_Init(void) //初始化
- {
- ATD0CTL2=0xc0; //定義寄存器2
- ATD0CTL3=0x08; //定義寄存器3
- ATD0CTL4=0xc3; //定義寄存器4
- ATD0CTL5=0xa0; //定義寄存器5
- ATD0DIEN=0x00; // 禁止數(shù)字輸入
- }
- void AD_GetValue0(void) //讀取AD轉換結果
- {
- ADValue0 = ATD0DR0; //讀結果寄存器0
- }
- void main(void)
- {
- TSCR2_PR = 7; //prescale factor is 8, bus clock/128=8Mhz/8
- TSCR2_TOI = 1; //timer overflow interrupt enable
- TSCR1_TEN = 1; //timer enable
- AD_Init(); //AD初始化
- DDRB = 0xFF;
- PORTB = 0x00;
- EnableInterrupts;
- for(;;) {
- }
- }
- #pragma CODE_SEG NON_BANKED
- #pragma TRAP_PROC
- void Int_TimerOverFlow(void)
- {
- {
- counter++;
- if(counter==10)
- {
- while(!(ATD0STAT1&0x01)){;} //等待轉換結束
- AD_GetValue0(); //讀取轉換結果
- PORTB = (int)ADValue0; //在B口顯示轉換值
- for(i=0;i<=1000;i++); //delay
- counter=0;
- }
- }
- TFLG2_TOF = 1; //clear timer overflow flag
- }
- #pragma CODE_SEG DEFAULT
復制代碼
第六章 EEPROM模塊
MC9S12DP256B內(nèi)部同時集成了兩種非易失存儲器:FLASH和EEPROM,前者用于存儲程序,后者可用來保存組態(tài)、設置等關鍵數(shù)據(jù),它們均為防止誤操作而設置了各種保護措施。本章主要介紹EEPROM的功能、特點及使用,包括擦除與寫入步驟。
第一節(jié) EEPROM模塊介紹1.1 EEPROM功能MC9S12DP256內(nèi)部集成了4KB的EEPROM存儲器,具有單塊和整塊擦除、編程、靈活保護和安全功能、快速區(qū)域擦除和字編程模式特點,規(guī)范字訪問可在單總線周期內(nèi)完成。EEPROM是一種非易失性存儲介質(zhì),具有穩(wěn)定、保密性好的特點,在系統(tǒng)掉電后,EEPROM中的內(nèi)容仍能可靠保持不變,可以用來保存一些短時間不變的內(nèi)容(如環(huán)境參數(shù)、產(chǎn)品序列等)。EEPROM可以同RAM一樣地讀,但要向EEPROM寫入需要一定的時序和花費比RAM多的時間,即需要一段特定的程序來寫EEPROM。
1.2 EEPROM結構$0000~$0FFF是4KB為EEPROM的存儲空間,復位時默認的EEPROM地址是從0開始的,而單片機各I/O寄存器的地址已經(jīng)占用了從0地址開始的1KB空間,故EEPROM中開始的1KB空間($0000---$03FF)看不到了,所以實際上用戶可以訪問的是$0400---$0FFF的3KB的存儲空間。
EEPROM設有保護機制,用戶可以通過編程$0FFD,在普通模式下設定需要的保護空間,保護空間可在64B、128B、192B、256B、320B、384B、448B、512B中進行選擇,相應的保護區(qū)在$0XXX---$0FFFF。由于設定保護地址所訪問的地址也在所保護的區(qū)域中,所以一旦用戶在普通模式下對$0FFD的內(nèi)容進行了編程,就無法再在此模式下修改保護區(qū)的內(nèi)容,從而也就達到了寫保護或禁止局部擦除的效果。要改變保護區(qū)的設定,需要單片機工作在“特殊模式”下,訪問EPROT寄存器,而一旦在特殊模式下取消了保密屬性,該區(qū)的內(nèi)容也就被擦除了。
1.3 EEPROM特點①單電源供電擦寫
②自動編程和擦除算法
③命令執(zhí)行完可產(chǎn)生中斷
④快速扇區(qū)擦除和字編程操作
⑤靈活的保護機制,避免意外編程和擦除
第二節(jié) EEPROM寄存器簡介2.1 時鐘分頻寄存器ECLKDIVEDIVLD:EEPROM時鐘分頻加載。ECLKDIV寄存器被寫入時此位置“1”;若此位置“0”,F(xiàn)CLKDIV寄存器從最后復位后沒有寫入。在沒有寫入此寄存器之前,擦寫和編程eeprom將引起進入錯誤和命令不被執(zhí)行。
1:最后復位后寄存器寫入。
0:寄存器沒有寫入。
PRDIV8:8分頻控制。
0 - 晶振時鐘為EEPROM時鐘分配器的時鐘源
1 - 晶振時鐘除以8后,為EEPROM時鐘分配器的時鐘源
EDIV[5:0] 時鐘分配器位
PRDIV8和EDIV[5:0]聯(lián)合用于將外部晶振頻率分頻為150~200KHZ。
注意:在對EEPROM進行操作之前,必須對時鐘進行初始化
這個頻率用于驅(qū)動EEPROM擦寫和編程。外部晶振頻率大于12.8MHZ,PRDIV8置1位,CLK=OSCCLK/8。反之,PRDIV8 置零,CLK=OSCCLK。
ECK=CLK/(EDIV[5:0]+1)。
2.2 配置寄存器ECNFGCBEIE:命令緩沖區(qū)空中斷允許位,
0:命令緩沖區(qū)空中斷關閉。
1:命令緩沖區(qū)空中斷允許。
CCIE — 指令完成中斷使能,當所有指令被完成該位產(chǎn)生中斷
0:命令完成中斷關閉。
2.3 保護寄存器EPROTEPOPEN:開啟EEPROM編程/擦寫
1:全部EEPROM或是部分EEPROM可以擦寫;
0:所有EEPROM塊保護。
EPDIS:EEPROM部分保護位
1:不作部分保護EEPROM。
0:EEPROM部分保護。
EP[2:0]——EEPROM保護地址范圍
2.4 狀態(tài)寄存器ESTATCBEIF:命令緩沖區(qū)空中斷標志,表示地址、數(shù)據(jù)命令緩沖去空,新的命令序列開始,標志寫“1”清零,通過標志清零,發(fā)出命令序列。寫“0”將取消沒有發(fā)出的命令序列,并ACCERR標志置“1”。
1:緩沖準備好接受新的命令。
0:緩沖器滿
CCIF— 命令完成中斷標志,表明不再有未決的指令。該標志通過硬件寫入來清除,寫操作不起作用。
1:所有命令完成。
0:命令正在進行。
PVIOL:保護沖突標志。表示在保護地址空間內(nèi)進行了擦寫或編程操作,在此標志置位同時,后續(xù)的擦寫或編程操作無法進行。標志寫“1”清零,寫“0” 無影響。在CBEIF清零后或者當CCIF清零時,寫入新的有效命令可以使保護錯誤標志清零。
1:保護沖突已發(fā)生。
0:無故障。
BLANK — 空白校驗標志
表明在響應一條擦除校驗指令后EEPROM塊已被完全地擦除
該標志位通過寫“1”被清除.
1 = EEPROM 被完全擦除.
0 = EEPROM未被完全擦除
ACCERR— 存取錯誤標志
表明在編程或擦除時序中有錯誤。該標志位通過寫“1”來清除。
1 = 存取錯誤已出現(xiàn)
0 = 指令時序或執(zhí)行被成功完成
ACCERR:進入錯誤標志。表示非法進入EEPROM塊或者與定義命令序列沖突。以下命令序列會引起ACCERR置位:
1在初始化ECLKDIV之前,向EEPROM地址寫值;
2向EEPROM地址寫入錯誤的字或字節(jié);
3在CBEIF未置1時,向EEPROM地址寫值;
4在執(zhí)行前一個編程或擦除命令之前,向EEPROM地址寫入第二個字
5在向EEPROM地址空間寫入字后,接著寫其它EEPROM寄存器,沒有寫ECMD寄存器;
6在執(zhí)行前一個寫好的命令之前,向ECMD寄存器寫入第二個命令;
7在對有保護的EEPROM空間,向ECMD寄存器寫入整塊擦除命令;
8在對有保護的EEPROM空間,向ECMD寄存器寫入部分擦除命令;
9在寫完命令寄存器后,接著寫其它EEPROM寄存器,而沒有寫ESTAT寄存器;
10在命令行列已開始或擦/寫命令已執(zhí)行的同時,從EEPROM塊讀取。這樣讀到無效數(shù)據(jù)。
2.5 命令寄存器ECMDERASE:EEPROM擦除
0: 無意義
1: 在MASS=0時,區(qū)域擦除;在MASS=1時,區(qū)域擦除;
PROG:EEPROM編程
0: 無意義。
1: EEPROM 編程。
ERVER:擦除校驗:
0: 無意義。
1: 區(qū)域擦除后擦除校驗。
MASS: 全局鏟除
0: 部分擦除
1: 全部擦除
注意:只有在ERASE和MASS同時置1時,才能實現(xiàn)全部擦除。
有關寄存器ECMD的命令字的設置:
第三節(jié) EEPROM應用實例3.1 EEPROM的寫入操作EEPROM的寫入操作可以按照以下步驟進行:
1. ECLKDIV寄存器初始化,確定分頻因子
2. 檢查EEPROM時鐘分頻寄存器(ECLKDIV_EDIVLD)是否已 經(jīng)設置
3. 檢查命令緩沖區(qū)(ESTAT_CBEIF)是否為空
4. 對讀寫錯誤(ESTAT_ACCER)標志位清零(寫1清零)
5. 對保護區(qū)編程錯誤(ESTAT_PVIOL)標志位清零(寫1清零)
6.檢查保護寄存器(EPROT_EPOPEN)是否允許編程/寫
7. 將編程的數(shù)據(jù)賦值給要編程的EEPROM地址
8. 對EEPROM命令寄存器(ECMD)寫入編程命令(0x20)
9. 對命令緩沖區(qū)空標志位(ESTAT_CBEIF)清零(寫1清零)
10. 等待,直到命令完成標志位(ESTAT_CCIF)置位
3.2 EEPROM的擦除操作1. ECLKDIV寄存器初始化,確定分頻因子
2. 檢查EEPROM時鐘分頻寄存器(ECLKDIV_EDIVLD)是否已經(jīng)設置
3.檢查命令緩沖區(qū)(ESTAT_CBEIF)是否為空
4.對讀寫錯誤(ESTAT_ACCER)標志位清零(寫1清零)
5.對保護區(qū)編程錯誤(ESTAT_PVIOL)標志位清零(寫1清零)
6.檢查保護寄存器(EPROT_EPOPEN)是否允許編程/寫
7. 在要擦除的EEPROM的段地址內(nèi)寫入任意數(shù)據(jù)
8. 對EEPROM命令寄存器(ECMD)寫入段擦除命令(0x40)
9. 對命令緩沖區(qū)空標志位(ESTAT_CBEIF)清零(寫1清零)
10. 等待,直到命令完成標志位(ESTAT_CCIF)置位
3.3 EEPROM示例程序(見附件)
第七章 FLASH模塊
MC9S12DP256B內(nèi)部同時集成了兩種非易失存儲器:FLASH和EEPROM,前者用于存儲程序,后者可用來保存組態(tài)、設置等關鍵數(shù)據(jù),它們均為防止誤操作而設置了各種保護措施。本章主要介紹flash的功能、特點及使用,包括擦除與寫入步驟。
第一節(jié) FLASH模塊介紹1.1 FLASH功能MC9S12DP256內(nèi)部集成了256KB的FLASH存儲器,具有單塊和整塊擦除、編程、靈活保護和安全功能、快速區(qū)域擦除和字編程模式特點,規(guī)范字訪問可在單總線周期內(nèi)完成。可以存放整個程序或者需要高速訪問或經(jīng)常運行的程序代碼,如操作系統(tǒng)核心或標準子程序庫、數(shù)據(jù)表格等。FLASH模塊對于單芯片應用系統(tǒng)是理想的程序存放處,它允許在現(xiàn)場進行代碼更新。
Flash是一種非易失性存儲介質(zhì),讀取它的內(nèi)容同RAM的讀取一樣方便,而對它的寫操作卻比EPROM還要快。同時,在系統(tǒng)掉電后,F(xiàn)lash中的內(nèi)容仍能可靠保持不變。Flash的主要優(yōu)點是結構簡單、集成密度大、成本低。由于Flash可以局部擦除,且寫入、擦除次數(shù)可達數(shù)萬次以上,從而使開發(fā)微控制器不再需要昂貴的仿真器。
1.2 FLASH結構$4000~4FFFF是48KB為FLASH的存儲空間,分成3個16KB空間如圖1-1所示。最后16KB空間的最后256B,即$FF00~$FFFF是中斷向量表空間。由于FLASH模塊的地址范圍超過STAR12(16位)最大地址64KB空間,因此模塊采用從一個$8000~$BFFF 16KB地址窗口分配地址,其余的地址位分配在分頁寄存器PPAGE。256KB的FLASH由4個64KB塊組成,如表3-1所示,每塊64KBFLASH按照16位二進制方式組織,支持按字節(jié)或字方式訪問。字節(jié)和規(guī)則字的訪問可在單總線周期內(nèi)完成,非規(guī)則字訪問需兩個總線256KB的FLASH被分成4個64KB塊,每一塊又可以繼續(xù)細分為16KB一頁,共16頁。每一頁再細分為4KB、2KB、1KB、或者512B一段。
圖1-1 MC9S12DP256B置位后的內(nèi)存
1.3 FLASH特點• 自動編程和擦除算法
• 快速扇區(qū)擦除和字編程操作
• 指令完成時中斷
• 2段命令流水線,快速實現(xiàn)多個字的編程
• 靈活的保護機制,避免意外編程和擦除
• 預防非法訪問的加密特征
第二節(jié) FLASH寄存器簡介FLASH寄存器如表2-1所示
2.1 時鐘分頻寄存器FCLKDIVFDIVLD:FLASH時鐘分頻加載。FCLKDIV寄存器被寫入時此位置“1”;若此位置“0”,F(xiàn)CLKDIV寄存器從最后復位后沒有寫入。在沒有寫入此寄存器之前,擦寫和編程FLASH將引起進入錯誤和命令不被執(zhí)行
0 - FCLKDIV 寄存器沒有被寫過
1 - FCLKDIV 寄存器從最近一次復位起已經(jīng)被寫過
PRDIV8 使能時鐘8分頻
0 - 晶振時鐘為FLASH時鐘分配器的時鐘源
1 - 晶振時鐘除以8后,為FLASH時鐘分配器的時鐘源
FDIV[5:0] 時鐘分配器位
—PRDIV8 和FDIV[5:0]的設置,必須滿足FLASH時鐘在150 kHz – 200 kHz范圍內(nèi)。最大的分頻系數(shù)為512。在對FLASH進行操作之前,必須對時鐘進行初始化,否則接下來的任何操作將是無效的。
2.2 配置寄存器 FCNFGCBEIE — 指令緩沖區(qū)空中斷使能
該位在空地址,數(shù)據(jù)和指令緩沖區(qū)的情況下使能中斷。
1 = CBEIF標志被置位產(chǎn)生中斷請求
0 = 指令緩沖區(qū)空中斷禁止
CCIE — 指令完成中斷使能
當所有指令被完成該位產(chǎn)生中斷
1 = CCIF 標志被置位產(chǎn)生中斷請求
0 = 指令完成中斷禁止
KEYACC — 使能安全密匙寫入
1 = 寫入flash模塊被解釋成打開后門的密匙.
0 = Flash 寫入后編程或擦除過程的開始
2.3 安全寄存器 FSECKEYEN:安全門碼控制。
1:允許通過BDM或外部總線接口開啟安全門。
0:禁止通過BDM或外部總線接口開啟安全門。
當KEYEN置1時,用戶可以通過以下步驟避開安全檢查
FCNFG寄存器中KEYACC置1。
通過安全門比較碼地址向FLASH 寫四個正確16位字。
將FCNFG寄存器中KEYACC置0。
如果全部四個字與FALSH內(nèi)容相符,強制通過SEC[1:0]處于非安全狀態(tài),使MCU處于非安全狀態(tài)。
6.如果全部四個字與FALSH內(nèi)容不相符,MCU處于安全狀態(tài),向CPU發(fā)回安全沖突信號。
NV[6:2]:非沖突標志位。這5位是用戶可以用做非沖突標志。
SEC0[1:0] 存儲安全位。這2位決定設備的安全狀態(tài)。如表2-2所示
表2-3 SEC0[1:0] 與安全狀態(tài)關系
2.4 保護寄存器 FPROTFPOPEN—FLASH編程或擦除保護
1 = FPHDIS和FPLDIS定義的FLASH地址區(qū)域不被保護
0 =
FPHDIS—Flash 保護高地址范圍禁止
該位用來決定在Flash塊地址映射的較高末端是否存在一個被保護的區(qū)域
1 = 保護禁止
0 = 保護使能
FPHS[1:0]—Flash 保護高地址范圍
這兩位用來決定保護區(qū)域的范圍。
FPLDIS—Flash 保護較低的地址范圍禁止
該位用來決定在Flash塊地址映射的較低末端是否存在一個被保護的區(qū)域
1 = 保護禁止
0 = 保護使能
FPLS[1:0]—Flash保護低地址范圍
這兩位用來決定保護區(qū)域的范圍
2.5 狀態(tài)寄存器 FSTAT 狀態(tài)寄存器CBEIF— 指令緩沖區(qū)空中斷標志
表明地址,數(shù)據(jù)和指令緩沖區(qū)為空因此一個新的指令序列可以開始。
該標志通過寫人“1”清除。指令序列通過清除該位來開始。
寫入“0” 可異常中止一個尚未開始的指令序列且置ACCERR標志
1 = 緩沖區(qū)準備接收一個新指令
0 = 緩沖區(qū)滿
CCIF— 指令完成中斷標志
表明不再有未決的指令。該標志通過硬件寫入來清除
寫操作不起作用。
1 = 所有指令都被完成
0 = 指令進行中
PVIOL— 保護錯誤標志
表明試圖對被保護的存儲器區(qū)域中的一個地址編程或擦除。
若該位被置1則并行的編程或擦除指令不能被執(zhí)行。該標志通過寫入“1”被
清除,也可通過在CBEIF被清零后或當CCIF 被清除時寫一條新的,有效
的指令來清除
1 = 保護系統(tǒng)侵犯已出項
0 = 無故障
ACCERR— 存取錯誤標志
表明在編程或擦除時序中有一個錯誤。該標志位通過寫
“1”來清除。
1 = 存取錯誤已出現(xiàn)
0 = 指令時序或執(zhí)行被成功完成
ACCERR:進入錯誤標志。表示非法進入FLASH塊或者與定義命令序列沖突。以下命令序列會引起ACCERR置位:
1.在初始化FCLDIV之前,向FLASH地址寫值;
2.當分頁寄存器沒有選擇16KBFLASH塊,向$8000~$BFFF地址空間的FLASH寫值;
3.向$4000~$7FFF地址空間的FLASH寫值或在BKSEL[1:0]沒選FALSH 0下,向$C000~$FFFF地址空間的FLASH寫值;
向FLASH地址空間寫入錯誤的字或字節(jié);
4.CBEIF未置1時,向FLASH地址寫值;
5.在執(zhí)行前一個編程或擦除命令之前,向FLASH地址空間寫入第二個字;
6.在向FLASH地址空間寫入字之后,接著寫其他FLASH寄存器,沒有寫FCMD寄存器;
7.在執(zhí)行完前一個寫好的命令之前,向FCMD寄存器寫入第二個命令;
8.在對有保護FLASH空間,向FCMD寄存器寫入整塊擦除命令;
9.在對有保護FLASH空間,向FCMD寄存器寫入部分擦除命令;
10.在寫完命令寄存器后,接著寫其他FLASH寄存器,沒有寫FSTAT寄存器;
11.在命令序列已開始或擦除/編程命令以執(zhí)行的同時,從FLASH塊讀取。這樣讀到無效數(shù)據(jù),但能讀其他沒有編程的FLASH塊。
BLANK:FLASH塊校驗標志,表示響應的擦除—校驗命令時FLASH塊全部擦除,標志寫“1”清零,寫“0” 無影響。
1:FLASH塊全部擦除
0:FLASH塊沒有全部擦除
BITS[1:0] 這兩位用于工廠測試預留,用戶無法使用。
2.6 命令寄存器 FCMDERASE:FLASH 擦除
0: 無意義
1: 在MASS=0時,區(qū)域擦除;在MASS=1時,區(qū)域擦除;
PROG:FLASH 編程
0: 無意義。
1: FLASH 編程。
ERVER:擦除校驗:
0: 無意義。
1: 區(qū)域擦除后擦除校驗。
MASS: 全局鏟除
0: 部分擦除
1: 全部擦除。
第三節(jié) FLASH應用實例3.1 FLASH的寫入操作FLASH的寫入操作可以按照以下步驟進行:
1. FCLKDIV寄存器初始化,確定分頻因子
2.設置FCNFG寄存器和PPAGE寄存器,用于管理命令序列。寫FCNFG寄存器中的BKSEL[1;0]位,選擇要擦除或編程的FALKSH塊狀的相應寄存器。如果編程在8000~BFFF地址范圍內(nèi),向(內(nèi)核)寄存器(X030)寫入值選擇要編程的某一16KB頁。當編程在4000~7FFF或C000~FFFF地址范圍,沒有必要寫分頁寄存器。
3. 檢查FLASH時鐘分頻寄存器(FCLKDIV_FDIVLD)是否已經(jīng)設置
4. 檢查命令緩沖區(qū)(FSTAT_CBEIF)是否為空
5. 對讀寫錯誤(FSTAT_ACCER)標志位清零(寫1清零)
6. 對保護區(qū)編程錯誤(FSTAT_PVIOL)標志位清零(寫1清零)
7. 將編程的數(shù)據(jù)賦值給要編程的FLASH地址
8. 對FLASH命令寄存器(FCMD)寫入編程命令(0x20)
9. 對命令緩沖區(qū)空標志位(FSTAT_CBEIF)清零(寫1清零)
10. 等待,直到命令緩沖區(qū)標志位(FSTAT_CBEIF)置位
11. 檢查是否還有新的數(shù)據(jù)需要寫入到FLASH,如有轉到第7步
12. 等待,直到命令完成標志位(FSTAT_CCIF)置位
3.2 FLASH的擦除操作1. FCLKDIV寄存器初始化,確定分頻因子
2.設置FCNFG寄存器和PPAGE寄存器,用于管理命令序列。寫FCNFG寄存器中的BKSEL[1;0]位,選擇要擦除或編程的FALKSH塊狀的相應寄存器。如果編程在8000~BFFF地址范圍內(nèi),向(內(nèi)核)寄存器(X030)寫入值選擇要編程的某一16KB頁。當編程在4000~7FFF或C000~FFFF地址范圍,沒有必要寫分頁寄存器。
3. 檢查FLASH時鐘分頻寄存器(FCLKDIV_FDIVLD)是否已經(jīng)設置
4. 檢查命令緩沖區(qū)(FSTAT_CBEIF)是否為空
5. 對讀寫錯誤(FSTAT_ACCER)標志位清零
6. 對保護區(qū)編程錯誤(FSTAT_PVIOL)標志位清零
7. 在要擦除的FLASH的段地址內(nèi)寫入任意數(shù)據(jù)
8. 對FLASH命令寄存器(FCMD)寫入段擦除命令(0x40)
9. 對命令緩沖區(qū)空標志位(FSTAT_CBEIF)清零
10. 等待,直到命令完成標志位(FSTAT_CCIF)置位
3.3 FLASH的擦寫操作注意事項a、由于在FLASH的擦除和寫入過程中,F(xiàn)LASH是不能讀的,故擦除和寫入FLASH的程序要放在RAM中,換言之,在FLASH的擦除或?qū)懭胫,要把擦除或(qū)懭氲目蓤?zhí)行代碼復制到RAM中去,并讓程序在RAM中執(zhí)行。這段程序的編譯是在FLASH中的程序段復制到RAM中的數(shù)據(jù)段,不論這段程序復制到RAM中的哪一段,即無論程序的起始地址在哪里,程序都能正確執(zhí)行。這就要求生成的程序和裝載地址無關,程序可以重載。
b、系統(tǒng)初始化后一定要嚴格按照上述步驟規(guī)范設置,這樣避免出現(xiàn)邏輯錯誤也便于檢查錯誤。此外,在編程選擇寫入或者擦除的范圍時,一定要明確所選區(qū)域是否需要設置分頁寄存器。
3.4 FLASH示例程序
各位智能車同仁,加油哦!當然記得支持本店哦!我們一定會竭誠為你服務
第八章 CodeWarrior IDE 12應用
第一步:雙擊桌面CodeWarrior IDE 12圖標,進入CodeWarrior IDE 12運用界面。在打開的界面中點擊菜單File,在其下拉菜單中點擊New,新建數(shù)據(jù)庫文件。

第二步:新建一個數(shù)據(jù)庫,如圖選擇第一行(HC(s)12New Project Wizard),然后再右面命名123(任意命名均可),確定。

第三步:進入歡迎界面,點擊下一步。然后選擇芯片型號MC9S12DP256B,點擊下一步。程序一定要與單片機型號一直,否則在硬件調(diào)試中會出現(xiàn)錯誤。
第四步:選擇使用的語言,在此選擇C語言,點擊“下一步”。
第五步:選擇調(diào)試專家,在此選擇“NO”,點擊“下一步”。
第六步:界面如下圖所示,選擇“NO”,點擊“下一步”。
第七步:界面如下圖所示,選擇” ANSI startup code” ,點擊“下一步”。
第八步:選擇有無浮點格式,根據(jù)自己情況而定,本程序在此選擇“None”,點擊“下一步”。
第九步:界面出現(xiàn)“選擇存儲模式?”,選擇Banked,點擊下一步。
第十步:界面出現(xiàn)“選擇硬件連接電纜型號?”,前兩項全選中,點擊“完成”。
第十一步:進入如下界面,點擊左側Sources文件前面的加號,選擇主程序中的Main.c,雙擊左鍵進入。
第十二步:顯示界面如下,其中右側為Main.c的編輯環(huán)境,可以在此輸入你的單片機程序,也可以刪除、修改或拷貝你前面編輯完成的程序。
例如當輸入以下源程序:
#include <hidef.h> /* common defines and macros */
#include <mc9s12dp256.h> /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dp256b"
void main(void)
{
PWME_PWME0=0; //關閉0通道
PWMPRCLK=0X05; //對總線時鐘進行預分頻,總線時鐘為8M,分頻后為250K
PWMCLK_PCLK0=0; //設A為其時鐘源
PWMSCLA=0X7D; //A時鐘為2000Hz
PWMPOL_PPOL0=1;//上升沿翻轉
PWMCAE_CAE0=0;//左對齊輸出
PWMDTY0=0X01; //占空比為25%的波形
PWMPER0=0X04; //輸出為500Hz的波
PWMCNT0=0X00;//0通道計數(shù)器清0
PWME_PWME0=1;//0通道使能,0通道為輸出通道
}
第十三步:程序輸入以后,點擊工具欄的

圖標(make)檢查程序是否有錯,如果有錯,會在編輯框上方提示錯誤警告,以

為標志,程序中會隨之用紅色箭頭在程序中標出出錯位置。例如下圖中的程序有兩個錯誤(第12行少了一個分號,導致無法編譯通過)。檢查程序并修改,直到?jīng)]有錯誤為止。
前面介紹的屬于程序在計算機中的編譯運行,不需要開發(fā)工具,適用于初試開發(fā)和檢查程序有無語法錯誤。下面介紹采用開發(fā)板的實際調(diào)試過程:
第一步:在上述單片機程序編譯的基礎上,將編程器與仿真試驗板連接好,編程器下載口用數(shù)據(jù)線同計算機相連,試驗板與5V直流電源相連。點擊

圖標開始調(diào)試(debug),進入調(diào)試仿真狀態(tài)后會出現(xiàn)如下界面。
第二步:在上面的界面中點擊“確定”以后。會出現(xiàn)下面界面“連接失敗”,仍點擊“確定”。
第三步:在上面的界面單擊“確定”以后,會出現(xiàn)如下界面單擊“取消”
第四步:在單擊“取消”以后,出現(xiàn)“硬件連接”失敗界面如下圖所示,單擊確定。
,

第五步:在上面的界面單擊“確定”以后,會發(fā)現(xiàn)光標在COMMAND窗口in>后閃動,輸入字母set gdi(注意set和gdi之間有一個空格)后單擊“回車鍵”。
第六步:單擊Browse按鈕,在安裝的軟件文件夾mc12中找到指定文件tbdml_gdi12.dll,然后單擊“確定”。
第七步:在上面的界面單擊“確定”以后,在圖示窗口輸入晶振頻率數(shù)值16:00后單擊“OK”。
第八步:在上面的界面單擊“確定”以后,在如下界面中單擊“OK”。

第九步:在TBDML HCS12中單擊Load,然后在自己建立的文件夾里找到bin文件夾,單擊bin文件夾然后再雙擊其中的第一個文件即可將源程序下載到flash中。
第十步:單擊圖示按鈕

即可執(zhí)行所編程序功能。
完整的Word格式文檔51黑下載地址: