资讯详情

主流16位单片机学习详解:飞思卡尔MC9S12G系列

描述

电子爱好者网络:随着驾驶员对汽车舒适性和方便性要求的提高,车身电子产品需要继续提供更高性能的半导体,同时保持竞争价格。目前,飞思卡尔半导体已开始扩大16位S12微控制器(MCU)优化大量对成本敏感的汽车车身电子应用。先进的S12G根据应用要求,设备设计提供灵活的内存、包装和成本选项。MC9S12G该系列是一款专注于低功耗、高性能、低引脚数量的高效汽车级16位微控制器产品。该系列为桥连8位高端微机和16位高性能微机MC9S12XS系列。本文将详细介绍飞思卡尔MC9S12系列芯片简介,MC9S12单片机最小系统硬件设计,典型程序应用,飞思卡尔XS128和G阐述了两种单片机的主要区别。

938bb4eae49ef8ca1203d4507dc82e8e.png

飞思卡尔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该系列可获得1000个包装-pin LQFP, 64-pin LQFP, 48-pinLQFP/QFN, 32-pin LQFP and 20-pin TSSOP,特别是对于较少引脚的封装发挥最大作用。此外,可以在每个模块中获得的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 J车身控制器、车门模块、乘客检测、空调、座椅控制器门模块、乘客检测、空调、座椅控制器和照明模块。这款16位S12G基于业界公认的系列S12架构为应用设计提供了更复杂的处理功能,保留了代码的有效性,并得到了广泛的应用S生态系统有助于降低内存占用和开发成本。

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 J一般汽车应用2602通信。

MC9S12G系列具有16位MCU飞思卡尔的所有优势和性能都保留了8位和16位MCU低成本、低功耗、电磁兼容性(EMC)以及代码效率等优点。

关于MC9S12G系列16位MCU的特性:

?总线频率为25MHz的S12 CPU内核提供业界公认S为了解决传统的8位应用设计版本,12架构和处理能力;

?高达240KB电影上的闪存(包括纠错码(ECC))存储代码有助于减少板上的闪存/ROM;

?高达4KB的EEPROM(包括ECC)提供的用户界面比以前几代产品的数据快闪更简单;

?采用多种可扩展性CAN模块(支持CAN协议2.0A/B),专为支持CAN设计通信端口复杂的系统需求;

?支持三个串行通信接口模块LIN通信,三个串行外部接口(SPI)模块可以提供更好的灵活性、更多的选项和优势,并需要增加SCI/LIN或SPI通信端口;

?在外设和存储器中提供16位存取,无等待状态;

?闪存从16K到240K包装从20开始TSSOP到100LQFP提供灵活的嵌入式设计和最大功能;

?不仅提供每个模块I/O而且还在I/O端口提供从停止或等待模式中唤醒的中断功能;

?高达11KB片上SRAM,提供更多存储单元;

?精密固定电压参考ADC转换;

? 1MHz内部振荡器;

?调整输入电源和所有内部电压。

及时复位钟-复位

上电复位

自动检测单片机VDD端跳变,启动自动工作。

外部复位

通过RESET引脚加低压,拉低超过一定时间

复位后可以实现。

看门狗复位

在软件运行后,帮助系统自动复位。

时钟监视器复位

利用内部的RC确保时钟频率符合要求。

振荡器和时钟电路

EXTAL输入外部时钟输入或石英振荡放大器

XTAL石英振荡放大器的输出

注:DG串联振荡电路和并联振荡电路可用于128。

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阅读更多精彩内容

点击阅读全文

标签: 稳压芯片mc1403

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

 锐单商城 - 一站式电子元器件采购平台  

 深圳锐单电子有限公司