電子發(fā)燒友網(wǎng):隨著駕駛員對(duì)車內(nèi)舒適度和便利性的要求在提高,汽車車身電子產(chǎn)品在保持具有競(jìng)爭(zhēng)力價(jià)格的同時(shí),還需要繼續(xù)提供性能更高的半導(dǎo)體。飛思卡爾半導(dǎo)體目前開始擴(kuò)大現(xiàn)已普及的16位S12微控制器(MCU)系列,以優(yōu)化大量對(duì)成本敏感的汽車車身電子應(yīng)用。先進(jìn)的S12G器件設(shè)計(jì)針對(duì)應(yīng)用需求,提供靈活的內(nèi)存、封裝和成本選項(xiàng)。MC9S12G系列是一個(gè)專注于低功耗、高性能、低引腳數(shù)量的高效汽車級(jí)16位微控制器產(chǎn)品。這個(gè)系列是橋連8位高端微機(jī)和16位高性能微機(jī),像MC9S12XS系列。本文將詳細(xì)介紹關(guān)于飛思卡爾MC9S12系列的芯片簡(jiǎn)介、MC9S12單片機(jī)最小系統(tǒng)硬件設(shè)計(jì)、典型程序應(yīng)用、飛思卡爾XS128和G128兩種單片機(jī)的主要區(qū)別等進(jìn)行闡述。
飛思卡爾MC9S12G系列單片機(jī)中文簡(jiǎn)介
1.1介紹
MC9S12G系列是一個(gè)專注于低功耗、高性能、低引腳數(shù)量的高效汽車級(jí)16位微控制器產(chǎn)品。這個(gè)系列是橋連8位高端微機(jī)和16位高性能微機(jī),像MC9S12XS系列。MC9S12G系列是為了滿足通用汽車CAN或LIN/J2602通信應(yīng)用。這些應(yīng)用的典型例子包括body controllers, occupant detection, doormodules, seat controllers, RKE receivers, smart actuators, lighting modules, and smart junction boxes.
MC9S12G系列使用了許多MC9S12XS系列和MC9S12P系列里面的相同特性,包括在閃存(flash memory)上的糾錯(cuò)指令(ECC),一個(gè)快速A/D轉(zhuǎn)換器(ADC)和一個(gè)為了改善電磁兼容性(EMC)性能的頻率調(diào)制相位鎖存循環(huán)(IPLL)。
MC9S12G系列是高效的對(duì)較低的程序存儲(chǔ)器至16K。為了簡(jiǎn)化顧客使用它,特制了一個(gè)4字節(jié)可擦除扇區(qū)的EEPROM。
MC9S12G系列傳送所有16位單片機(jī)的優(yōu)勢(shì)和效率,定位于低成本,低功耗,EMC,現(xiàn)行代碼尺寸效率優(yōu)勢(shì)被現(xiàn)存8位和16位單片機(jī)系列的使用者所分享。像MC9S12XS系列,MC9S12G系列運(yùn)行16位位寬的訪問(wèn)對(duì)所有的周期和存儲(chǔ)器狀態(tài)都不用等待。
MC9S12G系列可得到的封裝有100-pin LQFP, 64-pin LQFP, 48-pinLQFP/QFN, 32-pin LQFP and 20-pin TSSOP,特別是對(duì)較少引腳的封裝發(fā)揮出最大的功能。此外,在每個(gè)模塊中可得到的I/O口,進(jìn)一步的可用于中斷的I/O口允許從停止或等待模式中喚醒。
?
1.2特點(diǎn)
這部分說(shuō)明了MC9S12G系列的關(guān)鍵特性。
1.2.1MC9S12G系列比較
表1-1提供了MC9S12G系列不同型號(hào)特點(diǎn)的概要。這個(gè)微機(jī)系統(tǒng)提供了一個(gè)明確的功能范圍信息。
飛思卡爾MC9S12G系列芯片引腳圖
飛思卡爾MC9S12G系列芯片內(nèi)部資源模塊框圖
表1-1 MC9S12G系列概述
并不是所有的外圍設(shè)備都能夠應(yīng)用于所有封裝類型
表1-2顯示出了每個(gè)封裝外圍設(shè)備或外圍信道的最大值。并不是所有的外圍設(shè)備都能夠同時(shí)使用??墒褂玫耐鈬O(shè)備的最大值還受到表1-1中所選芯片的限制。
表1-2 每個(gè)封裝可使用外圍設(shè)備的最大值
1.2.2 芯片水平特點(diǎn)
在這個(gè)系列里面可應(yīng)用的模塊包括以下特點(diǎn):
S12內(nèi)核
高達(dá)240KB的片內(nèi)在線可編程FLASH存儲(chǔ)器防糾錯(cuò)閃存
高達(dá)4KB防糾錯(cuò)EEPROM
高達(dá)11KB片內(nèi)SRAM
擁有內(nèi)部濾波器的鎖相環(huán)回路(IPLL)頻率乘法器
4-16MHz振幅控制穿透振蕩器
1MHz內(nèi)部RC振蕩器
定時(shí)單元(TIM)支持達(dá)到8通道(提供16位輸入俘獲,輸出比較,計(jì)數(shù),脈沖存儲(chǔ)器功能)
多達(dá)8*8通道脈寬調(diào)節(jié)(PWM)模塊
多達(dá)16通道,10位或12位分辨率逐次近似計(jì)算法模數(shù)轉(zhuǎn)換器(ADC)
多達(dá)兩個(gè)8位數(shù)模轉(zhuǎn)換器(DAC)
多達(dá)3個(gè)串行外圍接口模塊(SPI)
多達(dá)3個(gè)串行通信接口(SCI)模塊(支持LIN通信)
多達(dá)一個(gè)多級(jí)控制局域網(wǎng)(MSCAN)模塊(支持CAN2.0 A/B 協(xié)議)
在線片內(nèi)穩(wěn)壓器(VREG)用于控制內(nèi)部供給和內(nèi)部電壓
自動(dòng)周期性中斷(API)
固定電壓基準(zhǔn)精度參考ADC轉(zhuǎn)換器
為汽車電子定造
飛思卡爾S12G系列是需要CAN(控制器區(qū)域網(wǎng)絡(luò))或LIN(本地互連網(wǎng)絡(luò))/SAE J2602通訊的汽車應(yīng)用的理想之選,這些應(yīng)用包括車身控制器、車門模塊、乘客檢測(cè)、空調(diào)、座椅控制器和照明模塊。這款16位S12G系列基于業(yè)界公認(rèn)的S12架構(gòu),提供更復(fù)雜的應(yīng)用設(shè)計(jì)所需的處理功能,保留了代碼的有效性,同時(shí)還利用了廣泛的S12生態(tài)系統(tǒng),而這則有助于減少內(nèi)存占用和開發(fā)成本。
MC9S12G128/96和MC9S12GN32/16是MC9S12G系列在市場(chǎng)上最先推出的四款主要產(chǎn)品。
汽車車身電子市場(chǎng)正在開發(fā)各種新應(yīng)用,該市場(chǎng)對(duì)不同類型的微控制器應(yīng)用具有特定的要求,需要不同的功能集。飛思卡爾這款先進(jìn)的16位產(chǎn)品系列,能夠?yàn)榭蛻魩?lái)可靠的16位MCU產(chǎn)品的高性能,并且以8位MCU產(chǎn)品的價(jià)格提供更多的功能,進(jìn)而實(shí)現(xiàn)更大的價(jià)值。
成熟的工藝技術(shù)
可擴(kuò)展S12G系列填補(bǔ)了高端8位MCU和高性能16位MCU之間的空白。它采用成熟、高性價(jià)比的0.18微米工藝,提供能在大量低端車身應(yīng)用范圍工作的選項(xiàng)。汽車設(shè)計(jì)人員能夠在內(nèi)存器大小的封裝內(nèi)向上、向下遷移,并且與整個(gè)S12G系列完全兼容。此外,該16位產(chǎn)品系列包括板載EEPROM等增值功能,幫助客戶設(shè)計(jì)出更復(fù)雜、但仍然對(duì)用戶友好的應(yīng)用。
MC9S12G系列是經(jīng)過(guò)優(yōu)化的汽車級(jí)16位微控制器產(chǎn)品線,具有低成本、高性能、引腳數(shù)量少的顯著特點(diǎn)。MC9S12G系列適合需要CAN或LIN/SAE J2602通信的一般汽車應(yīng)用。
MC9S12G系列具有16位MCU的所有優(yōu)點(diǎn)和性能,同時(shí)保留了飛思卡爾現(xiàn)有8位和16位MCU系列用戶所享有的低成本、低功耗、電磁兼容性(EMC)以及代碼效率等優(yōu)勢(shì)。
關(guān)于MC9S12G系列16位MCU的特性:
?總線頻率為25MHz的S12 CPU內(nèi)核提供業(yè)界公認(rèn)的S12架構(gòu)和處理能力,以解決更復(fù)雜的傳統(tǒng)8位應(yīng)用設(shè)計(jì)版本;
?高達(dá)240KB的片上閃存(包括糾錯(cuò)碼(ECC))可用來(lái)存儲(chǔ)代碼,幫助減少板上閃存/ROM;
?高達(dá)4KB的EEPROM(包括ECC)提供的用戶界面比以前幾代產(chǎn)品的數(shù)據(jù)快閃更簡(jiǎn)單;
?采用多個(gè)可擴(kuò)展CAN模塊(支持CAN協(xié)議2.0A/B),專為支持CAN通信端口復(fù)雜的系統(tǒng)需求而設(shè)計(jì);
?三個(gè)串行通信接口模塊用于支持LIN通信,三個(gè)串行外設(shè)接口(SPI)模塊可以提供更好的靈活性、更多的選項(xiàng)和優(yōu)勢(shì),同時(shí)需要增加SCI/LIN或SPI通信端口;
?在外設(shè)和存儲(chǔ)器中提供16位存取,無(wú)等待狀態(tài);
?閃存從16K到240K不等,封裝從20TSSOP到100LQFP不等,提供靈活的嵌入式設(shè)計(jì)和最大的功能;
?每個(gè)模塊不但提供I/O端口,而且還在I/O端口提供中斷功能,允許從停止或等待模式中喚醒;
?高達(dá)11KB片上SRAM,提供更多存儲(chǔ)單元;
?精密固定電壓參考用于ADC轉(zhuǎn)換;
? 1MHz內(nèi)部振蕩器;
?片上穩(wěn)壓器調(diào)節(jié)輸入電源和所有內(nèi)部電壓。
復(fù)位及時(shí)鐘—復(fù)位
上電復(fù)位
單片機(jī)自動(dòng)檢測(cè)VDD端的正跳變,啟動(dòng)自動(dòng)工作。
外部復(fù)位
通過(guò)RESET引腳加一低電壓,拉低超過(guò)一定時(shí)間
后可實(shí)現(xiàn)復(fù)位。
看門狗復(fù)位
幫助系統(tǒng)在軟件跑飛后自動(dòng)復(fù)位。
時(shí)鐘監(jiān)視器復(fù)位
利用內(nèi)部的RC電路來(lái)保證時(shí)鐘頻率滿足要求。
振蕩器和時(shí)鐘電路
EXTAL是外部時(shí)鐘輸入或石英振蕩放大器的輸入
XTAL是石英振蕩放大器的輸出
注:DG128可用串聯(lián)振蕩電路和并聯(lián)振蕩電路兩種連接方式。
9S12X系列單片機(jī)只可用并聯(lián)振蕩電路。
?
時(shí)鐘初始化寄存器-共5個(gè)
?
?。?)鎖相環(huán)控制寄存器(PLLCTL)
(2)時(shí)鐘合成寄存器(SYNR)-低6位有效,有效值0~63。
?。?)時(shí)鐘分頻寄存器(REFDV)-低4位有效,有效值0~15。
由鎖相環(huán)來(lái)產(chǎn)生時(shí)鐘頻率的公式:
例如:選用16MHz的外部晶振,若將SYNR設(shè)為
2,REFDV設(shè)為1,通過(guò)公式計(jì)算可得
PLLCLK=48MHz。從而得到系統(tǒng)的總線頻
率為24MHz。
PLL例子
CLKSEL=0x00; //禁止PLL
PLLCTL=0xe1; //PLL電路允許
SYNR=2;REFDV=1; //設(shè)置倍頻參數(shù)
PLLCTL=0x60; //時(shí)鐘監(jiān)控禁止
while(0==(CRGFLG&0x08));//等待穩(wěn)定
CLKSEL=0x80; //選擇PLL作為時(shí)鐘
//若晶振為16M,則PLLCLK=2*16*3/2=48MHz,則總線頻率是24MHz
RTI程序舉例
RTICTL = 0x7e;//4M/15*2^16 = 4Hz
CRGINT = 0x80;
// 中斷使能
得到大約每秒4次的中斷
MC9S12單片機(jī)最小系統(tǒng)硬件設(shè)計(jì)
——以MC9S12DG128為例
時(shí)鐘電路給單片機(jī)提供一個(gè)外接的16MHz的石英晶振
串口的RS-232驅(qū)動(dòng)電路可實(shí)現(xiàn)TTL電平到RS-232電平的轉(zhuǎn)換
BDM口讓用戶可以通過(guò)BDM調(diào)試工具向單片機(jī)下載和調(diào)試程序
供電電路主要是由單片機(jī)提供+5V電源和電源濾波
復(fù)位電路是通過(guò)一個(gè)復(fù)位按鍵給單片機(jī)一個(gè)復(fù)位信號(hào),調(diào)試過(guò)程中很有用。
單片機(jī)MC9S12G128應(yīng)用程序(PWM_Timer_ADC……)
???????
?
PWM應(yīng)用程序
/*
程序?qū)崿F(xiàn)功能:PP1口輸出PWM方波
程序說(shuō)明:通過(guò)改變duty和period ,從而控制PWM周期和占空比
duty cycle=duty/period
PWM frequency=1M/(2*period)(Fbus=24M,scla=24)
*/
#include 《hidef.h》 /* common defines and macros */
#include “derivative.h” /* derivative-specific definitions */
void SetBusClock_24MHZ(void);
void PWMDisable(byte channel);
void PWMEnable(byte channel);
void PWMSinglePortSetting(byte channel ,byte period ,byte duty) ;
void PWMsinglePortInitial(byte channel, byte clkab,byte clock, byte polarity,byte align) ;
void Service_WD(void);
void PWMGeneralInitial(byte prclk,byte scla,byte sclb,byte ctl);
void PWMConcatenateSetting(byte channel,word period,word duty);
void main(void)
{
/* put your own code here */
//總線時(shí)鐘頻率設(shè)置:24M
SetBusClock_24MHZ();
//對(duì)預(yù)分頻時(shí)鐘,分頻時(shí)鐘A,分頻時(shí)鐘B和控制寄存器的配置
//0分頻 01級(jí)聯(lián)
PWMGeneralInitial(0,24,0,0x10);
//PWM端口寄存器的配置
// 1通道 SA時(shí)鐘 起始高電平 左對(duì)齊
PWMsinglePortInitial(1,0,1,1,0);
//PWM級(jí)聯(lián)輸出配置
//50HZ 占空比12.5%
PWMConcatenateSetting(1,10000,250);
//EnableInterrupts;
for(;;) {
_FEED_COP(); /* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}
//*********************************************
//函數(shù)名:PWMEnable
//函數(shù)功能:PWM單個(gè)端口使能
//函數(shù)參數(shù):一個(gè) byte 類型channel 代表PWM通道號(hào)
// 返回值:無(wú)
//********************************************
void PWMEnable(byte channel)
{
if(channel》7) channel=7;
PWME|=(1《《channel); //選擇使能位
}
//**********************************************
//函數(shù)名稱:PWMDisable
//函數(shù)功能:PWM單個(gè)端口禁止
//函數(shù)參數(shù):一個(gè)byte類型 channel 代表PWM通道號(hào)
//返回值:無(wú)
//***********************************************
void PWMDisable(byte channel)
{
if(channel》7) channel=7;
PWME&=~(1《《channel); //選擇禁止位
}
//函數(shù)功能:?jiǎn)?dòng)看門狗
void Service_WD(void)
{
CPMUARMCOP=0x55;
CPMUARMCOP=0xAA;
}
//函數(shù)功能:總線時(shí)鐘設(shè)置
void SetBusClock_24MHZ(void)
{
CPMUOSC_OSCE=1; //enable osc
/*
時(shí)鐘倍頻:24MHz BusClock
48MHz VCO
48MHz PLL
*/
CPMUSYNR=0x00|0x05; //VCOFRQ[1:0],SYNDIV[5:0]
CPMUREFDIV=0x20|0x03;//REFFRQ[1:0],REFDIV[3:0]
CPMUPOSTDIV=0x00; //POSTDIV=0;
while(!CPMUFLG_LOCK)//等待VCO穩(wěn)定
Service_WD(); //看門狗
CPMUCLKS_PLLSEL=1;
}
//*********************************************
//函數(shù)名稱: PWMSinglePortSetting
//函數(shù)功能:實(shí)現(xiàn)PWM周期寄存器和占空比寄存器通道的單獨(dú)輸出
//函數(shù)參數(shù):3個(gè) byte類型
//參數(shù)1: channel代表了當(dāng)前配置的PWM通道
//參數(shù)2: period 周期配置參數(shù)
/*
Left aligned output (CAEx = 0) PWMx Period = Channel Clock Period * PWMPERx
Center Aligned Output (CAEx = 1) PWMx Period = Channel Clock Period * (2 * PWMPERx)
*/
//參數(shù)3: duty 占空比配置參數(shù)
/*
Polarity = 0 (PPOL x =0) Duty Cycle = [(PWMPERx-PWMDTYx)/PWMPERx] * 100%
Polarity = 1 (PPOLx = 1) Duty Cycle = [PWMDTYx / PWMPERx] * 100%
*/
//返回值:無(wú)
//**********************************************
void PWMSinglePortSetting(byte channel ,byte period ,byte duty)
{
if(channel》7) channel=7;
PWMDisable(channel); //禁止該通道
switch(channel)
{
case 0:
PWMPER0=period; //設(shè)置周期寄存器
PWMDTY0=duty; //設(shè)置占空比寄存器
break;
case 1:
PWMPER1=period; //設(shè)置周期寄存器
PWMDTY1=duty; //設(shè)置占空比寄存器
case 2:
PWMPER2=period; //設(shè)置周期寄存器
PWMDTY2=duty; //設(shè)置占空比寄存器
break;
case 3:
PWMPER3=period; //設(shè)置周期寄存器
PWMDTY3=duty; //設(shè)置占空比寄存器
break;
case 4:
PWMPER4=period; //設(shè)置周期寄存器
PWMDTY4=duty; //設(shè)置占空比寄存器
break;
case 5:
PWMPER5=period; //設(shè)置周期寄存器
PWMDTY5=duty; //設(shè)置占空比寄存器
break;
case 6:
PWMPER6=period; //設(shè)置周期寄存器
PWMDTY6=duty; //設(shè)置占空比寄存器
break;
case 7:
PWMPER7=period; //設(shè)置周期寄存器
PWMDTY7=duty; //設(shè)置占空比寄存器
break;
default:break;
}
PWMEnable(channel);
}
//*********************************************
//函數(shù)名:PWMSinglePortInitial
//函數(shù)功能:PWM端口寄存器的配置
//函數(shù)參數(shù):5個(gè)byte類型
//參數(shù)1:channel 代表了當(dāng)前配置的PWM通道
//參數(shù)2:clkab 參數(shù)2,3決定了時(shí)鐘源的選擇
//參數(shù)3: clock
/*
PWM Channel 0,1,4,5
PCLKAB[0,1,4,5] PCLK[0,1,4,5] Clock Source Selection
0 0 Clock A
0 1 Clock SA
1 0 Clock B
1 1 Clock SB
PWM Channel 2,3,6,7
PCLKAB[2,3,6,7] PCLK[2,3,6,7] Clock Source Selection
0 0 Clock B
0 1 Clock SB
1 0 Clock A
1 1 Clock SA
*/
//參數(shù)4:polarity PWM極性選擇
// 0 開始為低電平,周期計(jì)數(shù)開始為高電平
// 1 開始為高電平,周期計(jì)數(shù)開始為低電平
//參數(shù)5:align PWM對(duì)齊方式選擇
// 0 輸出左對(duì)齊
// 1 輸出中心對(duì)齊
//返回值:無(wú)
//**********************************************
void PWMsinglePortInitial(byte channel, byte clkab,byte clock, byte polarity,byte align)
{
if(channel》7) channel=7;
//禁止該通道
PWMDisable(channel);
// PWM 時(shí)鐘A/B 選擇
if(clkab==0) PWMCLKAB&=~(1《《channel);
else PWMCLKAB|=(1《《channel);
// PWM 時(shí)鐘選擇寄存器設(shè)置
if(clock==0) PWMCLK&=~(1《《channel);
else PWMCLK|=(1《《channel);
//PWM 極性選擇設(shè)置
if(polarity==0) PWMPOL&=~(1《《channel) ;
else PWMPOL|=(1《《channel);
//PWM 對(duì)齊方式設(shè)置
if(align==0) PWMCAE&=~(1《《channel);
else PWMCAE|=(1《《channel);
}
//**********************************************************
//函數(shù)名:PWMGeneralInitial
//函數(shù)功能:對(duì)預(yù)分頻時(shí)鐘,分頻時(shí)鐘A,分頻時(shí)鐘B和控制寄存器的配置
//函數(shù)參數(shù):4個(gè)byte類型
//參數(shù)1 prclk
/*
Clock A or Clock B Prescaler Selects
PCKA/B2 PCKA/B1 PCKA/B0 Value of Clock A/B
0 0 0 Bus clock
0 0 1 Bus clock / 2
0 1 0 Bus clock / 4
0 1 1 Bus clock / 8
1 0 0 Bus clock / 16
1 0 1 Bus clock / 32
1 1 0 Bus clock / 64
1 1 1 Bus clock / 128
*/
//參數(shù)2: scla
// Clock SA = Clock A / (2 * PWMSCLA)
//參數(shù)3: sclb
// Clock SB = Clock B / (2 * PWMSCLB)
//參數(shù)4: ctl
/*
control[CON67,CON45,CON23,CON01,PSWAI,PFRZ]
PWM級(jí)聯(lián)控制寄存器 CON67,CON45,CON23,CON01
0 單獨(dú)一個(gè)通道
1 兩個(gè)通道級(jí)聯(lián)
PSWAI 0 等待模式禁止時(shí)鐘輸入
1 等待模式允許時(shí)鐘輸入
PFRZ 0 凍結(jié)模式允許PWM時(shí)鐘輸入
1 凍結(jié)模式禁止PWM時(shí)鐘輸入
//返回值:無(wú)
*/
//**************************************************************
void PWMGeneralInitial(byte prclk,byte scla,byte sclb,byte ctl)
{
//禁止所有的PWM通道
PWME=0x00;
//設(shè)置預(yù)分頻參數(shù)
PWMPRCLK=prclk;
//設(shè)置A分頻參數(shù)
PWMSCLA=scla;
//設(shè)置B分頻參數(shù)
PWMSCLB=sclb;
//級(jí)聯(lián)配置
PWMCTL=ctl;
}
//***********************************************************
//函數(shù)名稱:PWMConcatenateSetting
//函數(shù)功能:PWM級(jí)聯(lián)輸出配置
//函數(shù)參數(shù):1個(gè)byte類型,2個(gè)word類型
//參數(shù)1: channel代表了當(dāng)前配置的PWM通道
//參數(shù)2: period 周期配置參數(shù)
/*
Left aligned output (CAEx = 0) PWMx Period = Channel Clock Period * PWMPERx
Center Aligned Output (CAEx = 1) PWMx Period = Channel Clock Period * (2 * PWMPERx)
*/
//參數(shù)3: duty 占空比配置參數(shù)
/*
Polarity = 0 (PPOL x =0) Duty Cycle = [(PWMPERx-PWMDTYx)/PWMPERx] * 100%
Polarity = 1 (PPOLx = 1) Duty Cycle = [PWMDTYx / PWMPERx] * 100%
*/
//返回值:無(wú)
//**************************************************************
void PWMConcatenateSetting(byte channel,word period,word duty)
{
if(channel》7) channel=7;
switch(channel)
{
case 0:
case 1:PWMDisable(0); //禁止通道0
PWMDisable(1); //禁止通道1
PWMPER01=period; //設(shè)置周期寄存器
PWMDTY01=duty; //設(shè)置占空比寄存器
PWMEnable(0); //使能通道0;
PWMEnable(1); //使能通道1;
break;
case 2:
case 3:PWMDisable(2); //禁止通道2
PWMDisable(3); //禁止通道3
PWMPER23=period; //設(shè)置周期寄存器
PWMDTY23=duty; //設(shè)置占空比寄存器
PWMEnable(2); //使能通道2;
PWMEnable(3); //使能通道3;
break;
case 4:
case 5:PWMDisable(4); //禁止通道4
PWMDisable(5); //禁止通道5
PWMPER45=period; //設(shè)置周期寄存器
PWMDTY45=duty; //設(shè)置占空比寄存器
PWMEnable(4); //使能通道4;
PWMEnable(5); //使能通道5;
break;
case 6:
case 7:PWMDisable(6); //禁止通道6
PWMDisable(7); //禁止通道7
PWMPER67=period; //設(shè)置周期寄存器
PWMDTY67=duty; //設(shè)置占空比寄存器
PWMEnable(6); //使能通道6;
PWMEnable(7); //使能通道7;
break;
default:break;
}
}
定時(shí)器應(yīng)用程序
#include 《hidef.h》 /* common defines and macros */
#include “derivative.h” /* derivative-specific definitions */
// 函數(shù)聲明
void OutputCompare_Init(void);;
void Service_WD(void);
void SetBusClock_24MHz(void);
// 全局變量
uint Timer7_Cnt=0;
void main(void) {
/* put your own code here */
SetBusClock_24MHz();
OutputCompare_Init();
EnableInterrupts;
for(;;) {
_FEED_COP(); /* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}
void OutputCompare_Init(void)
{
TSCR1_TEN = 0; /* Disable Timer module before adjusting registers. */
TIOS_IOS7 = 1; /* Set Channel 0 as output compare. */
TCTL1_OM7 = 0; /* Set channel 0 to toggle when a Timer match occurs. */
TCTL1_OL7 = 1; /* Set channel 0 to toggle when a Timer match occurs. */
TC7 = 0x4926; /* Set a value for channel 0 timer compare. */
TIE_C7I = 1; /* Enable channel 0 interrupt, handled by function TIM0ISR. */
TSCR1_TSWAI = 1; /* Disables the timer module while in wait mode. */
TSCR1_TSFRZ = 1; /* Disables the timer counter while in freeze mode. */
TSCR2_PR = 0x7; /* Set prescaler to divide by 128 */
TSCR2_TCRE = 1;
TSCR1_TEN = 1; /* Timer Enable. */
//中斷周期:0x4926*128/24MHz = 100ms
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt VectorNumber_Vtimch7 TIM7_ISR(void)
{
Timer7_Cnt++;
TFLG1 = TFLG1_C7F_MASK; /* Clear channel 0 flag. */
}
#pragma CODE_SEG DEFAULT
// 看門狗
void Service_WD(void)
{
CPMUARMCOP = 0x55;
CPMUARMCOP = 0xAA;
}
void SetBusClock_24MHz(void)
{
CPMUOSC_OSCE = 1; /* enable ext osc */
/*
Initialise the system clock from a 16 MHz Crystal,
24 MHz Bus CLK (48 MHz VCO, 48 MHz PLL)
*/
CPMUSYNR = 0x00 | 0x05; /* VCOFRQ[7:6], SYNDIV[5:0] */
CPMUREFDIV = 0x20 | 0x03; /* REFFRQ[7:6], REFDIV[3:0] */
CPMUPOSTDIV = 0x00; /* POSTDIV = 0 FPLL = FVCO */
while(!CPMUFLG_LOCK); /* wait for VCO to stabilize*/
Service_WD();
CPMUCLKS_PLLSEL = 1; /* Switch clk to use PLL */
}
SCI應(yīng)用程序
#include 《hidef.h》 /* common defines and macros */
#include “derivative.h” /* derivative-specific definitions */
// 函數(shù)聲明
void SCI0_Init(void);
void SCI0_BR(unsigned long br);
void SCI0_SendByte(char ch);
void Service_WD(void);
void SetBusClock_24MHz(void);
// 全局變量
char SCI_Flag = 0;
char SCI_Rev = 0;
void main(void) {
/* put your own code here */
SetBusClock_24MHz();
SCI0_BR(38400);
SCI0_Init();
EnableInterrupts;
SCI0_SendByte(0x01);
SCI0_SendByte(0x02);
SCI0_SendByte(0x03);
for(;;) {
_FEED_COP(); /* feeds the dog */
if(SCI_Flag==1) {
SCI_Flag = 0;
SCI0_SendByte(SCI_Rev);
}
} /* loop forever */
/* please make sure that you never leave main */
}
void Service_WD(void)
{
CPMUARMCOP = 0x55;
CPMUARMCOP = 0xAA;
}
void SetBusClock_24MHz(void)
{
CPMUOSC_OSCE = 1; /* enable ext osc */
/*
Initialise the system clock from a 16 MHz Crystal,
24 MHz Bus CLK (48 MHz VCO, 48 MHz PLL)
*/
CPMUSYNR = 0x00 | 0x05; /* VCOFRQ[7:6], SYNDIV[5:0] */
CPMUREFDIV = 0x20 | 0x03; /* REFFRQ[7:6], REFDIV[3:0] */
CPMUPOSTDIV = 0x00; /* POSTDIV = 0 FPLL = FVCO */
while(!CPMUFLG_LOCK); /* wait for VCO to stabilize*/
Service_WD();
CPMUCLKS_PLLSEL = 1; /* Switch clk to use PLL */
}
//串口初始化
void SCI0_Init(void)
{
SCI0CR1 = 0x00; /* 8 Data Bits, 1 Start Bit, 1 Stop Bit, No Parity */
SCI0CR2 = 0x2C; /* 使能接收中斷;使能 Tx,Rx */
/* SCIASR1, SCIACR1, SCIACR2, SCISR1, SCISR2, SCIDRH & SCIDRL left at default values */
}
//串口波特率設(shè)置
void SCI0_BR(unsigned long br)
{
uint brPrescaler;
brPrescaler = (uint)(24000000 / (16 * br));
/* Set the Baud Rate */
SCI0BDH = (uchar)((brPrescaler》》8));
SCI0BDL = (uchar)(brPrescaler);
}
//串口發(fā)送字節(jié)
void SCI0_SendByte(char ch)
{
/* check SCI transmit data register is empty */
while(SCI0SR1_TDRE == 0);
SCI0DRL = ch;
}
//串口中斷
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt VectorNumber_Vsci0 SCI0_ISR(void)
{
SCI0CR2_RIE=0;
while(SCI0SR1_RDRF == 0);
SCI_Rev = SCI0DRL;
SCI_Flag = 1;
SCI0CR2_RIE = 1;
}
#pragma CODE_SEG DEFAULT
ADC應(yīng)用程序
#include 《hidef.h》 /* common defines and macros */
#include “derivative.h” /* derivative-specific definitions */
// 函數(shù)聲明
void ADC_Init(void);
uint ADC_GetValue(byte ch);
void Service_WD(void);
void SetBusClock_24MHz(void);
void Delay(void);
// 全局變量
uint AD_Result;
uint AD_Result2;
void main(void) {
/* put your own code here */
SetBusClock_24MHz();
ADC_Init();
EnableInterrupts;
for(;;) {
_FEED_COP(); /* feeds the dog */
AD_Result = ADC_GetValue(7);
AD_Result2 = ADC_GetValue(0);
} /* loop forever */
/* please make sure that you never leave main */
}
// AD初始化
void ADC_Init(void)
{
ATDCTL1 = 0x3F; /* 10-Bit resolution ,discharge before sampling. */
ATDCTL3 = 0x88; /* Right Justified Data, Single conversion sequence */
ATDCTL4 = 0xE1; /* 6 MHz, Notice: 12MHz Max ATD Clock, Fatdlk = FBUS/(2*(PRS+1)) */
/* 26 ATD Clock cycles sample time */
}
// ADC通道采集
uint ADC_GetValue(byte ch)
{
ATDCTL5 = 0x0F & ch; /* Start Continuous Conversions on ch */
while (!ATDSTAT0_SCF); /* wait for conversion sequence to complete */
return ATDDR0;
}
// 看門狗
void Service_WD(void)
{
CPMUARMCOP = 0x55;
CPMUARMCOP = 0xAA;
}
void SetBusClock_24MHz(void)
{
CPMUOSC_OSCE = 1; /* enable ext osc */
/*
Initialise the system clock from a 16 MHz Crystal,
24 MHz Bus CLK (48 MHz VCO, 48 MHz PLL)
*/
CPMUSYNR = 0x00 | 0x05; /* VCOFRQ[7:6], SYNDIV[5:0] */
CPMUREFDIV = 0x20 | 0x03; /* REFFRQ[7:6], REFDIV[3:0] */
CPMUPOSTDIV = 0x00; /* POSTDIV = 0 FPLL = FVCO */
while(!CPMUFLG_LOCK); /* wait for VCO to stabilize*/
Service_WD();
CPMUCLKS_PLLSEL = 1; /* Switch clk to use PLL */
}
void Delay(void)
{
uint dummy_ctr;
for(dummy_ctr=0; dummy_ctr《0x007f;dummy_ctr++)
{
;
}
}
飛思卡爾XS128和G128兩種單片機(jī)的主要區(qū)別
一 端口
XS128有A, B, E, K, T, S, M, P, H, J, 和 AD口。 G128有A, B, C, D, E, T, S, M, P, J 和 AD口。 對(duì)于引腳數(shù)較少的封裝會(huì)缺少某些端口。 當(dāng)端口用作普通IO口時(shí)的相關(guān)寄存器命名規(guī)律相同,一般可以直接移植。 一些引腳的外部中斷功能的寄存器配置也一樣。但中斷號(hào)不同。 一些引腳的個(gè)別功能可能會(huì)不同,但一般很少用。 當(dāng)端口用作AD,PWM,SCI,SPI,CAN等功能時(shí)XS128和G128的引腳用法類似。
二 中斷
在CodeWarrior里使用中斷向量號(hào),可用如下方法查看到。 點(diǎn)File,選Find and Open File,輸入mc9s12g128.h,點(diǎn)OK,打開一個(gè).h文件。往下翻就是中斷向量表了。這個(gè)XS128和G128可能是不同的,替換一下自己程序中的向量號(hào)就行了。不要亂改這個(gè).h文件。
三 時(shí)鐘配置
這個(gè)很重要,雖然兩款單片機(jī)的相關(guān)寄存器名稱不同。但計(jì)算公式是相同的,見程序注釋: 設(shè)fosc=16MHz,例如:
2XS128官方規(guī)定的上限頻率是40M,G128的是25M。把XS128超頻到64M問(wèn)題不大,但把G128超頻到64M使用可能會(huì)影響系統(tǒng)穩(wěn)定甚至影響使用壽命。 當(dāng)G128超到64M時(shí),可能產(chǎn)生開機(jī)后無(wú)法成功運(yùn)行PLL而導(dǎo)致單片機(jī)不能工作的情況。強(qiáng)烈建議不要超頻過(guò)多。 文章的最后附上與時(shí)鐘配置相關(guān)的主要寄存器的中文翻譯。
四 模數(shù)轉(zhuǎn)換器
只需注意XS128有8位,10位,12位三種模式,G128只有8位和10位兩種模式。這個(gè)在ATDCTL1寄存器中設(shè)置。 其它設(shè)置基本相同,直接移植問(wèn)題不大。寄存器名可能有細(xì)微差別,例如XS128中是ATD0DR0,而G128是ATDDR0。
五 定時(shí)
XS128中的PIT,G128沒有。G128中有API,用Timer也行。 六 PWM,SCI,SPI,CAN等 基本相同,直接移植問(wèn)題不大。
七 Timer模塊 基本相同。
?
評(píng)論
查看更多