電子發燒友網:隨著駕駛員對車內舒適度和便利性的要求在提高,汽車車身電子產品在保持具有競爭力價格的同時,還需要繼續提供性能更高的半導體。飛思卡爾半導體目前開始擴大現已普及的16位S12微控制器(MCU)系列,以優化大量對成本敏感的汽車車身電子應用。先進的S12G器件設計針對應用需求,提供靈活的內存、封裝和成本選項。MC9S12G系列是一個專注于低功耗、高性能、低引腳數量的高效汽車級16位微控制器產品。這個系列是橋連8位高端微機和16位高性能微機,像MC9S12XS系列。本文將詳細介紹關于飛思卡爾MC9S12系列的芯片簡介、MC9S12單片機最小系統硬件設計、典型程序應用、飛思卡爾XS128和G128兩種單片機的主要區別等進行闡述。
飛思卡爾MC9S12G系列單片機中文簡介
1.1介紹
MC9S12G系列是一個專注于低功耗、高性能、低引腳數量的高效汽車級16位微控制器產品。這個系列是橋連8位高端微機和16位高性能微機,像MC9S12XS系列。MC9S12G系列是為了滿足通用汽車CAN或LIN/J2602通信應用。這些應用的典型例子包括body controllers, occupant detection, doormodules, seat controllers, RKE receivers, smart actuators, lighting modules, and smart junction boxes.
MC9S12G系列使用了許多MC9S12XS系列和MC9S12P系列里面的相同特性,包括在閃存(flash memory)上的糾錯指令(ECC),一個快速A/D轉換器(ADC)和一個為了改善電磁兼容性(EMC)性能的頻率調制相位鎖存循環(IPLL)。
MC9S12G系列是高效的對較低的程序存儲器至16K。為了簡化顧客使用它,特制了一個4字節可擦除扇區的EEPROM。
MC9S12G系列傳送所有16位單片機的優勢和效率,定位于低成本,低功耗,EMC,現行代碼尺寸效率優勢被現存8位和16位單片機系列的使用者所分享。像MC9S12XS系列,MC9S12G系列運行16位位寬的訪問對所有的周期和存儲器狀態都不用等待。
MC9S12G系列可得到的封裝有100-pin LQFP, 64-pin LQFP, 48-pinLQFP/QFN, 32-pin LQFP and 20-pin TSSOP,特別是對較少引腳的封裝發揮出最大的功能。此外,在每個模塊中可得到的I/O口,進一步的可用于中斷的I/O口允許從停止或等待模式中喚醒。
?
1.2特點
這部分說明了MC9S12G系列的關鍵特性。
1.2.1MC9S12G系列比較
表1-1提供了MC9S12G系列不同型號特點的概要。這個微機系統提供了一個明確的功能范圍信息。
飛思卡爾MC9S12G系列芯片引腳圖
飛思卡爾MC9S12G系列芯片內部資源模塊框圖
表1-1 MC9S12G系列概述
并不是所有的外圍設備都能夠應用于所有封裝類型
表1-2顯示出了每個封裝外圍設備或外圍信道的最大值。并不是所有的外圍設備都能夠同時使用。可使用的外圍設備的最大值還受到表1-1中所選芯片的限制。
表1-2 每個封裝可使用外圍設備的最大值
1.2.2 芯片水平特點
在這個系列里面可應用的模塊包括以下特點:
S12內核
高達240KB的片內在線可編程FLASH存儲器防糾錯閃存
高達4KB防糾錯EEPROM
高達11KB片內SRAM
擁有內部濾波器的鎖相環回路(IPLL)頻率乘法器
4-16MHz振幅控制穿透振蕩器
1MHz內部RC振蕩器
定時單元(TIM)支持達到8通道(提供16位輸入俘獲,輸出比較,計數,脈沖存儲器功能)
多達8*8通道脈寬調節(PWM)模塊
多達16通道,10位或12位分辨率逐次近似計算法模數轉換器(ADC)
多達3個串行外圍接口模塊(SPI)
多達3個串行通信接口(SCI)模塊(支持LIN通信)
多達一個多級控制局域網(MSCAN)模塊(支持CAN2.0 A/B 協議)
在線片內穩壓器(VREG)用于控制內部供給和內部電壓
自動周期性中斷(API)
固定電壓基準精度參考ADC轉換器
為汽車電子定造
飛思卡爾S12G系列是需要CAN(控制器區域網絡)或LIN(本地互連網絡)/SAE J2602通訊的汽車應用的理想之選,這些應用包括車身控制器、車門模塊、乘客檢測、空調、座椅控制器和照明模塊。這款16位S12G系列基于業界公認的S12架構,提供更復雜的應用設計所需的處理功能,保留了代碼的有效性,同時還利用了廣泛的S12生態系統,而這則有助于減少內存占用和開發成本。
MC9S12G128/96和MC9S12GN32/16是MC9S12G系列在市場上最先推出的四款主要產品。
汽車車身電子市場正在開發各種新應用,該市場對不同類型的微控制器應用具有特定的要求,需要不同的功能集。飛思卡爾這款先進的16位產品系列,能夠為客戶帶來可靠的16位MCU產品的高性能,并且以8位MCU產品的價格提供更多的功能,進而實現更大的價值。
成熟的工藝技術
可擴展S12G系列填補了高端8位MCU和高性能16位MCU之間的空白。它采用成熟、高性價比的0.18微米工藝,提供能在大量低端車身應用范圍工作的選項。汽車設計人員能夠在內存器大小的封裝內向上、向下遷移,并且與整個S12G系列完全兼容。此外,該16位產品系列包括板載EEPROM等增值功能,幫助客戶設計出更復雜、但仍然對用戶友好的應用。
MC9S12G系列是經過優化的汽車級16位微控制器產品線,具有低成本、高性能、引腳數量少的顯著特點。MC9S12G系列適合需要CAN或LIN/SAE J2602通信的一般汽車應用。
MC9S12G系列具有16位MCU的所有優點和性能,同時保留了飛思卡爾現有8位和16位MCU系列用戶所享有的低成本、低功耗、電磁兼容性(EMC)以及代碼效率等優勢。
關于MC9S12G系列16位MCU的特性:
?總線頻率為25MHz的S12 CPU內核提供業界公認的S12架構和處理能力,以解決更復雜的傳統8位應用設計版本;
?高達240KB的片上閃存(包括糾錯碼(ECC))可用來存儲代碼,幫助減少板上閃存/ROM;
?高達4KB的EEPROM(包括ECC)提供的用戶界面比以前幾代產品的數據快閃更簡單;
?采用多個可擴展CAN模塊(支持CAN協議2.0A/B),專為支持CAN通信端口復雜的系統需求而設計;
?三個串行通信接口模塊用于支持LIN通信,三個串行外設接口(SPI)模塊可以提供更好的靈活性、更多的選項和優勢,同時需要增加SCI/LIN或SPI通信端口;
?在外設和存儲器中提供16位存取,無等待狀態;
?閃存從16K到240K不等,封裝從20TSSOP到100LQFP不等,提供靈活的嵌入式設計和最大的功能;
?每個模塊不但提供I/O端口,而且還在I/O端口提供中斷功能,允許從停止或等待模式中喚醒;
?高達11KB片上SRAM,提供更多存儲單元;
?精密固定電壓參考用于ADC轉換;
? 1MHz內部振蕩器;
?片上穩壓器調節輸入電源和所有內部電壓。
復位及時鐘—復位
上電復位
單片機自動檢測VDD端的正跳變,啟動自動工作。
外部復位
通過RESET引腳加一低電壓,拉低超過一定時間
后可實現復位。
看門狗復位
幫助系統在軟件跑飛后自動復位。
時鐘監視器復位
利用內部的RC電路來保證時鐘頻率滿足要求。
振蕩器和時鐘電路
EXTAL是外部時鐘輸入或石英振蕩放大器的輸入
XTAL是石英振蕩放大器的輸出
注:DG128可用串聯振蕩電路和并聯振蕩電路兩種連接方式。
9S12X系列單片機只可用并聯振蕩電路。
?
時鐘初始化寄存器-共5個
?
?。?)鎖相環控制寄存器(PLLCTL)
(2)時鐘合成寄存器(SYNR)-低6位有效,有效值0~63。
?。?)時鐘分頻寄存器(REFDV)-低4位有效,有效值0~15。
由鎖相環來產生時鐘頻率的公式:
例如:選用16MHz的外部晶振,若將SYNR設為
2,REFDV設為1,通過公式計算可得
PLLCLK=48MHz。從而得到系統的總線頻
率為24MHz。
PLL例子
CLKSEL=0x00; //禁止PLL
PLLCTL=0xe1; //PLL電路允許
SYNR=2;REFDV=1; //設置倍頻參數
PLLCTL=0x60; //時鐘監控禁止
while(0==(CRGFLG&0x08));//等待穩定
CLKSEL=0x80; //選擇PLL作為時鐘
//若晶振為16M,則PLLCLK=2*16*3/2=48MHz,則總線頻率是24MHz
RTI程序舉例
RTICTL = 0x7e;//4M/15*2^16 = 4Hz
CRGINT = 0x80;
// 中斷使能
得到大約每秒4次的中斷
MC9S12單片機最小系統硬件設計
——以MC9S12DG128為例
時鐘電路給單片機提供一個外接的16MHz的石英晶振
串口的RS-232驅動電路可實現TTL電平到RS-232電平的轉換
BDM口讓用戶可以通過BDM調試工具向單片機下載和調試程序
供電電路主要是由單片機提供+5V電源和電源濾波
復位電路是通過一個復位按鍵給單片機一個復位信號,調試過程中很有用。
單片機MC9S12G128應用程序(PWM_Timer_ADC……)
???????
?
PWM應用程序
/*
程序實現功能:PP1口輸出PWM方波
程序說明:通過改變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 */
//總線時鐘頻率設置:24M
SetBusClock_24MHZ();
//對預分頻時鐘,分頻時鐘A,分頻時鐘B和控制寄存器的配置
//0分頻 01級聯
PWMGeneralInitial(0,24,0,0x10);
//PWM端口寄存器的配置
// 1通道 SA時鐘 起始高電平 左對齊
PWMsinglePortInitial(1,0,1,1,0);
//PWM級聯輸出配置
//50HZ 占空比12.5%
PWMConcatenateSetting(1,10000,250);
//EnableInterrupts;
for(;;) {
_FEED_COP(); /* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}
//*********************************************
//函數名:PWMEnable
//函數功能:PWM單個端口使能
//函數參數:一個 byte 類型channel 代表PWM通道號
// 返回值:無
//********************************************
void PWMEnable(byte channel)
{
if(channel》7) channel=7;
PWME|=(1《《channel); //選擇使能位
}
//**********************************************
//函數名稱:PWMDisable
//函數功能:PWM單個端口禁止
//函數參數:一個byte類型 channel 代表PWM通道號
//返回值:無
//***********************************************
void PWMDisable(byte channel)
{
if(channel》7) channel=7;
PWME&=~(1《《channel); //選擇禁止位
}
//函數功能:啟動看門狗
void Service_WD(void)
{
CPMUARMCOP=0x55;
CPMUARMCOP=0xAA;
}
//函數功能:總線時鐘設置
void SetBusClock_24MHZ(void)
{
CPMUOSC_OSCE=1; //enable osc
/*
時鐘倍頻: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穩定
Service_WD(); //看門狗
CPMUCLKS_PLLSEL=1;
}
//*********************************************
//函數名稱: PWMSinglePortSetting
//函數功能:實現PWM周期寄存器和占空比寄存器通道的單獨輸出
//函數參數:3個 byte類型
//參數1: channel代表了當前配置的PWM通道
//參數2: period 周期配置參數
/*
Left aligned output (CAEx = 0) PWMx Period = Channel Clock Period * PWMPERx
Center Aligned Output (CAEx = 1) PWMx Period = Channel Clock Period * (2 * PWMPERx)
*/
//參數3: duty 占空比配置參數
/*
Polarity = 0 (PPOL x =0) Duty Cycle = [(PWMPERx-PWMDTYx)/PWMPERx] * 100%
Polarity = 1 (PPOLx = 1) Duty Cycle = [PWMDTYx / PWMPERx] * 100%
*/
//返回值:無
//**********************************************
void PWMSinglePortSetting(byte channel ,byte period ,byte duty)
{
if(channel》7) channel=7;
PWMDisable(channel); //禁止該通道
switch(channel)
{
case 0:
PWMPER0=period; //設置周期寄存器
PWMDTY0=duty; //設置占空比寄存器
break;
case 1:
PWMPER1=period; //設置周期寄存器
PWMDTY1=duty; //設置占空比寄存器
case 2:
PWMPER2=period; //設置周期寄存器
PWMDTY2=duty; //設置占空比寄存器
break;
case 3:
PWMPER3=period; //設置周期寄存器
PWMDTY3=duty; //設置占空比寄存器
break;
case 4:
PWMPER4=period; //設置周期寄存器
PWMDTY4=duty; //設置占空比寄存器
break;
case 5:
PWMPER5=period; //設置周期寄存器
PWMDTY5=duty; //設置占空比寄存器
break;
case 6:
PWMPER6=period; //設置周期寄存器
PWMDTY6=duty; //設置占空比寄存器
break;
case 7:
PWMPER7=period; //設置周期寄存器
PWMDTY7=duty; //設置占空比寄存器
break;
default:break;
}
PWMEnable(channel);
}
//*********************************************
//函數名:PWMSinglePortInitial
//函數功能:PWM端口寄存器的配置
//函數參數:5個byte類型
//參數1:channel 代表了當前配置的PWM通道
//參數2:clkab 參數2,3決定了時鐘源的選擇
//參數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
*/
//參數4:polarity PWM極性選擇
// 0 開始為低電平,周期計數開始為高電平
// 1 開始為高電平,周期計數開始為低電平
//參數5:align PWM對齊方式選擇
// 0 輸出左對齊
// 1 輸出中心對齊
//返回值:無
//**********************************************
void PWMsinglePortInitial(byte channel, byte clkab,byte clock, byte polarity,byte align)
{
if(channel》7) channel=7;
//禁止該通道
PWMDisable(channel);
// PWM 時鐘A/B 選擇
if(clkab==0) PWMCLKAB&=~(1《《channel);
else PWMCLKAB|=(1《《channel);
// PWM 時鐘選擇寄存器設置
if(clock==0) PWMCLK&=~(1《《channel);
else PWMCLK|=(1《《channel);
//PWM 極性選擇設置
if(polarity==0) PWMPOL&=~(1《《channel) ;
else PWMPOL|=(1《《channel);
//PWM 對齊方式設置
if(align==0) PWMCAE&=~(1《《channel);
else PWMCAE|=(1《《channel);
}
//**********************************************************
//函數名:PWMGeneralInitial
//函數功能:對預分頻時鐘,分頻時鐘A,分頻時鐘B和控制寄存器的配置
//函數參數:4個byte類型
//參數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
*/
//參數2: scla
// Clock SA = Clock A / (2 * PWMSCLA)
//參數3: sclb
// Clock SB = Clock B / (2 * PWMSCLB)
//參數4: ctl
/*
control[CON67,CON45,CON23,CON01,PSWAI,PFRZ]
PWM級聯控制寄存器 CON67,CON45,CON23,CON01
0 單獨一個通道
1 兩個通道級聯
PSWAI 0 等待模式禁止時鐘輸入
1 等待模式允許時鐘輸入
PFRZ 0 凍結模式允許PWM時鐘輸入
1 凍結模式禁止PWM時鐘輸入
//返回值:無
*/
//**************************************************************
void PWMGeneralInitial(byte prclk,byte scla,byte sclb,byte ctl)
{
//禁止所有的PWM通道
PWME=0x00;
//設置預分頻參數
PWMPRCLK=prclk;
//設置A分頻參數
PWMSCLA=scla;
//設置B分頻參數
PWMSCLB=sclb;
//級聯配置
PWMCTL=ctl;
}
//***********************************************************
//函數名稱:PWMConcatenateSetting
//函數功能:PWM級聯輸出配置
//函數參數:1個byte類型,2個word類型
//參數1: channel代表了當前配置的PWM通道
//參數2: period 周期配置參數
/*
Left aligned output (CAEx = 0) PWMx Period = Channel Clock Period * PWMPERx
Center Aligned Output (CAEx = 1) PWMx Period = Channel Clock Period * (2 * PWMPERx)
*/
//參數3: duty 占空比配置參數
/*
Polarity = 0 (PPOL x =0) Duty Cycle = [(PWMPERx-PWMDTYx)/PWMPERx] * 100%
Polarity = 1 (PPOLx = 1) Duty Cycle = [PWMDTYx / PWMPERx] * 100%
*/
//返回值:無
//**************************************************************
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; //設置周期寄存器
PWMDTY01=duty; //設置占空比寄存器
PWMEnable(0); //使能通道0;
PWMEnable(1); //使能通道1;
break;
case 2:
case 3:PWMDisable(2); //禁止通道2
PWMDisable(3); //禁止通道3
PWMPER23=period; //設置周期寄存器
PWMDTY23=duty; //設置占空比寄存器
PWMEnable(2); //使能通道2;
PWMEnable(3); //使能通道3;
break;
case 4:
case 5:PWMDisable(4); //禁止通道4
PWMDisable(5); //禁止通道5
PWMPER45=period; //設置周期寄存器
PWMDTY45=duty; //設置占空比寄存器
PWMEnable(4); //使能通道4;
PWMEnable(5); //使能通道5;
break;
case 6:
case 7:PWMDisable(6); //禁止通道6
PWMDisable(7); //禁止通道7
PWMPER67=period; //設置周期寄存器
PWMDTY67=duty; //設置占空比寄存器
PWMEnable(6); //使能通道6;
PWMEnable(7); //使能通道7;
break;
default:break;
}
}
定時器應用程序
#include 《hidef.h》 /* common defines and macros */
#include “derivative.h” /* derivative-specific definitions */
// 函數聲明
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應用程序
#include 《hidef.h》 /* common defines and macros */
#include “derivative.h” /* derivative-specific definitions */
// 函數聲明
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 */
}
//串口波特率設置
void SCI0_BR(unsigned long br)
{
uint brPrescaler;
brPrescaler = (uint)(24000000 / (16 * br));
/* Set the Baud Rate */
SCI0BDH = (uchar)((brPrescaler》》8));
SCI0BDL = (uchar)(brPrescaler);
}
//串口發送字節
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應用程序
#include 《hidef.h》 /* common defines and macros */
#include “derivative.h” /* derivative-specific definitions */
// 函數聲明
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兩種單片機的主要區別
一 端口
XS128有A, B, E, K, T, S, M, P, H, J, 和 AD口。 G128有A, B, C, D, E, T, S, M, P, J 和 AD口。 對于引腳數較少的封裝會缺少某些端口。 當端口用作普通IO口時的相關寄存器命名規律相同,一般可以直接移植。 一些引腳的外部中斷功能的寄存器配置也一樣。但中斷號不同。 一些引腳的個別功能可能會不同,但一般很少用。 當端口用作AD,PWM,SCI,SPI,CAN等功能時XS128和G128的引腳用法類似。
二 中斷
在CodeWarrior里使用中斷向量號,可用如下方法查看到。 點File,選Find and Open File,輸入mc9s12g128.h,點OK,打開一個.h文件。往下翻就是中斷向量表了。這個XS128和G128可能是不同的,替換一下自己程序中的向量號就行了。不要亂改這個.h文件。
三 時鐘配置
這個很重要,雖然兩款單片機的相關寄存器名稱不同。但計算公式是相同的,見程序注釋: 設fosc=16MHz,例如:
2XS128官方規定的上限頻率是40M,G128的是25M。把XS128超頻到64M問題不大,但把G128超頻到64M使用可能會影響系統穩定甚至影響使用壽命。 當G128超到64M時,可能產生開機后無法成功運行PLL而導致單片機不能工作的情況。強烈建議不要超頻過多。 文章的最后附上與時鐘配置相關的主要寄存器的中文翻譯。
四 模數轉換器
只需注意XS128有8位,10位,12位三種模式,G128只有8位和10位兩種模式。這個在ATDCTL1寄存器中設置。 其它設置基本相同,直接移植問題不大。寄存器名可能有細微差別,例如XS128中是ATD0DR0,而G128是ATDDR0。
五 定時
XS128中的PIT,G128沒有。G128中有API,用Timer也行。 六 PWM,SCI,SPI,CAN等 基本相同,直接移植問題不大。
七 Timer模塊 基本相同。
?
評論
查看更多