随着驾驶员对车内舒适度和便利性的要求在提高,汽车车身电子产品在保持具有竞争力价格的同时,还需要继续提供性能更高的半导体。飞思卡尔半导体目前开始扩大现已普及的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模块 基本相同。
从数据到智能工业互联网和中国智造之痛
环形导轨输送线的各项性能参数是怎样的
电子产品对电子连接器的依赖
硒鼓注意事项
周报:华为官宣独立品牌“HI”,再现“造好”车野心
主流16位单片机学习详解:飞思卡尔MC9S12G系列
PCB设计时处理去耦电容和旁路电容的注意事项
基于凌阳16位单片机的智能车电路模块设计
手机不好做!黑莓视线转移,全力打造自动驾驶汽车?
华为P10闪存门最新消息:华为P10闪存门事件深入人心,如何测试手机内存
国家非常重视、扶持集成电路产业迅速发展
DS1245W 3.3V 1024k非易失SRAM
日本研究团队研发可褶皱可拉伸的超薄LED显示屏幕 主要用于医疗系统
AMIC110多协议可编工业通信处理器开发方案
关于EDA设计 这几个问题你一定要知道
Facebook正在做无人机、激光器及人造卫星的研发
缓存大小对CPU性能的影响解析
VR让ChinaJoy化身“虚拟现实娱乐盛典”
华为推TCC解决方案助力5G业务敏捷可靠上线
传紫光入股美光,抢苹果订单华亚科扮先锋