飞思卡尔s12单片机-用C语言开发应用程序

合集下载

飞思卡尔单片机S12使用方法及程序

飞思卡尔单片机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口上去。

C语言实现控制电机加减速正反转(飞思卡尔C代码)

C语言实现控制电机加减速正反转(飞思卡尔C代码)

C语言实现控制电机加减速正反转(飞思卡尔C代码)用单片机控制直流电动机的正反转、加减速的程序如何用C语言写参考一下这个例子吧。

#include#defineucharunignedchar#defineuintunignedintbitPW1=P2^0;bitPW2=P2^1;//控制电机的两个输入bitaccelerate=P2^2;//调速按键bittop=P2^3;//停止按键bitleft=P2^4;//左转按键bitright=P2^5;//右转按键#defineright_turnPW1=0;PW2=1//顺时针转动#defineleft_turnPW1=1;PW2=0//逆向转动#defineend_turnPW1=1;PW2=1//停转uintt0=25000,t1=25000;//初始时占空比为50%uinta=25000;//设置定时器装载初值25m设定频率为20Hzucharflag=1;//此标志用于选择不同的装载初值uchardflag;//左右转标志ucharcount;//用来标志速度档位voidkeycan();//键盘扫描voiddelay(ucharz);voidadjut_peed();//通过调整占空比来调整速度//某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某//voidmain(){keycan();//不断扫描键盘程序,以便及时作出相应的响应}}if(flag){flag=0;end_turn;a=t0;//t0的大小决定着低电平延续时间TH0=(65536-a)/256;TL0=(65536-a)%6;//重装载初值}ele{flag=1;//这个标志起到交替输出高低电平的作用if(dflag==0){right_turn;//右转}ele{left_turn;//左转}a=t1;//t1的大小决定着高电平延续时间TH0=(65536-a)/256;TL0=(65536-a)%6;//重装载初值}}TMOD=0某01;//工作方式寄存器软件起动定时器定时器功能方式1定时器0TH0=(65536-a)/256;TL0=(65536-a)%6;//装载初值ET0=1;//开启定时器中断使能EA=1;//开启总中断TR0=0;}//某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某//voiddelay(ucharz)//在12M下延时z毫秒{ uint某,y;for(某=z;某>0;某--)for(y=110;y>0;y--);}//某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某//voidkeycan(){if(top==0){TR0=0;//关闭定时器0即可停止转动end_turn;} if(left==0){TR0=1;dflag=1;//转向标志置位则左转}if(right==0){TR0=1;dflag=0;//转向标志复位则右转}if(accelerate==0){delay(5);//延时消抖if(accelerate==0){ while(accelerate==0);//等待松手count++;if(count==1){t0=20000;t1=30000;//占空比为百分之60}if(count==2){t0=15000;t1=35000;//占空比为百分之70}if(count==3){t0=10000;t1=40000;//占空比为百分之80}if(count==4){t0=5000;t1=45000;//占空比为百分之90}if(count==5){count=0;}}}}功能特点:1)总线速度高达40MHz,CAN总线:3个1Mbp的CAN总线,兼容CAN2.0A/B;2)128KB程序Flah和8KBDataFlah,用于实现程序和数据存储,均带有错误校正码(ECC);3)可配置A/D:16通道模数转换器;可选8位10位和12位精度,3μ的转换时间4)内嵌MSCAN模块用于CAN节点应用,内嵌支持LIN协议的增强型SIC模块和SPI模块;5)4通道16位计数器,CRG时钟和复位发生器:锁相环、看门狗、实时中断;增强型捕捉定时器;6)出色的低功耗特性,带有中断唤醒功能的10,实现唤醒休眠系统的功能;7)通道PWM:8位8通道或16位4通道PWM,易于实现电机控制。

pwm(飞思卡尔单片机)

pwm(飞思卡尔单片机)
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
/*************************************************************/
REFDV = 0x01; //时钟分频寄存器
//锁相环产生的时钟频率f=2*foscclk*(SYNR+1)/(REFDV+1)
//对于S12DG128 16MHz外部晶体振荡器,总线时钟为24MHz
//片内系统时钟为48MHz
while((CRGFLG & 0x08) !=0x08); /*等待锁相环频率锁定*/
PWMPER01 = 5000; //通道01的周期为4Hz
PWMPER23 = 5000; //通道23的周期为1Hz
PWMDTY01 = 3500; //通道01的占空比为70%
PWMDTY23 = 1500; //通道23的占空比为70%
PWME_PWME1 = 1; //使能通道01
PWME_PWME3 = 1; //使能通道23
}
void main(void) {
DisableInterrupts;
MCUInit();
init_pwm();
DDRB=1;
PORTB=1;
EnableInterrupts;
foபைடு நூலகம்(;;)
{
}
}
void init_pwm(void)
{
PWMCTL_CON01= 1; //联结通道0,1为16位的PWM

FreeScale_HCS12系列单片机教程(dg128)

FreeScale_HCS12系列单片机教程(dg128)

HCS12微控制器系列教程---第一讲:PWM 模块介绍该教程以MC9S12DG128单片机为核心进行讲解,全面阐释该16位单片机资源。

本文为第一讲,开始介绍S12 MCU的PWM模块。

PWM 调制波有8 个输出通道,每一个输出通道都可以独立的进行输出。

每一个输出通道都有一,一个周期控制寄存器和两个可供选择的时钟源。

每一个PWM 输出个精确的计数器(计算脉冲的个数)通道都能调制出占空比从0—100% 变化的波形。

PWM 的主要特点有:1、它有8 个独立的输出通道,并且通过编程可控制其输出波形的周期。

2、每一个输出通道都有一个精确的计数器。

3、每一个通道的PWM 输出使能都可以由编程来控制。

4、PWM输出波形的翻转控制可以通过编程来实现。

5、周期和脉宽可以被双缓冲。

当通道关闭或PWM计数器为0时,改变周期和脉宽才起作用。

6、8 字节或16 字节的通道协议。

,他们提供了一个宽范围的时钟频率。

7、有4 个时钟源可供选择(A、SA、B、SB)8、通过编程可以实现希望的时钟周期。

9、具有遇到紧急情况关闭程序的功能。

10、每一个通道都可以通过编程实现左对齐输出还是居中对齐输出。

HCS12微控制器系列教程---第二讲:PWM 寄存器简介1、PWM启动寄存器PWMEPWME 寄存器每一位如图1所示:复位默认值:0000 0000B图1 PWME 寄存器每一个PWM 的输出通道都有一个使能位PWMEx 。

它相当于一个开关,用来启动和关闭相应通道的PWM 波形输出。

当任意的PWMEx 位置1,则相关的PWM输出通道就立刻可用。

用法:PWME7=1 --- 通道7 可对外输出波形PWME7=0 --- 通道7 不能对外输出波形注意:在通道使能后所输出的第一个波形可能是不规则的。

当输出通道工作在串联模式时(PWMCTL寄存器中的CONxx置1),那么)使能相应的16位PWM 输出通道是由PWMEx的高位控制的,例如:设置PWMCTL_CON01 = 1,通道0、1级联,形成一个16位PWM 通道,由通道1 的使能位控制PWM 的输出。

2011年飞思卡尔比赛程序

2011年飞思卡尔比赛程序

#include <hidef.h> /* common defines and macros */#include <mc9s12dg128.h> /* derivative information //引用头文件,通过该头文件将单片机的各寄存器转换为相对应的C语言的变量名*/#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"#define mid_direction 147 //设置舵机中间位置的占空比#define right_direction 0 //设置直线路程时的相对中间位置的变化量#define micro_direction 12 //设置转小弯时舵机相对中间位置的变化量#define deep_direction 19 //设置转大弯时舵机相对中间位置的变化量#define emergence_direction 22 //设置紧急情况时舵机转向#define direct_speed 14 //设置直线时输出到电机的占空比从而控制电机转速#define micro_speed 13 //设置小弯时电机转速#define deep_speed 11 //设置大弯时电机转速#define emergence_speed 10 //设置紧急情况时电机转速#define inter 5#define inter1 500 //通过设置该参数数值来调节每次采集轮速传感的脉冲时间#define speed_keep 0.4 //为轮速的比例因子,因使用效果不好最后取消使用#define speed_kd 0.1#define kp 0.5//#define kd 1.3 //下列的全局变量的设定,是为了在小车冲出赛道后仍能记住返回而设int turn_symbol; //转向标志,在信号分析程序中设置1时为向右转为-1时向左转float memory_direction; //记忆上次转向unsigned char signal;int error; //定义转向本次与中间位置的偏差int last_error; //定义上次转向与中间位置的偏差int mem_error; //记忆上次转向偏差int speed;int speed1;float kd;float speed_error;float speed_last_error;int speed_back; //轮速反回脉冲数int stop_symbol; // 停车标志int flag;void PLL_init(void) // 系统时钟的初始化,因当时摸索欠考虑,时钟初始化比较乱,需要改进{CLKSEL_PLLSEL=0; //选定外部时钟,为1时选择锁相环时钟时钟选择寄存器初始化CLKSEL=0 ; //选择外部晶振为时钟源PLLCTL_PLLON=0; //锁相环电路禁止;PLLCTL_PRE=1; //实时中断允许PLLCTL_PCE=1; //允许看门狗PLLCTL_AUTO=1; //选择高频宽带控制PLLCTL_SCME=1; //探测到外部时钟失效时产生自给时钟信号SYNR=8; //时钟合成寄存器初始化REFDV=0X07; //时钟分频寄存器初始化与上句为做实验时确定的参数与理论参数有差距,可重新设置//CLKSEL_PLLSEL=1 ; //选定锁相环时钟此句被注解掉PLLCTL_CME=1; //时钟监控允许锁相环控制寄存器初始化PLLCTL_PLLON=1;while(!CRGFLG_LOCK);//循环直到该位为1即时钟频率已稳定,CLKSEL_PLLSEL=1; //选定锁相环时钟}void PORTAB_init(void) //信号输入输出口的设置,较简单{DDRA=0X00; //设置A口输入 DDR寄存器置0为输入,置1为输出DDRB=0XFF;//设置B口为输出,作为信号指示PORTB=0X00;//初始化时设置为全亮,0亮1灭}void PWM_init(void) //脉宽调制模块的初始化。

飞思卡尔智能车程序代码

飞思卡尔智能车程序代码
#define sciflag 1;
#define flag 1;
extern uchar cflag;
extern int i,j,m,n;
extern byte cs[40][60];
/*-----------------------*/
/*-------初始化----------*/
void InputInit(){
#pragma TRAP_PROC
void IRQ_ISR()
{
TIE_C1I=1; ;
//DDRB=0XFF;
//PORTB=0XF0;
//while(1);
i=0;
j=0;
}
#pragma CODE_SEG DEFAULT
#pragma CODE_SEG NON_BANKED
#pragma TRAP_PROC
TIE_C1I=0 ; //channel 0 interrupt DISable
TIOS_IOS1=0 ; //channel 0 input capture
TCTL4_EDG1A=1;
TCTL4_EDG1B=0;
}
/*-----------------------*/
/*--中断初始化--------------------*/
void init_IRQ() {
INTCR_IRQE=1; // IRQ select edge sensitive only
INTCR_IRQEN=1; // external IRQ enable
}
/*------ADT初始化--------------*/
void ADCInit(void)
void linenihe(void);

飞思卡尔MC9S12XEP芯片的CAN总线代码

飞思卡尔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[]="温度传感器。

单片机原理及应用-S12X单片机的结构与组成

单片机原理及应用-S12X单片机的结构与组成

单片机原理及应用-S12X单片机的结构与组成单片机原理及应用S12X 单片机的结构与组成在当今的电子技术领域,单片机的应用可谓无处不在。

从智能家居到工业控制,从汽车电子到医疗设备,单片机都扮演着至关重要的角色。

其中,S12X 单片机以其出色的性能和独特的结构组成,在众多单片机中脱颖而出。

S12X 单片机是飞思卡尔(现恩智浦)推出的一款高性能 16 位单片机。

它采用了增强型的 HCS12 内核,相较于传统的 8 位单片机,具有更强的处理能力和更丰富的功能。

从硬件结构上看,S12X 单片机主要由以下几个部分组成:1、中央处理器(CPU):这是单片机的核心,负责执行指令和进行数据处理。

S12X 的 CPU 采用了 16 位的架构,具有较高的运算速度和处理能力。

2、存储器:包括程序存储器(Flash 或 ROM)和数据存储器(RAM)。

程序存储器用于存储用户编写的程序代码,而数据存储器则用于存储运行过程中的临时数据。

S12X 单片机通常具有较大的存储空间,以满足复杂应用的需求。

3、输入/输出(I/O)端口:用于与外部设备进行数据交换。

这些端口可以配置为不同的工作模式,如输入、输出、高阻态等,以适应各种接口需求。

4、定时器/计数器:用于实现定时、计数和脉冲宽度调制(PWM)等功能。

S12X 单片机通常配备多个定时器/计数器,以满足不同的定时和计数需求。

5、串行通信接口:如SCI(串行通信接口)、SPI(串行外设接口)和 IIC(集成电路间总线)等,用于与其他设备进行串行数据通信。

6、模数转换器(ADC):用于将模拟信号转换为数字信号,以便单片机进行处理。

7、脉宽调制模块(PWM):可以生成不同占空比的脉冲信号,用于控制电机、灯光等设备。

在软件方面,S12X 单片机通常使用特定的开发工具和编程语言进行编程。

常见的编程语言有 C 语言和汇编语言。

开发人员可以使用这些语言编写程序,并通过下载工具将程序烧录到单片机的存储器中。

飞思卡尔S12xs128单片机BDM调试器使用技巧

飞思卡尔S12xs128单片机BDM调试器使用技巧

S12(X)单片机BDM调试器使用技巧第五届全国大学生“飞思卡尔”杯智能气车竞赛限制采用最新的MC9S12XS128(以下简称XS128)单片机作为主控芯片,替代MC9S12DG128。

XS128是Freescale公司推出的S12系列单片机中的一款增强型16位单片机。

片内资源丰富,接口模块有SPI、SCI、IIC、A/D、PWM等常见模块,在汽车电子应用领域具有广泛用途。

XS128和以往大赛使用的S12DG128系列单片机一样,调试接口都是使用Freescale公司传统的BD M(Background Debug Module)接口。

1 MC9S12XS128单片机介绍(1)CPU:增强型16位HCS12 CPU,片内总线时钟最高40 MHz;(2)片内资源:8 KB RAM、128 KB程序闪存、2 KB数据闪存;(3)串行接口模块:SCI、SPI;(4)脉宽调制模块(PWM)可设置成4路8位或者2路16位,逻辑时钟选择频率宽;(5)1个16路12位精度A/D转换器;(6)控制器局域网模块(CAN);(7)增强型捕捉定时器。

MC9S12XS128单片机有112、80和64引脚3种封装形式。

80-pin封装的单片机没有引出用于扩展方式的端口,仅引出了一个8路A/D接口。

竞赛可使用112或80引脚封装器件。

2 BDM接口和使用BDM调试器内部有一个8位的MC9HC08JB16单片机,该单片机有USB接口,可与PC 机信息交互。

HC08单片机和S12单片机间仅使用一根 I/O线通信,这根相连的信号线名为BKGD。

HC08单片机将BKGD置为输出,以串行发送命令,发送完成后转为输入,以接收信息。

S12单片机收到命令后转为输出,根据调试器发来的命令回送信息,然后立即转入接收态。

BDM工具以此方式实现S12单片机的在线调试、内部闪存的烧写等功能。

关于BDM接口的实现,读者可以参考Freescale任何一款S12单片机的器件手册,其对BDM接口的命令字、交互模式等都有详细描述。

飞思卡尔开发套件使用文档

飞思卡尔开发套件使用文档

H C S12开发工具包介绍一、HCS12微控制器简介HCS12(以下简称DP256)是Motorola新推出的高性能16位微控制器,具有强大的功能和广阔的市场前景。

HCS12单片机系列提供由32K-512K第三代快闪嵌入式存储器。

每一个HCS12单片机总线速度可达50 MHz, 外围时钟可以到25MHZ。

还具备编码效益、片上纠错能力,并与摩托罗拉68HC11和68HC12结构编码兼容。

二、HCS12开发工具包组件1、HCS12开发工具包硬件系统包括以下组件:z MC9S12DP256(兼容所有HCS12 D系列112pin封装的单片机)开发子板一块z BDM调试器一个z监控程序(可实现单板调试)z编程开发工具串口通讯线一根z标准5V电源一个以下先介绍BDM调试器的使用方法,再介绍利用监控程序实现单板调试的方法,最后介绍这套开发工具如何和codewarrior配合使用。

BDM调试器使用方法1.插上5V电源2.和PC机间用普通串口线相连3.配置超级终端首先打开超级中断开始-→程序-→附件-→通讯-→超级终端选择Hypertrm填入名称,这里用MC9S12DP256。

选择“确定”如果开发板是连接到串口1,就选“直接连接到串口1”,如果开发板连接到串口2,就选“直接连接到串口2”。

选择“确定”串口设置如下:选择“确定”按BDM头上的SW-PB复位键会看到以下内容此时BDM头还没有跟目标板相连。

这几个选项意义如下:1设定目标板的工作频率。

我们的目标板使用的是16M无源晶振。

选1后输入16000。

2让目标板复位3重新连接4擦除flash并解开密码锁(S12系列单片机有flash密码锁)5此选项不要选用户设定1为16000KHZ后,把BDM头6针插针和开发板的BDMIN 6针插座相连。

注意数据线红色一端靠近开发板BDMIN 的1。

此时BDM调试器给目标板供电。

回车,进入BDM调试器控制界面。

再次按BDM调试器的SW-PB可见到如下欢迎画面。

飞思卡尔单片机各种功能程序

飞思卡尔单片机各种功能程序

流水灯四种效果:#include <hidef.h> /* common defines and macros */ #include <stdlib.h>#include <mc9s12xdp512.h> /* derivative information */ #pragma LINK_INFO DERIV ATIVE "mc9s12xdp512"#include "main_asm.h" /* interface to the assembly module */ unsigned char temp;//unsigned char pa @0x200;//unsigned char pb @0x202;unsigned char key;static void delay(void) {volatile unsigned long i;for(i=0;i<100000;i++);}static unsigned char random;static void Random(void) {random = (unsigned char)rand();}void effect1() {unsigned char c;for(c=0;c<=6;c++) {delay();PORTB = ~(1<<c);}for(c=7;c>=1;c--) {delay();PORTB = ~(1<<c);}}void effect2() {unsigned char c;for(c=0;c<=6;c++) {delay();PORTB = ~(3<<c);}for(c=7;c>=1;c--) {delay();PORTB = ~(3<<c);}}void effect3() {unsigned char c,t=0xfe;for(c=0;c<=7;c++) {PORTB = t;delay();t<<=1;}}void effect4() {unsigned char c,t=0;for(c=0;c<=7;c++) {PORTB=t;delay();t = (t<<1)+1;;}}void main(void) {unsigned char x;DDRA=0xf0;DDRB=0xff;for(;;) {x=PORTA&0x03;switch(x) {case 0:effect1(); break;case 1:effect2(); break;case 2:effect3(); break;case 3:effect4(); break;}}/* wait forever *//* please make sure that you never leave this function */ }//行列反转法unsigned char key_scan() //键盘扫描函数{ unsigned char x,row=4,col=4,key=16;PUCR|=0x01; //等同于PUCR=PUCR|0x01,PUCR寄存器的第0位设置为1,即允许PORTA端口的上拉电阻。

飞思卡尔单片机编程

飞思卡尔单片机编程

关于Codewarrior 中的 .prm 文件网上广泛流传的一篇文章讲述的是8位飞思卡尔单片机的内存映射,这几天,研究了一下Codewarrior 5.0 prm文件,基于16位单片机MC9S12XS128,一点心得,和大家分享。

有什么错误请指正。

正文:关于Codewarrior 中的.prm 文件要讨论单片机的地址映射,就必须要接触.prm文件,本篇的讨论基于Codewarrior 5.0 编译器,单片机采用MC9S12XS128。

通过项目模板建立的新项目中都有一个名字为“project.prm”的文件,位于Project Settings->Linker Files文件夹下。

一个标准的基于XS128的.prm文件起始内容如下:.prm文件范例:NAMESENDSEGMENTSRAM = READ_WRITE DATA_NEAR 0x2000 TO 0x3FFF;ROM_4000 = READ_ONLY DATA_NEAR IBCC_NEAR 0x4000 TO 0x7FFF;ROM_C000 = READ_ONLY DATA_NEAR IBCC_NEAR 0xC000 TO 0xFEFF; //OSVECTORS = READ_ONLY 0xFF10 TO 0xFFFF;EEPROM_01 = READ_ONLY DATA_FAR IBCC_FAR 0x010800 TO 0x010BFF; EEPROM_02 = READ_ONLY DATA_FAR IBCC_FAR 0x020800 TO 0x020BFF; EEPROM_03 = READ_ONLY DATA_FAR IBCC_FAR 0x030800 TO 0x030BFF; EEPROM_04 = READ_ONLY DATA_FAR IBCC_FAR 0x040800 TO 0x040BFF; EEPROM_05 = READ_ONLY DATA_FAR IBCC_FAR 0x050800 TO 0x050BFF; EEPROM_06 = READ_ONLY DATA_FAR IBCC_FAR 0x060800 TO 0x060BFF; EEPROM_07 = READ_ONLY DATA_FAR IBCC_FAR 0x070800 TO 0x070BFF;PAGE_F8 = READ_ONLY DATA_FAR IBCC_FAR 0xF88000 TO 0xF8BFFF; PAGE_F9 = READ_ONLY DATA_FAR IBCC_FAR 0xF98000 TO 0xF9BFFF; PAGE_FA = READ_ONLY DATA_FAR IBCC_FAR 0xFA8000 TO 0xFABFFF; PAGE_FB = READ_ONLY DATA_FAR IBCC_FAR 0xFB8000 TO 0xFBBFFF; PAGE_FC = READ_ONLY DATA_FAR IBCC_FAR 0xFC8000 TO 0xFCBFFF;ENDPLACEMENT_PRESTART,STARTUP,ROM_VAR,STRINGS,VIRTUAL_TABLE_SEGMENT,//.ostext,DEFAULT_ROM, NON_BANKED,COPYINTO ROM_C000 ;OTHER_ROM INTO PAGE_FE, PAGE_FC, PAGE_FB, PAGE_FA, PAGE_F9, PAGE_F8;//.stackstart,SSTACK,//.stackend,PAGED_RAM,DEFAULT_RAMINTO RAM;DISTRIBUTE DISTRIBUTE_INTOROM_4000, PAGE_FE, PAGE_FC, PAGE_FB, PAGE_FA, PAGE_F9, PAGE_F8;CONST_DISTRIBUTE DISTRIBUTE_INTOROM_4000, PAGE_FE, PAGE_FC, PAGE_FB, PAGE_FA, PAGE_F9, PAGE_F8;DATA_DISTRIBUTE DISTRIBUTE_INTORAM;//.vectors INTO OSVECTORS;ENDENTRIES//_vectab OsBuildNumber _OsOrtiStackStart _OsOrtiStartENDSTACKSIZE 0x100VECTOR 0 _Startup//VECTOR 0 Entry//INIT Entry1 .prm文件组成结构按所含的信息的不同.prm文件有六个组成部分构成,这里仅讨论和内存空间映射关系紧密的三个部分,其他的不做讨论。

飞思卡尔单片机 MC9S12 单片机应用系统开发平台下实时操作

飞思卡尔单片机 MC9S12 单片机应用系统开发平台下实时操作
But be necessary in this saying an once implanting dyadic system , its belonging to electron system , include the microprocessor or tiny controller, people does not look upon to implanting dyadic system as the same computer , they are computer in concealing or implanting in various system. Be used to control a field , be given consideration to data handling mainly. But tiny controller is MCU , fundamental MCU import, comparatively entire digital handling system going to integrated central authority treatment element (cpu) , memory (RAM/ROM waits) , timer/ counter and interface various IO (I/O) in chip a sheet of.
计算机方向嵌入式计算机应用正在计算机领域迅速崛起,虽然该技术还不很成熟,但是它 的应用已经深入到社会各个领域,像办公自动化、民用消费品、计算机外设、机器人和武 器系统等等。
嵌入式系统,属于电子系统,包括微处理器或微控制器,嵌入式系统不是一般的计算 机,是隐藏或嵌入在各种系统中的计算机。主要用于控制领域,兼顾数据处理。而微控制 器即 MCU,MCU 的基本含义,在一片芯片上集成了中央处理单元(cpu)、存储器(RAM/ROM 等)、 定时器/计数器及多种输入\输出(I/O)接口的比较完整的数字处理系统。

飞思卡尔MC9S12C中文介绍以及简单编程编程

飞思卡尔MC9S12C中文介绍以及简单编程编程

C64 64K / 64k* 4K - 16MHz (25MHz option) 1 1 - 3-5V 31 - 60 1 8-ch 10-bit 48 / 52 / 80 C32 32K / 32K* 2K - 16MHz (25MHz option) 1 1 - 3-5V 31 - 60 1 8-ch 10-bit 48 / 52 / 80 GC32 32K 2K - 16MHz (25MHz option) 1 1 - 3-5V 31 - 60 0 8-ch 10-bit 48 / 52 / 80 GC16 16K 2K - 16MHz (25MHz option) 1 1 - 3-5V 31 - 60 0 8-ch 10-bit 48 / 52 / 80 TM Freescale Semiconductor Confidential and Proprietary Information. Freescale™ and the Freescale logo are trademarks of Freescale Semiconductor, Inc. All other product or service names are the property of their respective owners. © Freescale Semiconductor, Inc. 2005. Slide 5 S12 C-系列更新… –市场表现出色,给人崭新印象的入门级 C-系列… –16 位的性能 8 位的价格 –弥补 S12 在$2.00 以下的缺憾 –3-5V 工作电压 – 封装从小型的 48 QFP (7x7mm) 到标准的 80 QFP (与 S12D & B 兼容) – 9S12C64/96/128 已经通过质量测试 –*ROM 系列 (所有 CAN 版本) 将使 S12 入门级更低 – ROM Production targeted for 3Q05 (all versions). Exact schedule TBD. – 不带 CAN 的 9S12GC16/32/64/128 量产,价格更低!与 C32/64/96 管脚兼容 应用范围: 车身控制,ABS,EPS,座椅控制,空调 TM Freescale Semiconductor Confidential and Proprietary Information. Freescale™ and the Freescale logo are trademarks of Freescale Semiconductor, Inc. All other product or service names are the property of their respective owners. © Freescale Semiconductor, Inc. 2005. Slide 6 MC9S12Q 系列 Part No Flash ROM RAM CAN SCI SPI TIMER ADC PWM Package S12Q128 128k - 4k 1 1 1 6ch 16 bit 8ch 10bit 4 Ch 80, 52, 48 QFP S12Q96 96k - 3k 1 1 1 6ch 16 bit 8ch 10bit 4 Ch 80, 52, 48 QFP S12Q64 64k - 2k 1 1 1 6ch 16 bit 8ch 10bit - 52, 48 QFP S12Q32 32k - 1k 1 1 1 6ch 16 bit 8ch 10bit - 52, 48 QFP S12Q128 - 128k 4k 1 1 1 6ch 16 bit 8ch 10bit 4 Ch 80, 52, 48 QFP S12Q96 - 96k 3k 1 1 1 6ch 16 bit 8ch 10bit 4 Ch 80, 52, 48 QFP S12Q64 - 64k 2k 1 1 1 6ch 16 bit 8ch 10bit - 52, 48 QFP S12Q32 - 32k 1k 1 1 1 6ch 16 bit 8ch 10bit - 52, 48 QFP Q Family Q Family MCU’s MCU’s 特点/优点: •低成本 •基于 S12C-系列 •增强型 msCAN 12 •增强型 SCI 用于 LIN • SPI • 8 or 16 MHz Up to 4K RAM Up to 4K RAM Up to 128K Up to 128K FLASH/ROM FLASH/ROM

飞思卡尔S12系列寄存器和中断讲解

飞思卡尔S12系列寄存器和中断讲解

S12的输入/输入端口(I/O 口)I/O端口功能可设置为通用I/O 口、驱动、内部上拉/下拉、中断输入等功能。

设置I/O口工作方式的寄存器有:DDR、10、RDR、PE、IE 和 PS。

DDR :设定I/O 口的数据方向。

IO :设定输出电平的高低。

RDR :选择I/O 口的驱动能力。

PE:选择上拉/下拉。

IE:允许或禁止端口中断。

PS: 1、中断允许位置位时,选择上升沿/下降沿触发中断;2、中断禁止时且PE有效时,用于选择上拉还是下拉。

I/O端口设置1、A 口、B 口、E 口寄存器(1)数据方向寄存器 DDRA、DDRB、DDREDDRA、DDRB、DDRE均为8位寄存器,复位后其值均为 0。

当 DDRA=0、DDRB=0、 DDRE=0 时 A 口、B 口和 E 口均为输入口。

否则,A 口、B口、E 口为输出口。

当 DDRA、DDRB、DDRE的任何一位置1时,则该位对应的引脚被设置为输出。

例如,将A 口设置为输出口,则其 C语言程序的语句为:DDRA=0xff ;(2) A 口、B 口、E 口上拉控制寄存器PUCRPUCR 初:PUPKE —— ----- --------- -——RUPEE ——-————-——PUPBE PUR\EWrite: | | |PUCR为8位寄存器,复位后的值为 0。

当PUPAE、PUPBE、PUPEE被设置为1时,A 口、B 口、E 口具有内部上拉功能;为0时,上拉无效。

当A 口、 B 口、E 口为地址/数据总线时,PUPAE和PUPBE无效。

(3)A 口、B 口、E 口降功率驱动控制寄存器RDRIVRDRIV 篇眾?RDPK 口| | 良DPE 口口| 嵐DPB RDPARDRIV为8位寄存器,复位后的值为 0,此时,A 口、B 口、E 口驱动保持全功率;当 RDPA、RDPB、RDPE为1时,A 口、B 口、E 口输出引脚的驱动功率下降(4)数据寄存器PORTA、PORTB、PORTEPORTA、PORTB、PORTE均为8位寄存器,复位后的值为 0,端口引脚输出低电平;要使引脚输出高电平,相应端口对应位应该置1。

飞思卡尔单片机烧写程序步骤

飞思卡尔单片机烧写程序步骤

创建一个工程
选择单片机的型号,我一直用的是mc9s12xs128的单片机,然后在“choose your default connection:”里面选择最后一个“TBDML”,TBDML是一个仿真器,飞思卡尔单片机用的BDM 仿真器,选择好后下一步
这一步就是建立工程的名字和位置,左边选择语言类型,选择C即可,设置好名字和位置后点下一步
这个窗口指的是要不要从一个位置添加先前存在的工程,不用添加,直接下一步
直接下一步
这一步需要注意,在“Select the floating point format supported…….”里选择第二项,如上图,是选择浮点类型长度,选别的可能编译的时候出错,我也不知道为什么
这一步直接默认
直接点完成
即可完成工程的建立
工程建立后自动出来这个画面
在左边栏里,双击main.c会出来主程序,在里面写程序即可,写好后点一下这个按钮,生成一系列文件,如果没有错误,就不会有提示,遇到warming,一般没什么大问题,只要不是error就行,
然后烧写程序点绿色箭头,烧程序单片机通电。

先确保你的电脑装好仿真器的驱动,在资源管理器里面查看
同上显示的话表示正常,如果有黄色感叹号,则需要重新安装驱动。

飞思卡尔单片机应用实验指导书

飞思卡尔单片机应用实验指导书

飞思卡尔单片机应用实验指导书机械工程学院机械电子工程教研室实验一飞思卡尔嵌入式实验系统入门—GPIO控制实验一、实验目的:熟悉CodeWarrior集成开发环境及飞思卡尔嵌入式实验开发系统掌握AW60的GPIO结构及控制方法掌握CodeWarrior工程结构及创建汇编工程熟悉汇编指令及应用汇编语言编程方法二、实验内容1.运用CodeWarrior新建工程,进行工程程序编辑、编译、下载、调试2.利用飞思卡尔嵌入式实验开发系统根据实验需要进行硬件连接3.根据连接在PTD口上的两个拨动开关的状态,控制接中PTB口上的八个LED处在以下四种不同状态:八个LED亮—灭循环;四个灯交替亮—灭;一个LED左移流水灯;两个LED右移流水灯。

实验接线原理图图1-1 I/O 口实验接线图三、实验步骤1.将飞思卡尔嵌入式实验开发系统实验箱接上电源,写入器BDM 接头插接入核心卡BDM 座,USB 头接入PC 机USB 口。

2.PC 机上启动CodeWarrior ,新建工程LED.mcp(注意设置工程保存路径) 3.观察工程文件结构,查看相应文件。

4.在main.asm 中编辑工程主文件 5.编辑相关子程序6.编译,如果有错误修改,直至编译通过 7.链接、下载,调试观察LED 灯现象四、思考题1.CodeWarrior 建立工程有什么工程框架文件,这些文件的作用?2.嵌入式开发系统有哪些主要元器件?3.如果采用模块化设计方法,将系统初始化、LED 灯控制、延时程序等各自形成文件,GNDPTB 口 Vcc工程应用这些文件时应注意什么?4.上拉电阻和下拉电阻分内置的和外接的,内置的电阻一般只有几K或十几K,外接电阻可以是几M、十几M甚至更大。

当要求功耗较低时,应该怎样选择内置的还是外接的电阻?5.该实验的开关通过I/O口控制小灯的程序,分别叙述断点调试和单步调试的步骤,其中包含:利用汇编语言时,注意观察寄存器值的变化并记录寄存器中每次的值实验二串口通信(SCI)实验一、实验目的:1.进一步熟悉嵌入式开发系统环境、汇编、C语言、调试方式。

飞思卡尔单片机MC9s12xs128调试PS2

飞思卡尔单片机MC9s12xs128调试PS2

========================PS2.h=====================================#ifndef _PS2_H#define _PS2_H#define PS2_CLK PTJ_PTJ1#define PS2_RW PORTA_PA1typedef struct PS2_V alueType {char PS2_V alueData; /* 码表Num :77 /:E04A*:7C -:7B7: 6C 8:75 9:7D +:794: 6B 5:73 6:74 +:791: 69 2:72 3:7A Enter:E05A0: 70 .:71*//* 对应返回值Num :-5 /:-4 *:7C -:-27: 7 8:8 9:9 +:-14: 4 5:5 6:6 +:-11: 1 2:2 3:3 Enter:100: 0 .:-3 空格-6*/unsigned char PS2_V alueKind; //0 按下,1松手}PS2_V alueType;#endif _PS2_H======================================PS2.c============================ #include "PS2.h"#include "MC9S12XS128.h"//extern unsigned char PS2_Buffer[3];//extern unsigned char PS2_StopCodeFlag=0;//从PS/2中获取一个按键unsigned char PS2_GetData(void){unsigned char temp,i,res;for(i=0;i<11;i++) {while(PS2_CLK);if(i>0 && i<9) {res=res>>1;if(PS2_RW) {res=res|0x80;}}while (!PS2_CLK);}return res;}void Key_Interrupt(void) {//DDRJ=0X00;PIEJ_PIEJ1=1;PPSJ_PPSJ1=0;}void PS2_InsertBuffer(unsigned char *buffer,unsigned char bufferdata) {unsigned char *tempdata=buffer+1;(*buffer++)=(*tempdata++);(*buffer++)=(*buffer++);(*buffer)=bufferdata;}void PS2_GetChar(PS2_V alueType *PS2_V alue){unsigned char temp;temp=PS2_GetData();(*PS2_V alue).PS2_V alueKind=0;if(temp!=0xe0 && temp!=0xf0){switch (temp){/* 对应返回值Num :-6 /:-4 *:-5 -:-27: 7 8:8 9:9 +:-14: 4 5:5 6:6 +:-11: 1 2:2 3:3 Enter:100: 0 .:-3*/case 0x70 : (*PS2_V alue).PS2_V alueData=0; return;case 0x69 : (*PS2_V alue).PS2_V alueData=1; return;case 0x72 : (*PS2_V alue).PS2_V alueData=2; return;case 0x7A : (*PS2_V alue).PS2_V alueData=3; return;case 0x6B : (*PS2_V alue).PS2_V alueData=4; return;case 0x73 : (*PS2_V alue).PS2_V alueData=5; return;case 0x74 : (*PS2_V alue).PS2_V alueData=6; return;case 0x6C : (*PS2_V alue).PS2_V alueData=7; return;case 0x75 : (*PS2_V alue).PS2_V alueData=8; return;case 0x7D : (*PS2_V alue).PS2_V alueData=9; return;case 0x71 : (*PS2_V alue).PS2_V alueData=-3; return;case 0x79 : (*PS2_V alue).PS2_V alueData=-1; return;case 0x7B : (*PS2_V alue).PS2_V alueData=-2; return;case 0x7C : (*PS2_V alue).PS2_V alueData=-5; return;case 0x77 : (*PS2_V alue).PS2_V alueData=-6; return;case 0x66 : (*PS2_V alue).PS2_V alueData=-7; return;}}else if(temp==0xe0){temp=PS2_GetData();if(temp==0xf0){temp=PS2_GetData();(*PS2_V alue).PS2_V alueKind=1;if(temp==0x5A){(*PS2_V alue).PS2_V alueData=10; return;}else if(temp==0x4A){(*PS2_V alue).PS2_V alueData=-4; return;}}else{(*PS2_V alue).PS2_V alueKind=0;if(temp==0x5A){(*PS2_V alue).PS2_V alueData=10; return;}else if(temp==0x4A){(*PS2_V alue).PS2_V alueData=-4; return;}}}else if (temp==0xf0){(*PS2_V alue).PS2_V alueKind=1;temp=PS2_GetData();switch (temp){/* 对应返回值Num :-6 /:-4 *:-5 -:-27: 7 8:8 9:9 +:-14: 4 5:5 6:6 +:-11: 1 2:2 3:3 Enter:100: 0 .:-3 空格-7*/case 0x70 : (*PS2_V alue).PS2_V alueData=0; return;case 0x69 : (*PS2_V alue).PS2_V alueData=1; return;case 0x72 : (*PS2_V alue).PS2_V alueData=2; return;case 0x7A : (*PS2_V alue).PS2_V alueData=3; return;case 0x6B : (*PS2_V alue).PS2_V alueData=4; return;case 0x73 : (*PS2_V alue).PS2_V alueData=5; return;case 0x74 : (*PS2_V alue).PS2_V alueData=6; return;case 0x6C : (*PS2_V alue).PS2_V alueData=7; return;case 0x75 : (*PS2_V alue).PS2_V alueData=8; return;case 0x7D : (*PS2_V alue).PS2_V alueData=9; return;case 0x71 : (*PS2_V alue).PS2_V alueData=-3; return;case 0x79 : (*PS2_V alue).PS2_V alueData=-1; return;case 0x7B : (*PS2_V alue).PS2_V alueData=-2; return;case 0x7C : (*PS2_V alue).PS2_V alueData=-5; return;case 0x77 : (*PS2_V alue).PS2_V alueData=-6; return;case 0x66 : (*PS2_V alue).PS2_V alueData=-7; return;}}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Page 2
第七章 用C语言开发应用程序 语言开发应用程序 —编辑、编译、链接、定位 编辑、编译、链接、
集成开发环境IDE:将应用程序的编辑、编译、链接、定位、调试等集成在 :将应用程序的编辑、编译、链接、定位、 集成开发环境 一个大的软件包中,简化开发工作。但用户往往不清楚操作的原理。 一个大的软件包中,简化开发工作。但用户往往不清楚操作的原理。
flag=0; CLR 0X2100
0x2000~0x20FF为栈空间(STACKSIZE 0x100 ) 0x2100为定义的第一个全局变量flag的地址(见*.map文件) 虽然使用全局变量传递参数非常方便,但在多任务环境下,多个任务访问某个 全局变量会引起竞争(如中断服务程序和主程序都访问同一个全局变量)。
2、避免使用浮点数和双精度 、 3、C语言数据类型的位宽取决于单片机的类型和具体的 语言数据类型的位宽取决于单片机的类型和具体的IDE中的约定; 中的约定; 、 语言数据类型的位宽取决于单片机的类型和具体的 中的约定 中工程窗口中的“ 标签下“ 如codewarrior中工程窗口中的“target”标签下“standard”对话框中 中工程窗口中的 标签下 对话框中 “complier for”中 “Type sizes”按钮对应的对话框 中 按钮对应的对话框 Page 6
微控制器的编程是围绕存储器的
代码保存在存储器中 变量使用存储器 外设的控制实际是通过对存储器的访问来实现
Page 5
第七章 用C语言开发应用程序 语言开发应用程序 —编辑、编译、链接、定位 编辑、编译、链接、
7.2 开发嵌入式应用的 编译器的特点 开发嵌入式应用的C编译器的特点
注意变量的数据类型ቤተ መጻሕፍቲ ባይዱ
1、RAM空间有限,选择适合变量取值范围的数据类型,尤其是数组;适合的数 、 空间有限,选择适合变量取值范围的数据类型,尤其是数组; 空间有限 据类型能节省代码长度,缩短执行周期; 据类型能节省代码长度,缩短执行周期; Signed/unsigned char/int/short/long 每个数据类型都用特定的范围如下: 每个数据类型都用特定的范围如下:
第七章 用C语言开发应用程序 语言开发应用程序 —编辑、编译、链接、定位 编辑、编译、链接、
4、尽量不调整编译器默认的数 尽量不调整编译器默认的数 据类型的位宽,避免使用 据类型的位宽, 原始的数据类型, 原始的数据类型,而是通 过声明统一化的间接数据 类型。 类型。
#typedef unsigned char u8_t #typedef int u16_t #typedef unsigned long u32_t u16_t a; function() { a=5; a+=3; }
第七章 用C语言开发应用程序 语言开发应用程序 ———函数 函数
7.4 函数的结构与函数间参数的传递
函数间传递参数通常有两种方法:使用全局变量和形参。 1、全局变量
全局变量从RAM低地址堆起。但由于CodeWarrior默认在RAM低地址保留栈空 间,将堆栈视为第1个全局变量,所以全局变量紧随堆栈之后。例如: #include <hidef.h> /* common defines and macros */ #include "derivative.h" /* derivative-specific definitions */ extern void delay1(unsigned int countert); unsigned char flag; ……
Page 1
第七章 用C语言开发应用程序 语言开发应用程序 —编辑、编译、链接、定位 编辑、编译、链接、
7.1 C语言是开发单片机应用软件的有力工具 语言是开发单片机应用软件的有力工具
标准ANSI C:通用计算机上有操作系统的 语言 标准 :通用计算机上有操作系统的C语言 嵌入式C: 编译器需特殊处理与 编译器需特殊处理与CPU硬件相关的内容,随着单片机系统 硬件相关的内容, 嵌入式 :C编译器需特殊处理与 硬件相关的内容 程序空间的增大(可达4M), 语言的应用越来越广泛( ),C语言的应用越来越广泛 程序空间的增大(可达 ), 语言的应用越来越广泛(>4K)。 )。 µC/OS-II:实时操作系统RTOS,是指当外界事件或数据产生时,能 / - :实时操作系统 ,是指当外界事件或数据产生时, 够接受并以足够快的速度予以处理, 够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之 内来控制生产过程或对处理系统作出快速响应, 内来控制生产过程或对处理系统作出快速响应,并控制所有实时任务协 调一致运行的操作系统。保证系统的实时性、可靠性和稳定性。 调一致运行的操作系统。保证系统的实时性、可靠性和稳定性。 嵌入式C的优势:移植性好、库函数丰富、可读性好、便于使用 嵌入式 的优势:移植性好、库函数丰富、可读性好、便于使用RTOS。 的优势 。 汇编语言的优势:编写系统的硬件相关部分更直观、方便,代码少、 汇编语言的优势:编写系统的硬件相关部分更直观、方便,代码少、执 行速度快。常用于: 行速度快。常用于: • • • 系统的初始化 中断向量的初始化, 中断向量的初始化,开、关中断 I/O口的输入输出函数 口的输入输出函数
交叉编译:是指在一台大一些、 交叉编译:是指在一台大一些、
生目标系统的机器码。 生目标系统的机器码。目标系统 计算机的CPU类型完全不同。 类型完全不同。 计算机的 类型完全不同
第七章 用C语言开发应用程序 语言开发应用程序 —编辑、编译、链接、定位 编辑、编译、链接、
*.h *.c *.c++ C源文件 源文件 汇编源文件
Page 8
第七章 用C语言开发应用程序 语言开发应用程序 ———运行环境 运行环境
7.3 建立 语言程序运行环境 建立C语言程序运行环境
C语言的主程序从main()开始的,必须为main() 建立一个程序运行环境, 主要完成四件事情: 1、设置栈指针初值 2、相关硬件的系统初始化 3、调用函数main() 使之执行 4、给出main() 完成后的出口,即执行exit()。
最简情况下,只需1、3。 CodeWarrior默认在RAM低地址保留栈空间。 硬件的初始化通常包括相关寄存器初始化、时钟初始化、串行口初始化等 实际应用中,应用程序往往是一个死循环,不用4。调试时,可以把监控程序 的热启动地址作为出口
Page 9
第七章 用C语言开发应用程序 语言开发应用程序 ———运行环境 运行环境
Page 7
第七章 用C语言开发应用程序 语言开发应用程序 —编辑、编译、链接、定位 编辑、编译、链接、
7.2 开发嵌入式应用的 编译器的特点 开发嵌入式应用的C编译器的特点
注意函数的可重入性 在多任务环境下,允许某个函数同时被一个以上的任务调用,称该函数 具备可重入性。如果知道某个库函数中使用了全局变量,就可以认为这 个函数是不可重入的。
Page 11
第七章 用C语言开发应用程序 语言开发应用程序 ———函数 函数
7.4 函数的结构与函数间参数的传递
2、局部变量
局部变量是某个函数的“私有”变量,是在栈空间定义的,局部变量实际上 是子程序要用到的一块内存空间。例如: void main(void) { unsigned char i,settime; unsigned int j,m,n; …… } 局部变量只在函数内部有意义,它所占用的一块栈空间在子程序返回前会释 放掉,因此局部变量不涉及到参数传递。 (SP=0x2100)__ (SP=0x20F8)__
CodeWarrior自动生成Start12.c文件建立运行环境 创建新工程过程中,当选择了C编程语言后,有以下选择: 1、选择最小化的 startup代码
2、选择小模式:适用 于整个应用程序都 在64KB寻址空间 内的情况,若需分 页,自行处理。 3、Debug调试时,复 位后单步执行,可 以看到运行环境的 建立过程。 10 Page
*.asm *.inc
链接配 置文件
*.prm
C编译器 汇编编译器
列表文件
目标文件
*.obj
库文件
*.lst 反 编 译 器
链接器 *.sx 执行文件 *.abs
汇编 反编译文件
映射文件
*.map
Page 4
第七章 用C语言开发应用程序 语言开发应用程序 —编辑、编译、链接、定位 编辑、编译、链接、
Page 12
第七章 用C语言开发应用程序 语言开发应用程序 ———函数 函数
7.4 函数的结构与函数间参数的传递
3、形式参数
函数的形式参数也被安排在栈空间,参数传递是通过调用函数将值复制给被调 用的形式参数实现的,即参数是通过堆栈传递的。 使用的C编译器不同,参数进入堆栈的顺序以及最后一个参数或第一个参数保 存在什么地方也会有所不同。 CodeWarrior的传递规则: (1) 返回参数:return(n)中的n值。char n,则在B寄存器;int n,则在D寄存器; 其它类型,则返回一个指向n的指针,存在D寄存器。 (2) 定义函数:多个形参时,从右往左,第一个参数读D寄存器,其它依次读取 以堆栈指针为基地址,加上2(绕过函数程序的返回地址)开始 的堆栈空间内,左边第一个参数偏移量的值最大。
第七章 用C语言开发应用程序 语言开发应用程序
• • • • • 7.1 C语言是开发单片机应用软件的有力工具 语言是开发单片机应用软件的有力工具 7.2 开发嵌入式应用的 编译器的特点 开发嵌入式应用的C编译器的特点 7.3 建立 语言程序运行环境 建立C语言程序运行环境 7.4 函数的结构与函数间参数的传递 7.5 应用程序的模块化及其框架
1. 编辑程序源代码: *.c, *.asm, *.h ; 编辑程序源代码: 2. 预编译:对源代码文件中的文件包含(include)、预编译语句(#define)等进行分析、 预编译:对源代码文件中的文件包含( 、预编译语句( )等进行分析、 检查声明、定义的完整性,转换成C编译器可接受的格式 编译器可接受的格式; 检查声明、定义的完整性,转换成 编译器可接受的格式; 3. 编译 :检查和报告相关的语法错误,然后将 程序转换成汇编器可接受的代码。 检查和报告相关的语法错误,然后将C程序转换成汇编器可接受的代码 程序转换成汇编器可接受的代码。 4. 汇编 :生成针对某种 生成针对某种CPU的汇编浮动代码文件,*.obj; 的汇编浮动代码文件, 的汇编浮动代码文件 ; 5. 链接 :将浮动的 将浮动的*.obj文件模块按指定顺序链接起来,并且将所用到的 语言标准库函 文件模块按指定顺序链接起来, 文件模块按指定顺序链接起来 并且将所用到的C语言标准库函 用起来更方便的计算机上编译产 数也从各自所在的函数库中调出,把 文件中缺失的那些参数补上, 数也从各自所在的函数库中调出 把*.obj文件中缺失的那些参数补上,*.prm; 文件中缺失的那些参数补上 ; 6. 定位 :根据目标系统硬件的情况,给程序分配程序空间的地址、数据空间的地址以及 根据目标系统硬件的情况,给程序分配程序空间的地址、 所用的CPU及指令系统与所用的 所用的 及指令系统与所用的 程序运行的其实地址等,生成可执行的目标代码, 程序运行的其实地址等,生成可执行的目标代码,*.abs,*.sx; ; 7. 下载 :将*.sx文件下载到单片机的程序空间的相应地址内; 文件下载到单片机的程序空间的相应地址内; 文件下载到单片机的程序空间的相应地址内 8. 调试、运行 调试、 9. 反汇编:将目标代码反汇编成汇编语言,以便用户对应用程序中特别关键的部分进一 反汇编:将目标代码反汇编成汇编语言, 步优化( 步优化(project->Disassemble)。 。 Page 3
相关文档
最新文档