基于飞思卡尔MC9S12XEP的SPI程序
飞思卡尔单片机S12使用方法及程序
飞思卡尔单片机S12使用方法及程序单片机简介:9S12XS128MAA单片机是16位的单片机80个引脚,CPU是CPU12X,内部RAM 8KB,EEPROM:2KB,FLASH:128KB,外部晶振16M,通过内部PLL可得40M总线时钟。
9S12XS128MAA单片机拥有:CAN:1个,SCI:2个,SPI:1个,TIM:8个,PIT:4个,A/D:8个,PWM:8个下面介绍下我们项目用到的几个模块给出初始化代码1、时钟模块初始化单片机利用外部16M晶振,通过锁相环电路产生40M的总线时钟(9S12XS128系列标准为40M),初始化代码如下:view plaincopy to clipboardprint?/******************系统时钟初始化****************/void Init_System_Clock(){asm { // 这里采用汇编代码来产生40M的总线LDAB #3STAB REFDVLDAB #4STAB SYNRBRCLR CRGFLG,#$08,*//本句话含义为等待频率稳定然后执行下一条汇编语句,选择此频率作为总线频率BSET CLKSEL,#$80}}/******************系统时钟初始化****************/void Init_System_Clock(){asm { // 这里采用汇编代码来产生40M的总线LDAB #3STAB REFDVLDAB #4STAB SYNRBRCLR CRGFLG,#$08,*//本句话含义为等待频率稳定然后执行下一条汇编语句,选择此频率作为总线频率BSET CLKSEL,#$80}上面的代码是汇编写的,这个因为汇编代码量比较少,所以用它写了,具体含义注释已经给出,主函数中调用此函数即可完成时钟初始化,总线时钟为40M.2、SCI模块初始化单片机电路做好了当然少不了和PC之间的通信,通信通过单片机串口SCI链接到PC 端的COM口上去。
MC9S12XEP100开发板实验指导手册
12864 汉显液晶模块
ZX0802A 小液晶
7
飞翔科技
网店地址
无线遥控模块
该开収板可分20个功能模块,下面简单介绍每个功能模块: ●电源电路:电源模块使用LM2940芯片,将12V的电源转换成5V的电源,并使用LM1117芯片 将5V的电源转换为3.3V,以便给SD卡供电。本开収板提供的是12V的电源,可以直接连接一 般轿车上的电源。 ● LED灯:8个由单片机I/O控制的収光二枀管。 ●按键:4个按键,熟悉单片机的按键查询和中断功能。 ●蜂鸣器:该模块使用一个蜂鸣器作为収声器件。 ●SCI:本开収板有两路RS232,可调试单片机的串口。 ●LIN总线:该模块使用TJA1020芯片,本开収板有一路LIN接口,使用两块开収板,用户可 调试LIN总线通信。 ●CAN总线:该模块使用TJA1050芯片,本开収板有一路CAN接口,使用两块开収板,用户可
3.1 安装 CodeWarrior 软件……………………..……………………..……………….....................................17 3.2 安装 BDM 驱动…………………………….……………………..……………….........................................17 3.3 创建新工程…………………………….………….….…………..……………….........................................17 3.4 调试新建工程……………….…….………….…………………..………………........................................21 第 4 章 基础实验………………………….………………..…………………..……………........................................25 实验一 复位及看门狗…….….………………..…………………..………………........................................25 实验二 蜂鸣器实验……………………………..…………………..………………........................................27 实验三 LED 灯实验……….…..…..……………..…………………..………………........................................28 实验四 按键实验……………………………..…………………..………….………........................................29 实验五 ATD 实验…………..……….……....….………………..………….………........................................33 实验六 锁相环实验…………………………..…………………..………….……….......................................37 实验七 SCI 串口实验……………..…………..…………………..………….……….......................................38 实验八 PWM 实验……………….….……..…………………..………….………............................................41 实验九 ECT 实验………………..…..…..….………………..………….………..............................................42 实验十 实时中断实验……….…….….…………..……..……….……….................................................44 实验十一 PIT 实验…………..………..…………………..………….……….................................................45 实验十二数码管实验……..………..…………………..………….……….................................................46 第 5 章 高级实验……………..…………………..……………..………….………..................................................47 实验一 数字电压表..…………………..……………..………….………....................................................47 实验二 数字秒表及定时器…..……………..………….……….........................................................48 实验三 蜂鸣器播放音乐……..……………..………….………............................................................50 实验四 汉显液晶实验…………..……………..………….………..........................................................51 实验五 ZX0802A 小液晶实验..………..……..………….……….........................................................53 实验六 遥控模块实验…………..……………..………….………..........................................................54 实验七 温度传感器实验………..……………..………….……….........................................................56 实验八 RS-485 总线实验……..…….………..………….………..........................................................58 实验九 LIN 总线实验……..……………...………….……….................................................................59 实验十 CAN 总线实验……..…………....………….……….................................................................63 实验十一 SAE-J1939 实验...………….……….….……….................................................................66 实验十二 SD 卡实验………....………….……….….……….................................................................67 实验十三 综合演示实验…....………………….….……….................................................................69 实验十四 双核协同工作实验………………….….………...............................................................70 实验十五 DFLASH 实验.…………..….…….….………….………..........................................................76
基于飞思卡尔MC9S12XEP的SPI程序
基于飞思卡尔MC9S12XEP的SPI程序#defineSPI_GLOBALS#include\#defineWrite_To_FlahDataSize15taticuint8_tDummy;//选中flahvoidSPICSLow(uint8_tChip){if(Chip==0){SPI_FLASH1_CS_LOW();//选中flah1}ele{SPI_FLASH2_CS_LOW();//选中flah2}}//不选voidSPICSHigh(uint8_tChip){if(Chip==0){SPI_FLASH1_CS_HIGH();//不选中flah1}ele{SPI_FLASH2_CS_HIGH();//不选中flah2}}//flah写使能voidSPIWriteEnable(uint8_tChip){//flah写除能voidSPIWriteDiable(uint8_tChip){SPICSLow(Chip);//bringthechoenchip'CSpindown//SPI初始化voidSPIInit(void){DDRP_DDRP0=1;DDRP_DDRP1=1;DDRP_DDRP2=1;DDRP_DDRP3=1;SPI_WP1_OFF();SPI_WP2_OFF();SPI_FLASH1_CS_HIGH();SPI_FLASH2_CS_HIGH();SPI2BR=(0<<4)|(0);//(0+1)某2^(0+1)=2,20M/2=10MSPI2CR1=0某50;//主机模式}//SPI读flah的IDSPI_E某Tuint16_tSPIReadID(uint8_tChip){uint16_tID;SPICSLow(Chip);//bringthechoenchip'CSpindownDummy=SPIReadWriteByte(SPI2,0某00);//writeAddr[16:23]//写24位地址Dummy=SPIReadWriteByte(SPI2,0某00);//writeAddr[8:15]Dummy=SPIReadWriteByte(SPI2,0某00);//writeAddr[0:7]((uint8_t某)&ID)[0]=SPIReadWriteByte(SPI2,SPI_CMD_DUMMY);//manufacturerID ((uint8_t某)&ID)[1]=SPIReadWriteByte(SPI2,SPI_CMD_DUMMY);//deviceIDreturnID;//returntheIDvalue}//SPI读flah状态uint8_tSPIReadSta(uint8_tChip){uint8_tSta;SPICSLow(Chip);//bringthechoenchip'CSpindownSta=SPIReadWriteByte(SPI2,SPI_CMD_DUMMY);//tatuSPICSHigh(Chip);//bringthechoenchip'CSpinhighreturnSta;//returnthetatuvalue}//等待芯片空闲(在执行Byte-Program,Sector-Erae,Block-Erae,Chip-Erae操作后voidSPIWaitBuy(uint8_tChip){SPICSLow(Chip);///----------------------------------------------------------------------------------------------------------//Function:SPIFlah初始化//Param://Return://note///----------------------------------------------------------------------------------------------------------SPI_E某TvoidSPIFlahInit(void){uint8_ti;uint16_tID;SPIInit();//memet(SPI_Flah_Info,0,izeof(SPI_Flah_Info));//for(i=0;i<SP I_MA某_CHIPS;i++){ID=SPIReadID(i);SPI_Flah_Info[i].DeviceID=ID;SPI_Flah_Info[i].Size=(uint32_t)8某1024某1024;SPI_Flah_Info[i].SectorSize=4某1024;SPI_Flah_Info[i].SectorPage=16;SPI_Flah_Info[i].BlockSize=(uint32_t)64某1024;SPI_Flah_Info[i].Block=128;SPI_Flah_Info[i].PageSize=256;SP I_Flah_Info[i].Page=65536;}}/某--------------------------------------------------------------------------------------------------------SPI收发送函数----------------------------------------------------------------------------------------------------------某/SPI_E某Tuint8_tSPIReadWriteByte(uint8_tSPI,uint8_tData){if(SPIcaeSPI0:while(SPI0SR_SPTEF==0);SPI0DRL=Data;while(SPI0SR_SPIF==0);returnSPI0DRL;break;caeSPI2:while(SPI2SR_SPTEF==0);SPI2DRL=Data;while(SPI2SR_SPIF==0);returnSPI2DRL;break;}}///----------------------------------------------------------------------------------------------------------//Function:把Chip号芯片的Adre位置开始Len长度的数据读取到Buf中//Param://Return://note///----------------------------------------------------------------------------------------------------------SPI_E某TvoidSPIRead(uint8_tChip,uint32_tAddre,uint8_t某Buf,uint32_tLen){uint32_ti;SPIWaitBuy(Chip);//判忙SPICSLow(Chip);//bringthechoenchip'CSpindownDummy=SPIReadWriteByte(SPI2,((uint8_t某)&Addre)[1]);//writeAddr[8:15]某)&Addre)[2]);//writeAddr[0:7]for(i=0;i<Len;i+=1){Buf[i]=SPIReadWriteByte(SPI2,SPI_CMD_DUMMY);//readdata}SPICSHigh(Chip);//bringthechoenchip'CSpinhigh}///----------------------------------------------------------------------------------------------------------//Function:向chip号芯片的Addre位置开始的区域写入长度为Len 的Buf内容//Param://Return://note///----------------------------------------------------------------------------------------------------------SPI_E某TvoidSPIWritePage(uint8_tChip,uint32_tAddre,uint8_tBuf[],uint32_ tLen){uint8_ti;SPIWriteEnable(Chip);SPICSLow(Chip);//bringthechoenchip'CSpindownDummy=SPIReadWriteByte(SPI2,((uint8_t某)&Addre)[0]);//write Addr[16:23]Dummy=SPIReadWriteByte(SPI2,((uint8_t某)&Addre)[1]);//writeAddr[8:15]某)&Addre)[2]);//writeAddr[0:7]for(i=0;iDummy=SPIReadWriteByte(SPI2,Buf[i]);//writethedatatobeent} SPICSHigh(Chip);//bringthechoenchip'CSpinhighSPIWaitBuy(Chip );//判忙}///----------------------------------------------------------------------------------------------------------//Function:擦除flah一个ector//Param://Return://note///----------------------------------------------------------------------------------------------------------SPI_E某TvoidSPIEraeSector(uint8_tChip,uint32_tAddre){SPIWriteEnable(Chip);//writeenableSPIWaitBuy(Chip);//判忙SPICSLow(Chip);//bringthechoenchip'CSpindownDummy=SPIReadWriteByte(SPI2,SPI_CMD_4K_ERASE);//write4K_Erae Dummy=SPIReadWriteByte(SPI2,((uint8_t某)&Addre)[1]);//writeAddr[8:15]Dummy=SPIReadWriteByte(SPI2,((uint8_t某)&Addre)[2]);//writeAddr[0:7]SPICSHigh(Chip);//bringthechoenchip'CSpinhighSPIWriteDiable(Chip);SPIWaitBuy(Chip);//判忙}///----------------------------------------------------------------------------------------------------------//Function:擦除flah一个block//Param://Return://note///----------------------------------------------------------------------------------------------------------SPI_E某TvoidSPIEraeBlock(uint8_tChip,uint32_tAddre){SPIWriteEnable(Chip);SPIWaitBuy(Chip);//判忙SPICSLow(Chip);//bringthechoenchip'CSpindownDummy=SPIReadWriteByte(SPI2,((uint8_t某)&Addre)[0]);//writeAddr[16:23]Dummy=SPIReadWriteByte(SPI2,((uint8_t某)&Addre)[1]);//writeAddr[8:15]Dummy=SPIReadWriteByte(SPI2,((uint8_t某)&Addre)[2]);//writeAddr[0:7]SPICSHigh(Chip);//bringthechoenchip'CSpinhighSPIWriteDiable(Chip);SPIWaitBuy(Chip);//判忙}///----------------------------------------------------------------------------------------------------------//Function:擦除flah整片芯片//Param://Return://note///----------------------------------------------------------------------------------------------------------SPI_E某TvoidSPIEraeChip(uint8_tChip){SPIWriteEnable(Chip);SPIWaitBuy(Chip);//判忙SPICSLow(Chip);Dummy=SPIReadWriteByte(SPI2,SPI_CMD_CHIP_ERASE);SPICSHigh(Chip);SPIWaitBuy(Chip);//判忙SPIWriteDiable(Chip);}/某----------------------------------------------------------------------------------------------------------向SPI_FlahBuf 里面写入数据------------------------------------------------------------------------------------------------------------某///SPI_E某TSPIWriteToBuf/某----------------------------------------------------------------------------------------------------------向SPI_FlahBuf 里面写入数据------------------------------------------------------------------------------------------------------------某/SPI_E某TvoidSPIWriteToBuf(uint8_tarray[],uint8_tarray_len){uint8_ti;for(i=0;i<array_len;i++)SPI_FlahBuf[i]=array[i];SPI2CR1_SPIE=1;//给SPI缓冲区写完数据,打开中断,将数据写入到Flah里面。
MC9S12XEP100开发板实验指导手册
编程器P800-ISP【使用手册】MC9S12XEP系列芯片在线烧录指南
产品应用笔记
©2016 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 1
广州致远电子股份有限公司
P800 烧写指南
MC9S12XEP 系列芯片在线烧写指南
2. 工程新建
如下图,为 P800 的面板,点击创建开始 P800 工程的新建。
2.1 创建
图 2.0 P800 顶层面板
3.10 量产配置................................................................................................................. 11
3.11 缓冲区.....................................................................................................................12
2.1
创建........................................................................................................................... 2
2.2
芯片选择 ................................................................................................................... 3
1. 适用范围...................................................................................................................1
飞思卡尔MC9S12XS128功能模块驱动
用了一年多飞思卡尔MC9S12XS128这款处理器,现在总结下各个功能模块的驱动.//锁相环时钟的初始化总线频率为40MHz(总线时钟为锁相环时钟的一半)//晶振为11.0592MHzvoid PLL_init(void) //PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1) { //锁相环时钟= 2*11.0592*(39+1)/(10+1)=80MHz 总线时钟为40MHzREFDV=0x0A;SYNR=0x67; //0110_0111 低6位的值为19,高两位的值为推荐值while(CRGFLG_LOCK != 1);CLKSEL_PLLSEL = 1; //选定锁相环时钟//FCLKDIV=0x0F; //Flash Clock Divide Factor 16M/16=1M}//周期中断定时器的初始化-// //周期中断通道1用于脉冲累加器的定时采样,定时周期为: 10ms= (199+1)*(1999+1)/(40M) (没有使用)//周期中断通道0用于控制激光管的轮流发射,定时周期为: 2000us= (399+1)*(199+1)/(40M)//2011/4/4 15:24 定时时间改为1msvoid PIT_init(void){PITCFLMT_PITE = 0; // 禁止使用PIT模块 PITCFLMT :PIT 控制强制加载微计数器寄存器。
PITCE_PCE0 = 1; // 使能定时器通道0//PITCE_PCE1 = 1; //使能定时器通道1PITMUX = 0; //通道0,和通道1均选择8位微计数器0//修改时间只需要改下面四行PITMTLD0 = 199; //向8位微计数器中加载的值PITLD0 = 199; //向16位计数器中加载的值//PITMTLD1 = 39; //向8位微计数器中加载的值 8位,最大值不要超过255//PITLD1 = 1999; //向16位计数器中加载的值PITINTE |= 0x01; //使能定时器通道0的中断PITCFLMT_PITE = 1;//使能PIT模块}//脉冲累加器的初始化, PT7口外接光电编码器//最新修改: 2011/3/25 16:53void PT7_PulAcc_Init(void){DDRT &= 0x77;//设置PT7,PT3口为输入(硬件上PT7,PT3通过跳线联到了一块)PERT |= 0x80; //使能通道7的上拉电阻PPST &= 0x7f; //电阻设为上拉电阻TCTL4 &= 0x3f; //禁止PT3的输入捕捉功能PACTL = 0x50; //启动脉冲累加计数器,上升沿触发,禁止触发中断和溢出中断,主定时器禁止}//通道1用于控制舵机1 PWM 高电平有效,//通道3用于控制电机1 PWM 低电平有效,这与前两代车高电平有效有区别!!!!!//通道7用于给上排激光管提供PWM信号 PWM高电平有效!!!!!//通道6用于给下排激光管提供PWM信号 PWM高电平有效!!!!!// 2011-03-17 7:56 增加了A端口的使用新增通道6//2011-6-9 23:03 //增加了通道4,5的联合使用,用于控制下排方向舵机 void PWM_init(void){PWME = 0x00;//PWM禁止PWMPRCLK = 0x03; // ClockA=40M/8=5M, Clock B = 40M/1=40M PWMSCLB = 10; // Clock SB= 40/2*10= 2MHz(供电机)PWMSCLA = 5; // SA = Clock A/2*5 = 5M/10 = 500K = SA 用于控制舵机PWMPOL = 0xe2; //1110_0010通道7,通道6与通道1、通道5先输出高电平然后输出低电平,POLx=1先输出高电平后输出低电平; PPOLx=0先输出低电平)PWMCAE = 0x00; // 左对齐输出(CAEx=0为左对齐,反之为中心对齐)//PWMCLK = 0010_1010 (0 1 4 5位控制SA_1;或A_0; 2 3 6 7位控制SB_1 或B_0)//为PWM通道1选择时钟 SA(500KHz),//为PWM通道5选择时钟 SA(500KHz),//为通道3选择时钟 SB(10MHz)//为通道7选择时钟B(40MHz)//为通道6选择时钟B(40MHz)PWMCLK = 0x2A; //0010_1010PWMCTL = 0x70; //0111_0000 CON45=1,把通道4,5联合使用。
飞思卡尔MC9S12单片机实验程序
PORTB=0xff; //led灯全暗
TIOS=0x00; //设置定时器通道0为输入捕捉
TSCR1=0x80; //定时器使能
TSCR2=0x01; //设置自由计数器2分频,且禁止定时器溢出中断
TCTL4=0x02; //捕捉器仅下降沿捕捉
TIE=0x01; //允许定时器通道0的中断
}
}
void main(void) {
DDRB=0xff;
PORTB=0x00;
for(;;)
{
fun();
}
}
SCI
#include <hidef.h>
#include <mc9s12db128.h>
#pragma LINK_INFO DERIVATIVE "mc9s12db128b"
unsigned char pp=0xf0; //欲发送的数字
/*********串口初始化*********/
void init() {
DDRB=0xff;
PORTB=0xff; //开始led灯暗,即数据尚未接收
SCI0BD=52; //初始化波特率为9600
SCI0CR1=0x00; //八位无奇偶校验模式
SCI0CR2=0x2c; //接收中断允许
}
/**************写数据***********/
void interrupt 20 funck() {
unsigned char k;
k=read();
PORTB=~k;
}
SPI
不会,以后补充。
LED
#include <hidef.h> /* common defines and macros */
飞思卡尔16位单片机MC9S12XS128加密(程序下载不进去,正负极未短路,通电芯片不发烫)后解锁的方法及步骤w
飞思卡尔16位单片机MC9S12XS128加密(程序下载不进去,正负极未短路,通电芯片不发烫)后解锁的方法及步骤/*****************************************************************************/ *本人用此法成功解救了4块板子【窃喜!】,此说明是本人边操作边截图拼成的,有些是在别的说明上直接截图【有些图本人不会截取,就利用现成的了,不过那也是本人用豆和财富值换来的】,表达不清之处还望见谅,大家将就着看吧!如能有些许帮助,我心甚慰!!!————武狂狼2014.4.23 /*****************************************************************************/编译软件:CW5.1版本,下载器:飞翔BDMV4.6 【1】,连接好单片机,准备下载程序,单击下载按钮出现以下界面或(图1.1)图 1.1——4中所有弹出窗口均单击“取消”或红色“关闭”按钮依次进入下一界面(图1.2)(图1.3)(图1.4)******************************************************************************* *******************************************************************************【2】单击出现如下图所示下拉列表,然后单击(图2.1)出现下图(图2.2)对话框,按下面说明操作(图2.2)弹出图2.3,单击按钮,依次出现如图2.4--5窗口,均单击(图2.3)(图2.4)******************************************************************************* *******************************************************************************【3】单击出现下拉列表,然后单击下拉列表中单击按钮出现如下界面,单击选择相对应的单片机型号(我选的红色方框里的HCS12X….),单击OK. PS:【此步骤是本人自己试出来的,若不进行此操作,图3.3中下拉列表中无要找选项】(图3.1)(图3.3)(图3.4)(图3.5)红色方框2中默认即为所要选的文件,此步只需单击确认按钮即可,如有不同读者酌情处置。
飞思卡尔单片机mc9s12dg128的pwm参考程序
飞思卡尔单片机m c9s12d g128的p w m参考程序(总3页)--本页仅作为文档封面,使用时请直接删除即可----内页可以根据需求调整合适字体及大小--飞思卡尔单片机mc9s12dg128的pwm参考程序大学生参考网发表时间:10月13日 17:44 提交:demon#include <> /* common defines and macros */#include <> /* derivative information*/#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"/***********************************************************pwm初始化函数北华大学王盼宝 by demon 2007-5-12*********************************************************/voidpwm_initial()//pwm初始化函数{ PWME=0x22;//通道01,45使能 PWMPOL=0x22;//通道01,45输出波形开始极性为1 PWMCTL=0x50;//通道01,45级联 PWMCLK=0x02;//通道01选择SA为时钟源 PWMSCLA=0X04;//通道01时钟SA为3MHz(24/(2*4))PWMPER01=60000;//设定通道01输出频率(50Hz)PWMPER45=12000;//设定通道45输出频率(2KHz)}/***********************************************************pwm输出函数 by demon 2007-5-12*程序描述;由输入参数向舵机和电机输出相应pwm*参数:舵机方向:3300-5700 速度:0-12000*********************************************************/void pwm(int speed,int direction)//pwm{pwm_initial();if(direction<3300)direction=3300; if(direction>5700) direction=5700; PWMDTY01=direction;if(speed>12000) speed=12000;PWMDTY45=speed; }飞思卡尔单片机mc9s12dg128的io口初始化参考程序大学生参考网发表时间:10月13日 17:47 提交:demon#include <> /* common defines and macros */#include <> /* derivative information*/#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"北华大学王盼宝void main(){ DDRA=0x00; DDRB=0xFF;PUCR=0x02; while(1){ PORTB=PORTA; } EnableInterrupts;for(;;) {} /* wait forever *//* please make sure that you never leave this function */}飞思卡尔单片机mc9s12dg128的ad初始化参考程序void AD(void) { word t0=0;word t1=0;word t2=0;word t3=0;word t4=0;word t5=0;word t6=0;word t7=0;while(ATD0STAT0_SCF) { t0=ATD0DR0; ad00= (byte)(t0>>8);//高8位移到低8位且高8位为0 t1=ATD0DR1; ad01=(byte)(t1>>8); t2=ATD0DR2; ad02=(byte)(t2>>8); t3=ATD0DR3; ad03=(byte)(t3>>8); t4=ATD0DR4; ad04=(byte)(t4>>8); t5=ATD0DR5; ad05=(byte)(t5>>8); t6=ATD0DR6; ad06=(byte)(t6>>8); t7=ATD0DR7; ad07= (byte)(t7>>8); }。
飞思卡尔MC9S12XEP芯片的CAN总线代码
#define CAN_GLOBALS#include "can.h"void EEC1_Process(uint8_t OutPtr, uint8_t InPtr);void EEC2_Process(uint8_t OutPtr, uint8_t InPtr);void EEC3_Process(uint8_t OutPtr, uint8_t InPtr);void ET1_Process(uint8_t OutPtr, uint8_t InPtr);void CCVS_Process(uint8_t OutPtr, uint8_t InPtr);void LFE_Process(uint8_t OutPtr, uint8_t InPtr);void AMB_Process(uint8_t OutPtr, uint8_t InPtr);void IC1_Process(uint8_t OutPtr, uint8_t InPtr);void VEP1_Process(uint8_t OutPtr, uint8_t InPtr);void EFL_P1_Process(uint8_t OutPtr, uint8_t InPtr);void LFC_Process(uint8_t OutPtr, uint8_t InPtr);void Digit2Ascii1(uint32_t Digit, uint8_t InPtr); //一位小数void Digit2Ascii0(uint32_t Digit, uint8_t InPtr); //数字转化为ASCII码 0位小数void Digit2AsciiPos0(uint32_t Digit, uint8_t InPtr); //数字转化为ASCII码 0位小数负数uint8_t *Result;HMI_Text_Dis_tPtr HMI_Text_DisPtr;///----------------------------------------------------------------------------------------------------------//Function://Param://Return://note///----------------------------------------------------------------------------------------------------------void CANFilterInit(uint8_t CAN){if(CAN<CANS){switch(CAN){case CAN0:CAN0IDAR0 = 0xFF;CAN0IDAR1 = 0xFF; CAN0IDAR2 = 0xFF; CAN0IDAR3 = 0xFF; CAN0IDMR0 = 0xFF; CAN0IDMR1 = 0xFF; CAN0IDMR2 = 0xFF; CAN0IDMR3 = 0xFF; CAN0IDAR4 = 0xFF; CAN0IDAR5 = 0xFF; CAN0IDAR6 = 0xFF; CAN0IDAR7 = 0xFF; CAN0IDMR4 = 0xFF; CAN0IDMR5 = 0xFF; CAN0IDMR6 = 0xFF; CAN0IDMR7 = 0xFF; break;case CAN1:CAN1IDAR0 = 0xFF; CAN1IDAR1 = 0xFF; CAN1IDAR2 = 0xFF; CAN1IDAR3 = 0xFF; CAN1IDMR0 = 0xFF; CAN1IDMR1 = 0xFF; CAN1IDMR2 = 0xFF; CAN1IDMR3 = 0xFF; CAN1IDAR4 = 0xFF; CAN1IDAR5 = 0xFF; CAN1IDAR6 = 0xFF; CAN1IDAR7 = 0xFF; CAN1IDMR4 = 0xFF; CAN1IDMR5 = 0xFF; CAN1IDMR6 = 0xFF; CAN1IDMR7 = 0xFF; break;}}}/*--------------------------------------------------------------------------------------------------------Function:Param:Return:note----------------------------------------------------------------------------------------------------------*/void CANRxQueInit(void){CAN_RxQue.Front = 0;CAN_RxQue.Rear = 0;memset(&CAN_RxQue, 0, sizeof(CAN_RxQue));}/*--------------------------------------------------------------------------------------------------------Function: CAN0 CAN1初始化Param:Return:note----------------------------------------------------------------------------------------------------------*/CAN_EXT void CANInit(uint8_t CAN){if(CAN<CANS){switch(CAN){case CAN0:CAN0CTL1_CANE = 1; //使能CAN模块CAN0CTL1_LISTEN = 0; //除能监听模式CAN0BTR0 = CAN0BTR0_Val; //设置波特率CAN0BTR1 = CAN0BTR1_Val;CANFilterInit(CAN0); //设置验收、屏蔽滤波器CAN0CTL0_INITRQ = 0; //请求退出初始化while(CAN0CTL1_INITAK == 1){ //请求处理ing _asm(nop);}while(CAN0CTL0_SYNCH == 0){_asm(nop);}CAN0RFLG = 0xC3; //清除接收相关标志位CANRxQueInit(); //CAN中断接收队列CAN0RIER_RXFIE = 1; //接收中断允许break;case CAN1:CAN1CTL1_CANE = 1; //使能CAN模块CAN1CTL1_LISTEN = 0; //除能监听模式CAN1BTR0 = CAN1BTR0_Val; //设置波特率CAN1BTR1 = CAN1BTR1_Val;CANFilterInit(CAN1); //设置验收、屏蔽滤波器CAN1CTL0_INITRQ = 0; //请求退出初始化while(CAN1CTL1_INITAK == 1){ //请求处理ing _asm(nop);}while(CAN1CTL0_SYNCH == 0){_asm(nop);}CAN1RFLG = 0xC3; //清除接收相关标志位CANRxQueInit(); //CAN中断接收队列CAN1RIER_RXFIE = 1; //接收中断允许break;}}}/*----------------------------------------------------------------------------------------------------------Function:存储并显示把CAN_RxQue 队列里的数据存放到 FLASH 中,某些数据再存到HMI_Text_Dis_Que 队列里进行显示其中 CAN_RxQue 的ID转换为 PGNTmp 再转换为 HMI_Text_Dis_Que 显示的位置CAN_RxQue 的数据即 HMI_Text_Dis_Que 的数据起始帧命令帧终止帧都已包含Param:Return:note----------------------------------------------------------------------------------------------------------*/CAN_EXT void CANRxQueToProcess(void){ID_tPtr IDPtr;uint32_t PGNTmp;while(CAN_RxQue.Front!= CAN_RxQue.Rear) //源队列未空,可出列{IDPtr = &(CAN_RxQue.PDUs[CAN_RxQue.Front].Bits.ID); //指向出列项ID 域PGNTmp = 0;PGNTmp |= (uint8_t)(IDPtr->Bits.DP | IDPtr->Bits.R<<1);//析取DP和RPGNTmp <<= 8;PGNTmp |= (uint8_t)(IDPtr->Bits.PF0 | IDPtr->Bits.PF1<<2 | IDPtr->Bits.PF2<<5); //析取PFPGNTmp <<= 8;PGNTmp |= (uint8_t)(IDPtr->Bits.PS0 | IDPtr->Bits.PS1<<7);//析取PSif(PGNTmp == (uint16_t)PGN_FAULT_MEMORY){FAULT_flag = 1;}else{FAULT_flag = 0;}switch(PGNTmp){case (uint16_t)PGN_EEC1:EEC1_Process(CAN_RxQue.Front, HMI_Text_Dis_Que.Rear); break;case (uint16_t)PGN_EEC2:EEC2_Process(CAN_RxQue.Front, HMI_Text_Dis_Que.Rear); break;case (uint16_t)PGN_EEC3:EEC3_Process(CAN_RxQue.Front, HMI_Text_Dis_Que.Rear); break;case (uint16_t)PGN_AMB:AMB_Process(CAN_RxQue.Front, HMI_Text_Dis_Que.Rear); break;case (uint16_t)PGN_CCVS:CCVS_Process(CAN_RxQue.Front, HMI_Text_Dis_Que.Rear);break;case (uint16_t)PGN_ET1:ET1_Process(CAN_RxQue.Front, HMI_Text_Dis_Que.Rear); break;case (uint16_t)PGN_LFE:LFE_Process(CAN_RxQue.Front, HMI_Text_Dis_Que.Rear); break;case (uint16_t)PGN_EFL_P1:EFL_P1_Process(CAN_RxQue.Front, HMI_Text_Dis_Que.Rear); break;case (uint16_t)PGN_IC1:IC1_Process(CAN_RxQue.Front, HMI_Text_Dis_Que.Rear); break;case (uint16_t)PGN_VEP1:VEP1_Process(CAN_RxQue.Front, HMI_Text_Dis_Que.Rear); break;case (uint16_t)PGN_LFC: // 时间太大目前只能计算两个字节的LFC_Process(CAN_RxQue.Front, HMI_Text_Dis_Que.Rear);break;case (uint16_t)PGN_FAULT_MEMORY:FAULT_MEMORY_Process(CAN_RxQue.Front, HMI_Text_Dis_Que.Rear, 0, 0); //为了方便触摸屏看故障类型上下条时使用break;default:break;}CAN_RxQue.Front = (uint8_t)(CAN_RxQue.Front+1)%CAN_RXQUE_LEN;//出列一项}CANRxQueInit();}///----------------------------------------------------------------------------------------------------------//Function://Param://Return://note///----------------------------------------------------------------------------------------------------------void EEC1_Process(uint8_t OutPtr, uint8_t InPtr){uint32_t engspeed;uint32_t actualengtorque;eec1 = (EEC1_t *)CAN_RxQue.PDUs[OutPtr].Bits.DataField;engspeed = (((uint32_t)swab16(eec1->EngSpeed))*12) +(((uint32_t)swab16(eec1->EngSpeed))>>1);actualengtorque = ((uint32_t)(eec1->ActualEngTorque)) * 100;if(HMI_Text_Dis_Que.Front !=(HMI_Text_Dis_Que.Rear+1)%HMI_TEXTDIS_QUELEN) {HMI_Text_DisPtr = HMI_Text_Dis_Que.HMI_Text_Dis +HMI_Text_Dis_Que.Rear;HMI_Text_DisPtr->CMD_Start = HMI_CMD_START;HMI_Text_DisPtr->CMD_Type = HMI_CMD_TextDIS_ASCII;HMI_Text_DisPtr->Start_Point.x = 145;HMI_Text_DisPtr->Start_Point.y = 150;Digit2Ascii0(engspeed, InPtr);HMI_Text_DisPtr->CMD_End = HMI_CMD_END;HMI_Text_Dis_Que.Rear =(uint8_t)(HMI_Text_Dis_Que.Rear+1)%HMI_TEXTDIS_QUELEN;}if(HMI_Text_Dis_Que.Front !=(HMI_Text_Dis_Que.Rear+1)%HMI_TEXTDIS_QUELEN) {HMI_Text_DisPtr = HMI_Text_Dis_Que.HMI_Text_Dis + HMI_Text_Dis_Que.Rear;HMI_Text_DisPtr->Cmd_Start = HMI_CMD_START;HMI_Text_DisPtr->Cmd_Type = HMI_CMD_TEXTDIS_ASCII;HMI_Text_DisPtr->Start_Point.x = 590;HMI_Text_DisPtr->Start_Point.y = 150;if(actualengtorque<12500){actualengtorque = 12500 - actualengtorque;Digit2AsciiPos0(actualengtorque, HMI_Text_Dis_Que.Rear);}else{actualengtorque = actualengtorque - 12500;Digit2Ascii0(actualengtorque, HMI_Text_Dis_Que.Rear);}HMI_Text_DisPtr->Cmd_End = HMI_CMD_END;HMI_Text_Dis_Que.Rear =(uint8_t)(HMI_Text_Dis_Que.Rear+1)%HMI_TEXTDIS_QUELEN; //进列一项}Record_Write();}///----------------------------------------------------------------------------------------------------------//Function://Param://Return://note///----------------------------------------------------------------------------------------------------------void EEC2_Process(uint8_t OutPtr, uint8_t InPtr){uint32_t accpedalpos1;eec2 = (EEC2_t *)CAN_RxQue.PDUs[OutPtr].Bits.DataField;accpedalpos1 = ((uint32_t)(eec2->accpedalPos1)) * 40;if(HMI_Text_Dis_Que.Front !=(HMI_Text_Dis_Que.Rear+1)%HMI_TextDIS_QUELEN) //目的队列未满,可入列{HMI_Text_DisPtr = HMI_Text_Dis_Que.HMI_Text_Dis +HMI_Text_Dis_Que.Rear; //指向入列项HMI_Text_DisPtr->CMD_Start = HMI_CMD_START; //写入命令头HMI_Text_DisPtr->CMD_Type = HMI_CMD_TEXTDIS_ASCII; //写入命令种类HMI_Text_DisPtr->Start_Point.x = 145; //文本显示位置x坐标HMI_Text_DisPtr->Start_Point.y = 315; //文本显示位置y坐标Digit2Ascii0(accpedalpos1, InPtr); //%HMI_Text_DisPtr->CMD_End = HMI_CMD_END;HMI_Text_Dis_Que.Rear =(uint8_t)(HMI_Text_Dis_Que.Rear+1)%HMI_TEXTDIS_QUELEN; //进列一项}Record_Write();}///----------------------------------------------------------------------------------------------------------//Function://Param://Return://note///----------------------------------------------------------------------------------------------------------void EEC3_Process(uint8_t OutPtr, uint8_t InPtr){eec3 = (EEC3_t *)CAN_RxQue.PDUs[OutPtr].Bits.DataField;Record_Write();}///----------------------------------------------------------------------------------------------------------//Function://Param://Return://note///----------------------------------------------------------------------------------------------------------void ET1_Process(uint8_t OutPtr, uint8_t InPtr){uint32_t engcoolanttemp;et1 = (ET1_t *)CAN_RxQue.PDUs[OutPtr].Bits.DataField;engcoolanttemp = ((uint32_t)(et1->EngCoolantTemp)) *100;if(HMI_Text_Dis_Que.Front !=(HMI_Text_Dis_Que.Rear+1)%HMI_TextDIS_QUELEN) //目的队列未满,可入列{HMI_Text_DisPtr = HMI_Text_Dis_Que.HMI_Text_Dis +HMI_Text_Dis_Que.Rear; //指向入列项HMI_Text_DisPtr->CMD_Start = HMI_CMD_START; //写入命令头HMI_Text_DisPtr->CMD_Type = HMI_CMD_TEXTDIS_ASCII; //写入命令种类HMI_Text_Dis_Que.HMI_Text_Dis[InPtr].Start_Point.x = 145; //文本显示位置x坐标HMI_Text_Dis_Que.HMI_Text_Dis[InPtr].Start_Point.y = 390;if(engcoolanttemp<4000){engcoolanttemp = 4000 - engcoolanttemp;Digit2AsciiPos0(engcoolanttemp, InPtr);}else{engcoolanttemp = engcoolanttemp - 4000;Digit2Ascii0(engcoolanttemp, InPtr);}HMI_Text_DisPtr->CMD_End = HMI_CMD_END;HMI_Text_Dis_Que.Rear =(uint8_t)(HMI_Text_Dis_Que.Rear+1)%HMI_TEXTDIS_QUELEN; //进列一项}Record_Write();}///----------------------------------------------------------------------------------------------------------//Function://Param://Return://note///----------------------------------------------------------------------------------------------------------void CCVS_Process(uint8_t OutPtr, uint8_t InPtr){uint32_t vehiclespeed;ccvs = (CCVS_t *)CAN_RxQue.PDUs[OutPtr].Bits.DataField;vehiclespeed = (((uint32_t)swab16(ccvs->VehicleSpeed)) * 100) >> 8;if(HMI_Text_Dis_Que.Front !=(HMI_Text_Dis_Que.Rear+1)%HMI_TEXTDIS_QUELEN) //目的队列未满,可入列{HMI_Text_DisPtr = HMI_Text_Dis_Que.HMI_Text_Dis +HMI_Text_Dis_Que.Rear; //指向入列项HMI_Text_DisPtr->CMD_Start = HMI_CMD_START; //写入命令头HMI_Text_DisPtr->CMD_Type = HMI_CMD_TEXTDIS_ASCII; //写入命令种类HMI_Text_DisPtr->Start_Point.x = 370; //文本显示位置x坐标HMI_Text_DisPtr->Start_Point.y = 150; //文本显示位置y坐标Digit2Ascii1(vehiclespeed, InPtr); //%HMI_Text_DisPtr->CMD_End = HMI_CMD_END;HMI_Text_Dis_Que.Rear =(uint8_t)(HMI_Text_Dis_Que.Rear+1)%HMI_TEXTDIS_QUELEN; //进列一项}Record_Write();}///----------------------------------------------------------------------------------------------------------//Function://Param://Return://note///----------------------------------------------------------------------------------------------------------void LFE_Process(uint8_t OutPtr, uint8_t InPtr){uint32_t engfuelrate;lfe = (LFE_t *)CAN_RxQue.PDUs[OutPtr].Bits.DataField;engfuelrate = ((uint32_t)swab16(lfe->EngFuelRate)) * 5;if(HMI_Text_Dis_Que.Front !=(HMI_Text_Dis_Que.Rear+1)%HMI_TEXTDIS_QUELEN) {HMI_Text_DisPtr = HMI_Text_Dis_Que.HMI_Text_Dis +HMI_Text_Dis_Que.Rear;HMI_Text_DisPtr->Cmd_Start = HMI_CMD_START;HMI_Text_DisPtr->Cmd_Type = HMI_CMD_TEXTDIS_ASCII;HMI_Text_DisPtr->Start_Point.x = 370;HMI_Text_DisPtr->Start_Point.y = 365;Digit2Ascii0(engfuelrate, InPtr);HMI_Text_DisPtr->Cmd_End = HMI_CMD_END;HMI_Text_Dis_Que.Rear =(uint8_t)(HMI_Text_Dis_Que.Rear+1)%HMI_TEXTDIS_QUELEN; //进列一项}Record_Write();}///----------------------------------------------------------------------------------------------------------//Function://Param://Return://note///----------------------------------------------------------------------------------------------------------static void AMB_Process(uint8_t OutPtr, uint8_t InPtr){amb = (AMB_t *)CAN_RxQue.PDUs[OutPtr].Bits.DataField;Record_Write();}///----------------------------------------------------------------------------------------------------------//Function://Param://Return://note///----------------------------------------------------------------------------------------------------------void IC1_Process(uint8_t OutPtr, uint8_t InPtr){uint32_t engintakemanifold1temp; // 进气温度uint32_t engairinletpressure; //绝对增压压力ic1 = (IC1_t *)CAN_RxQue.PDUs[OutPtr].Bits.DataField;engintakemanifold1temp = ((uint32_t)(ic1->EngIntakeManifold1Temp)) * 100;engairinletpressure = ((uint32_t)(ic1->EngAirInletPressure)) * 200;if(HMI_Text_Dis_Que.Front !=(HMI_Text_Dis_Que.Rear+1)%HMI_TextDIS_QUELEN) //目的队列未满,可入列{HMI_Text_DisPtr = HMI_Text_Dis_Que.HMI_Text_Dis +HMI_Text_Dis_Que.Rear; //指向入列项HMI_Text_DisPtr->CMD_Start = HMI_CMD_START; //写入命令头HMI_Text_DisPtr->CMD_Type = HMI_CMD_TEXTDIS_ASCII; //写入命令种类HMI_Text_DisPtr->Start_Point.x = 370; //文本显示位置x坐标HMI_Text_DisPtr->Start_Point.y = 255;if(engintakemanifold1temp<4000){engintakemanifold1temp = 4000 - engintakemanifold1temp;Digit2AsciiPos0(engintakemanifold1temp, InPtr);}else{engintakemanifold1temp = engintakemanifold1temp - 4000;Digit2Ascii0(engintakemanifold1temp, InPtr);}HMI_Text_DisPtr->CMD_End = HMI_CMD_END;HMI_Text_Dis_Que.Rear =(uint8_t)(HMI_Text_Dis_Que.Rear+1)%HMI_TextDIS_QUELEN; //进列一项}if(HMI_Text_Dis_Que.Front !=(HMI_Text_Dis_Que.Rear+1)%HMI_TEXTDIS_QUELEN) {HMI_Text_DisPtr = HMI_Text_Dis_Que.HMI_Text_Dis +HMI_Text_Dis_Que.Rear;HMI_Text_DisPtr->CMD_Start = HMI_CMD_START;HMI_Text_DisPtr->Cmd_Type = HMI_CMD_TEXTDIS_ASCII;HMI_Text_DisPtr->Start_Point.x = 590;//590HMI_Text_DisPtr->Start_Point.y = 255;Digit2Ascii0(engairinletpressure, HMI_Text_Dis_Que.Rear);HMI_Text_DisPtr->Cmd_End = HMI_CMD_END;HMI_Text_Dis_Que.Rear =(uint8_t)(HMI_Text_Dis_Que.Rear+1)%HMI_TEXTDIS_QUELEN; //进列一项}Record_Write();}///----------------------------------------------------------------------------------------------------------//Function://Param://Return://note///----------------------------------------------------------------------------------------------------------void VEP1_Process(uint8_t OutPtr, uint8_t InPtr){uint32_t batterybotentialswitched;vep1 = (VEP1_t *)CAN_RxQue.PDUs[OutPtr].Bits.DataField;batterybotentialswitched = ((uint32_t)swab16(vep1->BatteryPotentialSwitched))*5;if(HMI_Text_Dis_Que.Front !=(HMI_Text_Dis_Que.Rear+1)%HMI_TEXTDIS_QUELEN) {HMI_Text_DisPtr = HMI_Text_Dis_Que.HMI_Text_Dis +HMI_Text_Dis_Que.Rear;HMI_Text_DisPtr->Cmd_Start = HMI_CMD_START;HMI_Text_DisPtr->Cmd_Type = HMI_CMD_TEXTDIS_ASCII;HMI_Text_DisPtr->Start_Point.x = 590;HMI_Text_DisPtr->Start_Point.y = 365;Digit2Ascii1(batterybotentialswitched, InPtr);HMI_Text_DisPtr->Cmd_End = HMI_CMD_END;HMI_Text_Dis_Que.Rear =(uint8_t)(HMI_Text_Dis_Que.Rear+1)%HMI_TextDIS_QUELEN;}Record_Write();}///----------------------------------------------------------------------------------------------------------//Function://Param://Return://note///----------------------------------------------------------------------------------------------------------void EFL_P1_Process(uint8_t OutPtr, uint8_t InPtr){uint32_t engoilpressure;efl_p1 = (EFL_P1_t *)CAN_RxQue.PDUs[OutPtr].Bits.DataField;engoilpressure = ((uint32_t)(efl_p1->EngOilPressure)) * 400;if(HMI_Text_Dis_Que.Front !=(HMI_Text_Dis_Que.Rear+1)%HMI_TEXTDIS_QUELEN) //目的队列未满,可入列{HMI_Text_DisPtr = HMI_Text_Dis_Que.HMI_Text_Dis +HMI_Text_Dis_Que.Rear; //指向入列项HMI_Text_DisPtr->CMD_Start = HMI_CMD_START; //写入命令头HMI_Text_DisPtr->CMD_Type = HMI_CMD_TEXTDIS_ASCII; //写入命令种类HMI_Text_DisPtr->Start_Point.x = 145; //文本显示位置x坐标HMI_Text_DisPtr->Start_Point.y = 230; //文本显示位置y坐标Digit2Ascii0(engoilpressure, InPtr);HMI_Text_DisPtr->Cmd_End = HMI_CMD_END;HMI_Text_Dis_Que.Rear =(uint8_t)(HMI_Text_Dis_Que.Rear+1)%HMI_TEXTDIS_QUELEN; //进列一项}Record_Write();}///----------------------------------------------------------------------------------------------------------//Function://Param://Return://note///----------------------------------------------------------------------------------------------------------void LFC_Process(uint8_t OutPtr, uint8_t InPtr){uint32_t engtotalfuelused;lfc = (LFC_t *)CAN_RxQue.PDUs[OutPtr].Bits.DataField;engtotalfuelused = ((uint32_t)swab32(lfc->EngTotalFuelUsed))>>1 ;if(HMI_Text_Dis_Que.Front !=(HMI_Text_Dis_Que.Rear+1)%HMI_TextDIS_QUELEN) //目的队列未满,可入列{HMI_Text_DisPtr = HMI_Text_Dis_Que.HMI_Text_Dis +HMI_Text_Dis_Que.Rear; //指向入列项HMI_Text_DisPtr->CMD_Start = HMI_CMD_START; //写入命令头HMI_Text_DisPtr->CMD_Type = HMI_CMD_TEXTDIS_ASCII; //写入命令种类HMI_Text_DisPtr->Start_Point.x = 125; //文本显示位置x坐标HMI_Text_DisPtr->Start_Point.y = 220; //文本显示位置y坐标Digit2Ascii1(engtotalfuelused, InPtr);HMI_Text_DisPtr->Cmd_End = HMI_CMD_END;HMI_Text_Dis_Que.Rear =(uint8_t)(HMI_Text_Dis_Que.Rear+1)%HMI_TEXTDIS_QUELEN; //进列一项}Record_Write();}///----------------------------------------------------------------------------------------------------------//Function://Param://Return://note///----------------------------------------------------------------------------------------------------------CAN_EXT void FAULT_MEMORY_Process(uint8_t OutPtr, uint8_t InPtr, uint8_t Touch_flag, uint16_t num){uint16_t Fault_Type;uint8_t error1[]="安全晶体管电磁阀阵列1(高边)故障"; uint8_t error2[]="安全晶体管电磁阀阵列1(低边)故障"; uint8_t error3[]="安全晶体管电磁阀阵列3(高边)故障"; uint8_t error4[]="存储器控制错误";uint8_t error5[]="看门狗控制错误";uint8_t error6[]="处理器控制错误";uint8_t error7[]="TRAP控制错误";uint8_t error8[]="5V电压控制错误";uint8_t error9[]="12V传感器电压控制错误";uint8_t error10[]="12.5V电压控制错误";uint8_t error11[]="24V电压错误";uint8_t error12[]="nvSRAM控制错误";uint8_t error13[]="nvSRAM数据控制错误";uint8_t error14[]="CAN接口初始化错误";uint8_t error15[]="SEAJ1939协议错误";uint8_t error16[]="传感器电缆堵塞";uint8_t error17[]="温度传感器。
飞思卡尔MC9S12XEP芯片的RS485程序实例
#define RS485_GLOBALS#include "RS485.h"#include "clk.h"RS485_EXT void RS485_QUE_Int(){RS485_RXQUE_SCI1.Rear=0;RS485_RXQUE_SCI1.Front=0;RS485_RXQUE_SCI0.Rear=0;RS485_RXQUE_SCI0.Front=0;RS485_TXQUE_SCI0.Front=0;RS485_TXQUE_SCI0.Rear=0;RS485_TXQUE_SCI1.Front=0;RS485_TXQUE_SCI1.Rear=0;RS485_SCI1_Status=1;RS485_SCI0_Status=1;rs485Init( SCI0);rs485Init( SCI1);}/////////////////////////////////////////////////////////////////////////////// ///////RS485_EXT void rs485Init(uint8_t SCI){if(SCI<SCIX){switch(SCI){case SCI0:SCI0BDH = SCI0Baud_val>>8;SCI0BDL = SCI0Baud_val;SCI0CR1 = 0x00; //8个数据位无校验位SCI0CR2 = (0<<5) | (1<<3) | (1<<2);//SCI2CRC2 第5,3,2位置1 RIE TE RE break;case SCI1:SCI1BDH = SCI1Baud_val>>8;SCI1BDL = SCI1Baud_val;SCI1CR1 = 0x00; //8个数据位无校验位SCI1CR2 = (0<<5) | (1<<3) | (1<<2);//SCI4CRC2 第5,3,2位置1 RIE TE RE break;}}}/////////////////////////////////////////////////////////////////////////////// /////////功能:RS485_0发射、接收切换函数,Tx_Rx为Rx时,开启接收功能,为Tx时,开启发送功能//参数定义:Tx_Rx是用来对函数功能切换的,使输出脚电平的不同,来控制硬件的功能切换///////////////////////////////////////////////////////////////////////////////////// ////////////*/RS485_EXT void rs485_TxOrRx(uint8_t SCI,uint8_t Tx_Rx){DDR1AD0_DDR1AD07=1;DDR0AD0_DDR0AD07=1;if(SCI<SCIX){switch(SCI){case SCI0: if(Tx_Rx==1)PT1AD0_PT1AD07=1;elsePT1AD0_PT1AD07=0;break;case SCI1: if(Tx_Rx==1)PT0AD0_PT0AD07=1;elsePT0AD0_PT0AD07=0;break;}}}/*------------------------------------------------------------------------------------------功能:RS485发射函数参数定义:SCI用来选择RS485 1和0模块,array[]是要发射的数据数组名,也就是首地址。
飞思卡尔MC9S12XET256 SCI串口寄存器说明
串口寄存器说明该模块指南提供了串行通信接口(SCI)模块概述。
SCI的允许与外围设备和其他CPU异步串行通信。
1.1 SCI包括这些特征:•全双工或单线运行•标准标记/空间不归零(NRZ)格式•可选的IrDA1.4返回到零倒置(RZI)与可编程脉冲宽度格式•13位的波特率选择•可编程8位或9位数据格式•分别使能发射机和接收机•可编程极性对发射机和接收机•可编程发送器输出校验•两个接收器唤醒的方法:-唤醒空闲线- 地址标志唤醒•中断驱动的操作有八个标志:-发送器空- 传输完成- 接收器满- 空闲接收器输入- 接收器溢出-噪声误差-帧错误- 奇偶错误- 接收有效边缘唤醒- 发送冲突检测支持LIN-间隔检测支持LIN•接收帧错误检测•硬件奇偶校验•1 / 16位时间噪声检测1.2 操作模式SCI的功能相同在正常、特殊和仿真模式。
它有两种低功耗模式,等待和停止模式。
•运行模式•等待模式•停止模式1.3 寄存器说明1、波特率控制寄存器(SCIBDH、SCIBDL)SCIBDH和SCIBDL一起构成了一个16位的波特率控制寄存器。
SBR12~~SBR0为波特率常数。
IREN:红外调制模式使能位1 使能0 禁止TNP[0..1]:窄脉冲发射位,这些位使能SCI是否能发送一个1 / 16,3 /16,1/ 32或1 / 4的窄脉冲。
见表20-3。
SBR[0..12]:波特率设置位When IREN = 0 then,SCI baud rate = SCI bus clock / (16 x SBR[12:0])When IREN = 1 then,SCI baud rate = SCI bus clock / (32 x SBR[12:1])【说明】波特率发生器在复位后是禁止的,在设置TE、RE(在SCICR2寄存器中)后才会工作。
当(SBR[12:0] = 0 and IREN = 0) 或者(SBR[12:1] = 0 andIREN = 1),波特率发生器不工作。
如何快速读懂并理解MC9S12XE系列的编程手册
如何快速读懂并理解MC9S12XE系列的编程手册在现今的经济社会,比拼的“快”不仅仅是速度快,更是效率高。
身处社会分工细致的今天,让自己更快效率更高是有方法的。
每一家MCU产商都会提供他们生产的MCU型号的datasheet,Reference Manual等各种说明手册。
这对于从事电子软件开发的人员来说,这是他们的第一手资料,也是他们最重要的参考资料,他们所有的软件设计工作都是参考手册上的内容,比如,硬件工程师可能比较在乎芯片的电气特性;MCU应用工程师关注外设,编程器时序开发人员则比较注重去理解Flash Module,在工作中他们要仔细并反复阅读他们所关注的部分。
最近则频繁的收到飞思卡尔芯片烧录不良的反馈,而且最多的集中在MC9S12XE这个系列上。
MC9S12XEP100这款飞思卡尔芯片跟平时我们所遇到的芯片相比有些特殊。
首先,它的Flash包括以下三部分:一、1MB的P-flash(Program Flash),非易失性代码存储器;二、32KB的D-flash(Data Flash),我们可以把它当作EEPROM;三、4KB的Buffer RAM。
其次,它三部分Flash特殊的地方:1)三部分Flash各部分分别映射在global Map的不同部分,并不是连续的。
所以对于所有的编写程序的工程师来说,要实现Flash Operations,首先要正确实现Flash Module 各部分的地址映射。
下图就是简单的一个映射说明:2)4KB的Buffer RAM。
虽然它就是一个RAM,但是它比较特殊,因为它的每次修改都会转储到D-Flash的一个分区中,每次上电会将该分区的内容自动加载到Buffer RAM中,所以它就是一个下电不丢失数据的RAM,我们就把它当作一个EEPROM。
MCU批量生产时的编程主要包括以下几部分,这里特别提醒做项目的工程师,烧录芯片是非常关键的,因为他包含了对整个MCU的Flash进行操作和加密:1)Flash 操作(编程、擦除、校验等)由于Buffer Ram的存在使得要实现Flash操作配置变得难度加大,因为对Buffer Ram的任何操作,最终都要更新到D-flash中的EEP中,所以在对Buffer Ram操作之前要对D-flash进行分区,分成D-flash和EEP两部分。
基于MC9S12XEP100的整车控制器CANBootLoader设计与实现
( 1 .北京 理工 大学电动车辆 国家工程实验室 ,北京 1 0 0 0 8 1 ;2 .北京蓝天海科清洁能源技术有 限公 司 ,北京 1 0 2 2 0 6 )
摘
要 :为 了避免 因 使用 传 统 B D M 工 具进 行 下 载应 用 程序 带 来 的不 便 ,基 于 飞思 卡 尔 S 1 2 X系 列 微 控制 器
MC 9 S 1 2 X E P 1 0 0 ,设计并实现 了一个应 用于整车控制器上 的 C A N B o o t L o a d e r .该 B o o t L o a d e r 可以通过 进行 简单 的 配置修改而应用于其他 的 S 1 2 X系列微控制器.实验结 果表 明 :B o o t L o a d e r 能正确 引导程序 运行 ,准确 、方 便地
Ve h i c l e Co n t r o l Un i t Ba s e d o n M C9 S 1 2 XEP1 0 0
Y ANG J i n g . z h e , W AN G Z h i . f u , L I U J i e
( 1 .t h e N a t i o n a l L a b o r a t o r y f o r E l e c t r i c V e h i c l e s , B e i j i n g I n s t i t u t e o f t e c h n o l o g y , B e i j i n g , 1 0 0 0 8 1 ,C h i n a ;2 .B e i j i n g B l u e S k y H a r t c o u r t C l e a n E n e r y g T e c h n o l o y g L t d .C o . , B e i j i n g , 1 0 2 2 0 6 ,C h i n a )
基于飞思卡尔MC9S12XE系列单片机的汽车电子车身控制器硬件自动化设计
要 求 填 写 输 入 输 出信 息表 ,就 可 以 自动 生 成 满 足功 能 的 电路 原 理 图。根据 汽 车 电子 行 业 的特 点 ,将 自动 化 硬 件 设 计 向 更 为 专 业 化 的 方 向进 一 步 尝试 , 目标 是 能创 建 一 个 能 够 满 足 各 种 实际 负 载和 功 能 需 求 , 并且 在 成 本 上较 为优 化 的 专 业性 平 台 型 软件 。 关键 词 : 单 片机 ; 汽 车 电子 ; 自动化 设 计 ;硬 件 设 计 中图 分 类 号 : T P 3 1 1 文献 标 志码 :A
Mi c r o c o mp u t e r A p p l i c a t i o n s V o 1 . 2 9 . N o . 1 1 . 2 0 1 3
文章编号 :1 0 0 7 . 7 5 7 X( 2 0 1 3 ) 1 1 - 0 0 4 9 - 0 2
开 发应 用
微 型 电脑 应 用
2 0 1 3 年第 2 9 卷第 1 1 期
基 于 飞思 卡 尔 MC 9 S 1 2 X E系 列 单 片机 的汽 车 电子 车 身 控 制 器 硬 件 自动 化 设 计
刘继阳 路 林 吉
摘 要 : 旨在 介 绍 一 种 汽 车 电子行 业 的硬 件 自动化 设 计 软 件 ,主 要 用 于 汽 车 车 身控 制 系统 。使 用 者 只 要 明确 系统 需 求 ,按 照
” i
0
I _
… _ … 一_
环境 ,电路硬什 的 自动化 设计只能针对某 一 行业或者应用 ,
并 大 部 分针 对 的 足 局 部 电路 拓 扑 。 本 文 的 土 要 电子的 自动化硬什设计软什 , 在产 品的系
mc9s12xs128的SPI通信的读写讲课教案
m c9s12x s128的S P I 通信的读写#include <hidef.h>#include "derivative.h"uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};byte a;void delay(word z) //延时函数{byte x,y;for(z;z>0;z--)for(x=110;x>0;x--)for(y=25;y>0;y--);}void crg_init(void) //总线时钟调整{CLKSEL=0; //bus=2*16M*(2+1)/(1+1)PLLCTL_PLLON=1;SYNR=0x00|0x01;REFDV=0x80|0x01;POSTDIV=0X00;while(!(CRGFLG_LOCK)); //总线频率为24mCLKSEL_PLLSEL=1;}void SPI_int(void) // SPI初始化{MODRR_MODRR4=1; //使用PM口SPI0CR1=0x5e; //中断禁止主机模式时钟空闲为高先发最高位 }void init(){DDRB=0xff;DDRM=0xff; //选择M口的接口我做实验时犯的低级错误 }void send_data(word data) //写一个字节{PTM_PTM3=0; //M口的第三引脚为低SPI0DR=data; //将数据写入移位寄存器while(!(SPI0SR&0x20)); //等数据发完}uchar read(void) //SPI读一个字节{while(!(SPI0SR_SPIF)); //检测传输是否完成return SPI0DRL; //读数据并返回while(SPI0SR_SPIF==0); //清除该位为下次读数据做准备}void main(void){init();crg_init();SPI_int();EnableInterrupts;for(;;){a++;if(a==10)a=0;// a=read();send_data(a); //发送a的值PORTB=table[a]; //在数码管上显示a的植delay(1000); //延时1秒左右}}。
基于MC9S12XEP100的BootLoader设计与实现
10.16638/ki.1671-7988.2018.17.063基于MC9S12XEP100的BootLoader设计与实现王志强(天津职业技术师范大学汽车与交通学院车辆系,天津300000)摘要:程序的引导加载功能已是汽车电控单元中必不可少的部分,基于飞思卡尔16位处理器MC9S12XEP100,采用CAN总线技术,设计了一种BootLoader。
介绍了BootLoader的实现方法,包括底层驱动构成、引导机制设计、诊断模块设计、存储模块设计以及FLASH安全机制设计等。
实验结果表明,BootLoader能够正确引导程序运行,方便准确的进行控制器软件升级。
关键词:CAN总线;Flash模块;BootLoader;电控单元;安全机制中图分类号:U462.2 文献标识码:B 文章编号:1671-7988(2018)17-190-04Design and implementation of BootLoader base on MC9S12XEP100Wang Zhiqiang( Tianjin V ocational and Technical Normal University, School of Automobile and Transportation, Tianjin 300000 )Abstract: Bootloader function is one of the essential function of embedded system. A BootLoader is designed based on the 16-bit Freescale MCU MC9S12XEP100 and CAN bus. And the application of Bootloader is introduced, which includes driver module design, diagnostic module design, BOOT method design, memory module design, and Flash protected design. Experimental results show that Bootloader could boot the application accurately, downloads and upgrades correctly. Keywords: CAN bus; BootLoader; FLASH Module; ECU; SafetyCLC NO.: U462.2 Document Code: B Article ID: 1671-7988(2018)17-190-041 引言汽车电子电控单元ECU的开发周期较长,并且汽车电子产品开发对安全性、可靠性的指标要求很高。
飞思卡尔单片机 MC9S12 单片机应用系统开发平台下实时操作
计算机方向嵌入式计算机应用正在计算机领域迅速崛起,虽然该技术还不很成熟,但是它 的应用已经深入到社会各个领域,像办公自动化、民用消费品、计算机外设、机器人和武 器系统等等。
嵌入式系统,属于电子系统,包括微处理器或微控制器,嵌入式系统不是一般的计算 机,是隐藏或嵌入在各种系统中的计算机。主要用于控制领域,兼顾数据处理。而微控制 器即 MCU,MCU 的基本含义,在一片芯片上集成了中央处理单元(cpu)、存储器(RAM/ROM 等)、 定时器/计数器及多种输入\输出(I/O)接口的比较完整的数字处理系统。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#define SPI_GLOBALS#include "spi.h"#define Write_To_FlashDataSize 15static uint8_t Dummy;//选中flashvoid SPICSLow(uint8_t Chip){if(Chip == 0){SPI_FLASH1_CS_LOW();//选中flash1}else{SPI_FLASH2_CS_LOW();//选中flash2}}//不选void SPICSHigh(uint8_t Chip){if(Chip == 0){SPI_FLASH1_CS_HIGH(); //不选中flash1}else{SPI_FLASH2_CS_HIGH(); //不选中flash2}}//flash 写使能void SPIWriteEnable(uint8_t Chip){SPICSLow(Chip); //bring the chosen chip's CS pin downDummy=SPIReadWriteByte(SPI2, SPI_CMD_WREN); //write Write_Enable command SPICSHigh(Chip); //bring the chosen chip's CS pin high}//flash 写除能void SPIWriteDisable(uint8_t Chip){SPICSLow(Chip); //bring the chosen chip's CS pin downDummy = SPIReadWriteByte(SPI2, SPI_CMD_WRDI); //write Write_Disable commandSPICSHigh(Chip); //bring the chosen chip's CS pin down}//SPI初始化void SPIInit(void){DDRP_DDRP0 = 1;DDRP_DDRP1 = 1;DDRP_DDRP2 = 1;DDRP_DDRP3 = 1;SPI_WP1_OFF();SPI_WP2_OFF();SPI_FLASH1_CS_HIGH();SPI_FLASH2_CS_HIGH();SPI2BR = (0<<4) | (0); //(0+1)*2^(0+1) = 2, 20M/2 = 10MSPI2CR1 = 0x50; //主机模式}//SPI读flash的IDSPI_EXT uint16_t SPIReadID(uint8_t Chip){uint16_t ID;SPICSLow(Chip); //bring the chosen chip's CS pin downDummy = SPIReadWriteByte(SPI2, SPI_CMD_RDID); //write the Read_ID commandDummy = SPIReadWriteByte(SPI2, 0x00); //write Addr[16:23] //写24位地址Dummy = SPIReadWriteByte(SPI2, 0x00); //write Addr[8:15]Dummy = SPIReadWriteByte(SPI2, 0x00); //write Addr[0:7]((uint8_t *)&ID)[0] = SPIReadWriteByte(SPI2, SPI_CMD_DUMMY);//manufacturer ID((uint8_t *)&ID)[1] = SPIReadWriteByte(SPI2, SPI_CMD_DUMMY); //device IDSPICSHigh(Chip); //bring the chosen chip's CS pin highreturn ID; //return the ID value}// SPI 读flash状态uint8_t SPIReadSta(uint8_t Chip){uint8_t Sta;SPICSLow(Chip); //bring the chosen chip's CS pin downDummy = SPIReadWriteByte(SPI2, SPI_CMD_RDSR); //write the Read_Status commandSta = SPIReadWriteByte(SPI2, SPI_CMD_DUMMY); //statusSPICSHigh(Chip); //bring the chosen chip's CS pin highreturn Sta; //return the status value}// 等待芯片空闲(在执行Byte-Program,Sector-Erase,Block-Erase,Chip-Erase 操作后void SPIWaitBusy(uint8_t Chip){SPICSLow(Chip);while ((SPIReadSta(Chip) & 0x01) == 0x01); // waste time until not busy}///----------------------------------------------------------------------------------------------------------//Function: SPIFlash 初始化//Param://Return://note///----------------------------------------------------------------------------------------------------------SPI_EXT void SPIFlashInit(void){uint8_t i;uint16_t ID;SPIInit();// memset(SPI_Flash_Info, 0, sizeof(SPI_Flash_Info));//for(i = 0; i < SPI_MAX_CHIPS; i++){ID = SPIReadID(i);SPI_Flash_Info[i].DeviceID = ID;SPI_Flash_Info[i].Size = (uint32_t)8*1024*1024;SPI_Flash_Info[i].SectorSize = 4*1024;SPI_Flash_Info[i].SectorPages = 16;SPI_Flash_Info[i].BlockSize = (uint32_t)64*1024;SPI_Flash_Info[i].Blocks = 128;SPI_Flash_Info[i].PageSize = 256;SPI_Flash_Info[i].Pages = 65536;}}/*--------------------------------------------------------------------------------------------------------SPI 收发送函数----------------------------------------------------------------------------------------------------------*/SPI_EXT uint8_t SPIReadWriteByte(uint8_t SPI, uint8_t Data){if(SPI<SPIS)switch(SPI){case SPI0: while(SPI0SR_SPTEF==0);SPI0DRL = Data;while(SPI0SR_SPIF==0);return SPI0DRL;break;case SPI2: while(SPI2SR_SPTEF==0);SPI2DRL = Data;while(SPI2SR_SPIF==0);return SPI2DRL;break;}}///----------------------------------------------------------------------------------------------------------//Function: 把Chip号芯片的Adress位置开始Len长度的数据读取到Buf中//Param://note///----------------------------------------------------------------------------------------------------------SPI_EXT void SPIRead(uint8_t Chip, uint32_t Address, uint8_t *Buf, uint32_t Len) {uint32_t i;SPIWaitBusy(Chip); //判忙SPICSLow(Chip); //bring the chosen chip's CS pin downDummy =SPIReadWriteByte(SPI2, SPI_CMD_READ); //write Fast_Read command Dummy =SPIReadWriteByte(SPI2, ((uint8_t *)&Address)[0]); //write Addr[16:23]Dummy =SPIReadWriteByte(SPI2, ((uint8_t *)&Address)[1]); //write Addr[8:15]Dummy =SPIReadWriteByte(SPI2, ((uint8_t *)&Address)[2]); //write Addr[0:7]for(i = 0; i < Len; i += 1){Buf[i] =SPIReadWriteByte(SPI2, SPI_CMD_DUMMY); //read data }SPICSHigh(Chip); //bring the chosen chip's CS pin high}///----------------------------------------------------------------------------------------------------------//Function: 向chip号芯片的Address位置开始的区域写入长度为Len的Buf内容//Param://Return://note///----------------------------------------------------------------------------------------------------------SPI_EXT void SPIWritePage(uint8_t Chip, uint32_t Address, uint8_t Buf[], uint32_t Len){uint8_t i;SPIWriteEnable(Chip);SPICSLow(Chip); //bring the chosen chip's CS pin downDummy = SPIReadWriteByte(SPI2, SPI_CMD_BYTE_WRITE); //write Byte_Write commandDummy = SPIReadWriteByte(SPI2, ((uint8_t *)&Address)[0]); //writeDummy = SPIReadWriteByte(SPI2, ((uint8_t *)&Address)[1]); //writeAddr[8:15]Dummy = SPIReadWriteByte(SPI2, ((uint8_t *)&Address)[2]); //writeAddr[0:7]for(i=0; i<Len; i+=1){Dummy = SPIReadWriteByte(SPI2, Buf[i]); //write the data to besent}SPICSHigh(Chip); //bring the chosen chip's CS pin highSPIWaitBusy(Chip); //判忙}///----------------------------------------------------------------------------------------------------------//Function: 擦除flash一个sector//Param://Return://note///----------------------------------------------------------------------------------------------------------SPI_EXT void SPIEraseSector(uint8_t Chip, uint32_t Address){SPIWriteEnable(Chip); //write enableSPIWaitBusy(Chip); //判忙SPICSLow(Chip); //bring the chosen chip's CS pin downDummy = SPIReadWriteByte(SPI2, SPI_CMD_4K_ERASE); //write 4K_Erasecommand Dummy = SPIReadWriteByte(SPI2, ((uint8_t *)&Address)[0]); //writeAddr[16:23]Dummy = SPIReadWriteByte(SPI2, ((uint8_t *)&Address)[1]); //writeAddr[8:15]Dummy = SPIReadWriteByte(SPI2, ((uint8_t *)&Address)[2]); //writeAddr[0:7]SPICSHigh(Chip); //bring the chosen chip's CS pin highSPIWriteDisable(Chip);SPIWaitBusy(Chip); //判忙}///----------------------------------------------------------------------------------------------------------//Function: 擦除flash一个block//Param://Return://note///----------------------------------------------------------------------------------------------------------SPI_EXT void SPIEraseBlock(uint8_t Chip, uint32_t Address){SPIWriteEnable(Chip);SPIWaitBusy(Chip); //判忙SPICSLow(Chip); //bring the chosen chip's CS pin downDummy = SPIReadWriteByte(SPI2, SPI_CMD_64K_ERASE); //write 64K_Erase commandDummy = SPIReadWriteByte(SPI2, ((uint8_t *)&Address)[0]); //write Addr[16:23]Dummy = SPIReadWriteByte(SPI2, ((uint8_t *)&Address)[1]); //write Addr[8:15]Dummy = SPIReadWriteByte(SPI2, ((uint8_t *)&Address)[2]); //write Addr[0:7]SPICSHigh(Chip); //bring the chosen chip's CS pin highSPIWriteDisable(Chip);SPIWaitBusy(Chip); //判忙}///----------------------------------------------------------------------------------------------------------//Function: 擦除flash整片芯片//Param://Return://note///----------------------------------------------------------------------------------------------------------SPI_EXT void SPIEraseChip(uint8_t Chip){SPIWriteEnable(Chip);SPIWaitBusy(Chip); //判忙SPICSLow(Chip);Dummy = SPIReadWriteByte(SPI2, SPI_CMD_CHIP_ERASE);SPICSHigh(Chip);SPIWaitBusy(Chip); //判忙SPIWriteDisable(Chip);}/*----------------------------------------------------------------------------------------------------------向SPI_FlashBuf里面写入数据------------------------------------------------------------------------------------------------------------*///SPI_EXT SPIWriteToBuf/*----------------------------------------------------------------------------------------------------------向SPI_FlashBuf里面写入数据------------------------------------------------------------------------------------------------------------*/SPI_EXT void SPIWriteToBuf(uint8_t array[],uint8_t array_len){uint8_t i;for(i=0;i< array_len;i++)SPI_FlashBuf[i] = array[i];SPI2CR1_SPIE=1;//给SPI缓冲区写完数据,打开中断,将数据写入到Flash里面。