描述

电子发烧友网:随着驾驶员对车内舒适度和便利性的要求在提高,汽车车身电子产品在保持具有竞争力价格的同时,还需要继续提供性能更高的半导体。飞思卡尔半导体目前开始扩大现已普及的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)

多达两个8位数模转换器(DAC)

多达一个5V模拟比较器(ACMP)

多达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个

(1)锁相环控制寄存器(PLLCTL)

(2)时钟合成寄存器(SYNR)-低6位有效,有效值0~63。

(3)时钟分频寄存器(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模块 基本相同。

打开APP精彩内容

点击阅读全文

飞思卡尔单片机c语言编程详解,主流16位单片机学习详解:飞思卡尔MC9S12G系列...相关推荐

  1. 单片机c语言编程30倒计时,急求51单片机倒计时三十秒程序

    急求51单片机倒计时三十秒程序 关注:117  答案:2  手机版 解决时间 2021-01-31 06:56 提问者青春统帅 2021-01-30 16:36 第二位同志请补充一下注释 谢谢 最佳答 ...

  2. 单片机c语言编程教学大纲,《单片机C语言编程》教学大纲

    <单片机C语言编程>教学大纲 课程代码:000002336 课程英文名称:Microcontroller C Programming Language 课程总学时:24 讲课:16 实验: ...

  3. PIC单片机与PIC单片机C语言编程简介

    对于计算机学院与电子学院相关的同学来说,单片机一定不是一个陌生的概念.在大学的学习生涯中,经常用于教学的是MCS-51系列单片机.其实,除了MCS-51单片机外,还有一类单片机--PIC单片机. PI ...

  4. 单片机c语言开发实验心得,在单片机C语言编程中的心得体会

    在单片机C语言编程中的心得体会在单片机C语言编程中的心得体会 在单片机C语言编程中的心得体会 作者:彭树林 在单片机C语言编程中使用恰当的`优化手段,可以写出简洁高效的代码.以下是笔者在C51编程过程 ...

  5. 两位数码管秒表c语言,单片机C语言编程实现双数码管可调秒表

    单片机C语言编程实现双数码管可调秒表 解:只要满足题目要求,方法越简单越好.由于单片机I/O资源足够,所以双数码管可接成静态显示方式,两个共阴数码管分别接在P1(秒十位)和P2(秒个位)口,它们的共阴 ...

  6. 51单片机c语言工作手册,51单片机C语言编程手册

    51单片机C语言编程手册 1 第一章 介绍 这是一本关于Intel 80C51 以及广大的51 系列单片机的书这本书介绍给读者一些 新的技术使你的8051 工程和开发过程变得简单请注意这本书的目的可不 ...

  7. 单片机c语言编程入门下載,系列单片机C语言编程入门.pdf

    系列单片机C语言编程入门.pdf 本文由c h e n j u n j u n j u n 3贡献 p d f 文档可能在WAP端浏览体验不佳.建议您优先选择TXT,或下载源文件到本机 查看. 维普资 ...

  8. c语言程序设计分段定时器,单片机C语言编程定时器的几种表达方式

    原标题:单片机C语言编程定时器的几种表达方式 吴鉴鹰单片机开发板地址 店铺:[吴鉴鹰的小铺] 地址:[https://item.taobao.com/item.htm?_u=ukgdp5a7629&a ...

  9. 访问外部扩展C语言编程,单片机C语言编程(系统扩展IC)8.ppt

    单片机C语言编程(系统扩展IC)8 第8章 单片机系统扩展 第8章 单片机系统扩展 目 录 8.1 扩展并行三总线 8.2 扩展简单并行输入/输出口 8.3 扩展并行数据存储器 8.4 串行扩展总线接 ...

  10. C语言对p1口取反,单片机c语言编程基础(5页)-原创力文档

    单片机的外部结构: 1. DIP40双列直插: 2. P0,P1,P2,P3四个8位准双向I/O引脚:(作为I/O输入时,要先输出高电平) 3. 电源VCC(PIN40)和地线GND(PIN20): ...

最新文章

  1. LaTeX 公式输入软件 KLatexFormula
  2. rsync定时加脚本实现本地到阿里的ftp文件同步
  3. DownloadManager 的使用
  4. Docker 搭建pxc集群 + haproxy + keepalived 高可用(二)
  5. C#中? 、?? 、?. 、??= 的用法和说明
  6. MySQL 示例数据库 employees 详解
  7. position:fixed定位
  8. SQL数据旋转的问题
  9. [python]Python概述
  10. 最新STM32G0系列选型表1
  11. 【51单片机】蜂鸣器程序
  12. 运放的输入失调电压、输入偏置电流和输入失调电流以及电阻匹配的作用之一
  13. RK3288开发板——Debian8系统制作
  14. 介绍identity matrices
  15. 转载---SQL Server XML基础学习之7--XML modify() 方法对 XML 数据中插入、更新或删除...
  16. 雅高集团2021年即将开业的新酒店数量强劲增长
  17. 价值百万的企业大数据分析报告是如何炼成的?
  18. 高通thermal-engine配置文件格式详解
  19. 如何在CSDN收获粉丝-你主动我们之间就会有故事
  20. Linux ar命令说明

热门文章

  1. 线上电商运营流程绘制流程图分享
  2. 最新emoji表情代码大全_三十而已表情包下载-三十而已表情包大全最新下载
  3. y480 linux无线网卡驱动,联想y480无线网卡驱动下载
  4. [python] ylgy攻略 用魔法打败魔法
  5. 加多宝首度披露"换头手术"的详细内幕
  6. python转换成exe后会出现dos框_解决Pyinstaller 打包exe文件 取消dos窗口(黑框框)的问题...
  7. python版使用tinypng压缩图片大小
  8. Hyperchain 超块链创始人史兴国对谈杨民道:新公链赛道烽烟再起,move语言能开启下一轮牛市吗?
  9. html动画转换为桌面动态壁纸,怎么设置电脑动态壁纸-动态桌面,这个功能太好玩了...
  10. houseprice_analysis_广州房子租售比分析(中)