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

飞思卡尔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

{

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

{

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和R

PGNTmp <<= 8;

PGNTmp |= (uint8_t)(IDPtr->Bits.PF0 | IDPtr->Bits.PF1<<2 | IDPtr->Bits.PF2<<5); //析取PF

PGNTmp <<= 8;

PGNTmp |= (uint8_t)(IDPtr->Bits.PS0 | IDPtr->Bits.PS1<<7);

//析取PS

if(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;//590

HMI_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[]="温度传感器。。。";

uint8_t error18[]="温度传感器控制单元内部错误";

uint8_t error19[]="频率传感器的输入速度和冗余速度的信息,在同一时间出现故障"; uint8_t error20[]="频率传感器的输入速度故障";

uint8_t error21[]="频率传感器的输出速度故障";

uint8_t error22[]="频率传感器的输出速度和冗余速度的信息,在同一时间出现故障"; uint8_t error23[]="接近开关换向片A旋转方向故障";

uint8_t error24[]="接近开关换向片B旋转方向故障";

uint8_t error25[]="电磁阀转换器1故障";

uint8_t error26[]="当前电磁阀转换器1超出范围";

uint8_t error27[]="电磁阀联轴器1故障";

uint8_t error28[]="当前电磁阀联轴器1超出范围";

uint8_t error29[]="电磁阀换向片A旋转方向故障";

uint8_t error30[]="当前电磁阀换向片A旋转方向超出范围";

uint8_t error31[]="电磁阀换向片B旋转方向故障";

uint8_t error32[]="当前电磁阀换向片B方向超出范围";

uint8_t error33[]="使能信号UTR1故障";

uint8_t error34[]="换向气缸叶端位置";

uint8_t error35[]="倒车单位不正确组合/双啮合";

uint8_t error36[]="VTDC只获得一个填充命令";

uint8_t error37[]="VTDC获得两个旋转方向命令";

uint8_t error38[]="在热交换前变速箱油温警告";

uint8_t error39[]="在热交换前变速箱油过热";

uint8_t error40[]="倒车超时停止";

uint8_t error41[]="倒车缸没到中间位置";

uint8_t error42[]="滑动联轴器1过高";

uint8_t error43[]="对于范围和旋转模式,输入速度过高";

if(!Touch_flag)

{

fault_memory = (FAULT_MEMORY *)CAN_RxQue.PDUs[OutPtr].Bits.DataField;

Fault_Type = swab16(fault_memory->Num);

}

else if(Touch_flag)

{

Fault_Type = num;

}

if(!HMI_Error_Dis.Cmd_Start) //目的队列未满,可入列

{

HMI_Error_Dis.Cmd_Start = HMI_CMD_START;

HMI_Error_Dis.Cmd_Type = HMI_CMD_TEXTDIS_ASCII;

HMI_Error_Dis.Start_Point.x = 101;

HMI_Error_Dis.Start_Point.y = 490;

switch(Fault_Type){

case 1:

Result = memcpy(HMI_Error_Dis.Str_Dis, error1, 31);

break;

case 2:

Result = memcpy(HMI_Error_Dis.Str_Dis, error2, 31);

break;

case 4:

Result = memcpy(HMI_Error_Dis.Str_Dis, error3, 31);

break;

case 6:

Result = memcpy(HMI_Error_Dis.Str_Dis, error4, 14);

break;

case 7:

Result = memcpy(HMI_Error_Dis.Str_Dis, error5, 14);

break;

case 8:

Result = memcpy(HMI_Error_Dis.Str_Dis, error6, 14);

break;

case 11:

Result = memcpy(HMI_Error_Dis.Str_Dis, error7, 12);

break;

case 12:

Result = memcpy(HMI_Error_Dis.Str_Dis, error8, 14);

break;

case 13:

Result = memcpy(HMI_Error_Dis.Str_Dis, error9, 21);

break;

case 15:

Result = memcpy(HMI_Error_Dis.Str_Dis, error10, 17);

break;

case 16:

Result = memcpy(HMI_Error_Dis.Str_Dis, error11, 11);

break;

case 17:

Result = memcpy(HMI_Error_Dis.Str_Dis, error12, 14);

break;

case 18:

Result = memcpy(HMI_Error_Dis.Str_Dis, error13, 18);

break;

case 41:

Result = memcpy(HMI_Error_Dis.Str_Dis, error14, 17);

break;

case 46:

Result = memcpy(HMI_Error_Dis.Str_Dis, error15, 16);

break;

case 100:

Result = memcpy(HMI_Error_Dis.Str_Dis, error16, 14);

break;

case 110:

Result = memcpy(HMI_Error_Dis.Str_Dis, error17, 16);

break;

case 118:

Result = memcpy(HMI_Error_Dis.Str_Dis, error18, 26);

break;

case 132:

Result = memcpy(HMI_Error_Dis.Str_Dis, error19, 56);

break;

case 133:

Result = memcpy(HMI_Error_Dis.Str_Dis, error20, 24);

break;

case 136:

Result = memcpy(HMI_Error_Dis.Str_Dis, error21, 24);

break;

case 139:

Result = memcpy(HMI_Error_Dis.Str_Dis, error22, 56);

break;

case 140:

Result = memcpy(HMI_Error_Dis.Str_Dis, error23, 27);

break;

case 141:

Result = memcpy(HMI_Error_Dis.Str_Dis, error24, 27);

break;

case 201:

Result = memcpy(HMI_Error_Dis.Str_Dis, error25, 17);

break;

case 202:

Result = memcpy(HMI_Error_Dis.Str_Dis, error26, 25);

break;

case 213:

Result = memcpy(HMI_Error_Dis.Str_Dis, error27, 17);

break;

case 214:

Result = memcpy(HMI_Error_Dis.Str_Dis, error28, 25);

break;

case 223:

Result = memcpy(HMI_Error_Dis.Str_Dis, error29, 25);

case 224:

Result = memcpy(HMI_Error_Dis.Str_Dis, error30, 33);

break;

case 225:

Result = memcpy(HMI_Error_Dis.Str_Dis, error31, 25);

break;

case 226:

Result = memcpy(HMI_Error_Dis.Str_Dis, error32, 29);

break;

case 300:

Result = memcpy(HMI_Error_Dis.Str_Dis, error33, 16);

break;

case 319:

Result = memcpy(HMI_Error_Dis.Str_Dis, error34, 16);

break;

case 325:

Result = memcpy(HMI_Error_Dis.Str_Dis, error35, 25);

break;

case 326:

Result = memcpy(HMI_Error_Dis.Str_Dis, error36, 22);

break;

case 327:

Result = memcpy(HMI_Error_Dis.Str_Dis, error37, 24);

break;

case 328:

Result = memcpy(HMI_Error_Dis.Str_Dis, error38, 24);

break;

case 331:

Result = memcpy(HMI_Error_Dis.Str_Dis, error39, 22);

break;

case 335:

Result = memcpy(HMI_Error_Dis.Str_Dis, error40, 12);

break;

case 339:

Result = memcpy(HMI_Error_Dis.Str_Dis, error41, 18);

break;

case 342:

Result = memcpy(HMI_Error_Dis.Str_Dis, error42, 15);

break;

case 351:

Result = memcpy(HMI_Error_Dis.Str_Dis, error43, 32);

break;

default:

}

HMI_Error_Dis.Cmd_End = HMI_CMD_END;

}

else{

return;

}

if(!Touch_flag)

{

Record_Write();

}

}

///----------------------------------------------------------------------------------------------------------

//Function: 数字转化为Ascii码如101->'1''.''0''1',1002->'1''0''.''2'

//Param:

//Return:

//note

///----------------------------------------------------------------------------------------------------------

void Digit2Ascii1(uint32_t Digit, uint8_t InPtr)

{

uint8_t i, j, k;

uint32_t Temp;

Temp = Digit;

k = 6;

if((Digit > 1000000) || (Digit == 1000000))

{

i = 7;

}

else if((Digit > 100000) || (Digit == 100000))

{

i = 6;

}

else if((Digit > 10000) || (Digit == 10000))

{

i = 5;

}

else if((Digit > 1000) || (Digit == 1000))

{

i = 4;

}

else

{

i = 3;

}

j = i-1;

i = i-1;

Temp /= 10;

do{

if(i-j != 1){

HMI_Text_Dis_Que.HMI_Text_Dis[InPtr].Str_Dis[k] = Temp%10 | 0x30;

Temp /= 10;

}

else{

HMI_Text_Dis_Que.HMI_Text_Dis[InPtr].Str_Dis[k] = '.';

}

k--;

j--;

}while(j);

HMI_Text_Dis_Que.HMI_Text_Dis[InPtr].Str_Dis[k] = Temp%10 | 0x30;

}

void Digit2Ascii0(uint32_t Digit, uint8_t InPtr)

{

uint8_t i, j, k;

uint32_t Temp;

Temp = Digit;

k = 6;

if((Digit > 1000000) || (Digit == 1000000))

{

i = 7;

}

else if((Digit > 100000) || (Digit == 100000))

{

i = 6;

}

else if((Digit > 10000) || (Digit == 10000))

{

i = 5;

}

else if((Digit > 1000) || (Digit == 1000))

{

i = 4;

}

else

{

i = 3;

飞思卡尔单片机编程

关于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文件范例: NAMES END SEGMENTS RAM = READ_WRITE DATA_NEAR 0x2000 TO 0x3FFF;

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_00 = READ_ONLY DATA_FAR IBCC_FAR 0x000800 TO 0x000BFF; 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;

飞思卡尔智能车电机资料上课讲义

3.1.6驱动电机介绍 驱动电机采用直流伺服电机,我们在此选用的是RS-380SH型号的伺服电机,这是因为直流伺服电机具有优良的速度控制性能,它输出较大的转矩,直接拖动负载运行,同时它又受控制信号的直接控制进行转速调节。在很多方面有优越性,具体来说,它具有以下优点: (1)具有较大的转矩,以克服传动装置的摩擦转矩和负载转矩。 (2)调速范围宽,高精度,机械特性及调节特性线性好,且运行速度平稳。 (3)具有快速响应能力,可以适应复杂的速度变化。 (4)电机的负载特性硬,有较大的过载能力,确保运行速度不受负载冲击的 影响。 (5)可以长时间地处于停转状态而不会烧毁电机,一般电机不能长时间运行 于停转状态,电机长时间停转时,稳定温升不超过允许值时输出的最大堵转转矩称为连续堵转转矩,相应的电枢电流为连续堵转电流。 图3.1为该伺服电机的结构图。图3.2是此伺服电机的性能曲线。 图3.1 伺服电机的结构图

图3.2 伺服电机的性能曲线 3.1.7 舵机介绍 舵机是一种位置伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。其工作原理是:控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。舵机的控制信号是PWM信号,利用占空比的变化改变舵机的位置。一般舵机的控制要求如图3.3所示。图3.4为舵机的控制线。 图3.3 舵机控制要求

飞思卡尔K60 DMA 中文手册

/*----------------------------------------------------------------------------------------------------------------------------- 桂林电子科技大学 物联网工程 Editor:JaceLin Date:2014.2.5 -------------------------------------------------------------------------------------------------------------------------------- 一、DMA特性 1)k60有16个DMA通道 二、寄存器 1)控制寄存器:DMA_CR 31-18 reserved 17 CX 取消转移,0正常操作,1取消剩下数据转移 16 ECX 错误取消转移,0正常操作,1取消转移 15-8 reserved 14 EMLM 使能副循环映射 0 禁止,TCDn.word2 为32位 1 使能,TCDn.word被重新定义 6 CLM 持续连接模式,0当副循环结束后,再次激活DMA要通过裁决,1不用裁决 5 HALT 停止DMA操作,0正常模式,1停止DMA操作 4 HOE 错误时停止,0正常操作,1当有错误时HALT=1,也就是DMA停止 3 reserved 2 ERCA 使能循环通道裁决, 1 EDBG 使能调试,写0,调试也用DMA,写1,调试时DMA不可用 0 reserved 2)错误状态寄存器DMA_ES 31 VLD 所有错误状态位逻辑或,0没有错误,1表示至少有1个错误没有清除 30-17 保留 16 ECX 转移被取消0没有被取消的转移,1最后一次记录是被取消的转移 15 保留 14 CPE 通道优先错误,0没有通道优先错误,1有 13-12 保留 11-8 ERRXHN 错误通道位/被取消的位(最多16位) 7 SAE 源地址错误,0没有源地址配置错误,1有错误 6 SOE 源偏移错误,0没有源偏移配置错误,1有偏移配置错误 5 DAE 目标地址错误,0没有错,1有错误 4 DOE 目标偏移错误,0没有错误,1有 3 NCE NBYTES/CITER配置错误,0没有,1有 2 SGE Scatter/Gather配置错误,0没有,1有 1 SBE 源总线错误,0没有错误,1有

飞思卡尔MC9S12XS128技术手册翻译AD

飞思卡尔MC9S12XS128技术手册(AD转换部分) 英文资料:飞思卡尔MC9S12XS256RMV1官方技术手册 1.1 XS12系列单片机的特点 XS12系列单片机特点如下: ·16位S12CPU —向上支持S12模糊指令集并去除了其中的MEM, WAV, WAVR, REV, REVW 五条指令; —模块映射地址机制(MMC); —背景调试模块(BDM); ·CRG时钟和复位发生器 —COP看门狗; —实时中断; ·标准定时器模块 —8个16位输入捕捉或输出比较通道;; —16位计数器,8位精密与分频功能; —1个16位脉冲累加器; ·周期中断定时器PIT —4具有独立溢出定时的定时器; —溢出定时可选范围在1到2^24总线时钟; —溢出中断和外部触发器; ·多达8个的8位或4个16位PWM通道 —每个通道的周期和占空比有程序决定; —输出方式可以选择左对齐或中心对其; —可编程时钟选择逻辑,且可选频率范围很宽; ·SPI通信模块 —可选择8位或16位数据宽度;

—全双工或半双工通信方式; —收发双向缓冲; —主机或从机模式; —可选择最高有效为先输出或者最低有效位先输出; ·两个SCI串行通信接口 —全双工或半双工模式 ·输入输出端口 —多达91个通用I/O引脚,根据封装方式,有些引脚未被引出; —两个单输入引脚; ·封装形式 —112引脚薄型四边引线扁平封装(LQFP); —80引脚扁平封装(QFP); —64引脚LQFP封装; ·工作条件 —全功率模式下单电源供电范围3.15V到5V; —CPU总线频率最大为40MHz —工作温度范围–40 C到125 C 第十章模拟—数字转换 10.1 介绍 ADC12B16C是一个16通道,12位,复用方式输入逐次逼近模拟—数字转换器。 ATD的精度由电器规格决定。 10.1.1 特点 ·可设置8位、10位、12位精度 ·在停止模式下,ATD转换使用内部时钟 ·转换序列结束后自动进入低耗电模式 ·可编程采样时间 ·转化结果可选择左对齐或右对齐

飞思卡尔单片机LED控制例程详解

我的第一个LED程序 准备工作: 硬件:Freescale MC9S08JM60型单片机一块; 软件:集成开发环境codewarrior IDE; 开发板上有两个LED灯,如下图所示: 实验步骤: 1.首先,确保单片机集成开发环境及USBDM驱动正确安装。其中USBDM的安装步骤如下:?假设之前安装过单片机的集成开发环境6.3版本:CW_MCU_V6_3_SE; ?运行USBDM_4_7_0i_Win,这个程序会在c盘的程序文件夹下增加一个目录C:\Program Files\pgo\USBDM 4.7.0,在这个目录下: 1〉C:\ProgramFiles\pgo\USBDM 4.7.0\FlashImages\JMxx下的文件 USBDM_JMxxCLD_V4.sx是下载器的固件文件; 2〉C:\Program Files\pgo\USBDM 4.7.0\USBDM_Drivers\Drivers下有下载器的usb 驱动 所以在插入usb下载器,电脑提示发现新的usb硬件的时候,选择手动指定驱动 安装位置到以上目录即可。 ?运行USBDM_4_7_0i_Win之后,还会在目录: C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.3\prog\gdi 下增加一些文件,从修改时间上来看,增加了6个文件,这些文件是为了在codewarrior 集成开发环境下对usb下载器的调试、下载的支持。

2.新建一个工程,工程建立过程如下: ?运行单片机集成开发环境codewarrior IDE ?出现如下界面 ●Create New Project :创建一个新项目工程 ●Load Example Project :加载一个示例工程 ●Load Previous Project :加载以前创建过的工程 ●Run Getting started Tutorial:运行CodeWarrior软件帮助文档 ●Start Using CodeWarrior:立刻使用CodeWarrior ?点击Create New project按钮,以创建一个新的工程,出现选择CPU的界面 如下,请选择HCS08/HCS08JM Family/MC9S08JM60,在右边的Connection窗口

freescale MC9S12P128中文手册

1 Chapter1 Device Overview MC9S12P-Family 1.1介绍 The MC9S12P 系列单片机是经过优化后有着低成本、高性能、低引脚数的汽车专业级单片机产品,该产品倾向于弥补高端16位单片及产品如MC9S12XS和低端8位单片机产品之间的空缺。MC9S12P 主要针对于要求使用CAN 或者LIN/J2602通讯接口的汽车应用产品,典型的应用案例包括车身控制器、乘坐人员检测、车门控制、座椅控制、遥控车门开关信号接收器、智能执行器、车灯模块、智能接线器。 The MC9S12P 系列单片机使用了很多MC9S12XS系列单片机相同的功能,包括片内闪存错误纠正代码(ECC)、一个专为数据诊断或者数据存储的单独的数据闪存模块、高速AD转换器和高频调制锁相环(IPLL)有效改善电磁兼容性能。MC9S12P系列单片机提供的所有16为单片机优点和微处理器效率,同时保持飞思卡尔用户熟悉的8位及16位单片机,低成本,功耗,EMC和高效的代码80针QFP、64针LQFP、40针QFN封装产品,最大限度的与MC9S12尺寸的优点,如同MC9S12XS一样可以无需等待外围设备和内存的状态既可以运行16为带款的寻址,MC9S12P系列单片机主要有XS引脚兼容. I/O口在各种模式下都可以使用,同时具有中断功能的I/O口还可以在停止或等待模式下唤醒。 1.2 芯片特性 表一:提供了MC9S12P家庭成员特征摘要, 1.P或D寄存器擦除或者编程需要最低总线频率为1MHZ

1.2.2 芯片功能 ? S12 CPU 内核 ? 高达128 KB具有ECC功能的片上闪存 ? 4 Kbyte带ECC功能的数据闪存 ? 高达6 Kb片上静态存储器(SRAM) ? 具有内部滤波器的锁相环倍频器(IPLL) ? 4–16 MHz 皮尔斯振荡器 ? 1 MHz内部RC振荡器 ? 定时器(TIM) 具有16位输入捕捉、输出比较、计数器脉冲累加器功能 ? 具有8位6通道的脉冲调制模块(PWM) ? 10通道12位分辨率的逐次逼近AD转换器 ? 1个串行通信外部接口(SPI) ? 1个支持局域网通讯串行通信(SCI) 模块 ?一个多可扩展控制器区域网络(MSCAN) 模块(支持CAN 协议2.0A/B) ?片上电压调节器(VREG) 可对内部供电及内部电压整流 ? 自主周期中断(API) 1.3 模块特征 1.3.1 CPU S12 CPU 是一个高速的16位处理单元: ?全16-bit数据通道提供有效的数学运算和高速的数学执行 ? 包含很多单字节指令,可以有效的利用ROM空间 ? 宽域变址寻址功能: —采用堆栈指针作为所有变址操作的变址寄存器 —除了在自增或自减模式下都可以利用程序计数器作为变址寄存器 —使用A\B\D累加器做累加器偏移 —自动变址,前递增(++a)、前递减(--a)、后递减(a--)、后递增(a++)(by –8 to +8) 1.3.2 带ECC功能的片内闪存 ? 高达128 Kb程序闪存空间 — 32 位数据加7 位ECC (纠错码) 允许单字节纠错和双字节纠错 — 512字节擦出扇区空间 —自动编程和擦除算法 —用户设置读写页面边界 —具有可以防止偶然编程或者擦除的保护结构 ? 4 Kb 数据闪存空间 — 16 位数据加6位纠错码允许单字节和双字节纠错功能 — 256 字节的擦出扇区空间 —自动编程和擦除算法 —用户设置读写页面边界 1.3.3 片内静态存储器

2011飞思卡尔问题官方回答汇总(1)

所属赛区: 华南赛区 提问时间: 2010年11月16日 18:22:33 问题标题: A 车模问题 问题内容: 如老师所言,A 车模在承轴等一些小方面做了改动,那以前买的A 车模能不能用于参加第六届的比赛? 回 答: 可以。秘书处 队伍名称: 风之子 所属赛区: 华北赛区 提问时间: 2010年11月24日 20:38:55 问题标题: 去年车模 问题内容: 请问去年的B 型车模能参赛吗?能的话,能参加哪个组别的? 回 答: 去年B 型车模由于质量不稳定,今年已经取消该车莫,所以今年 不能参加比赛了。而规定使用新型的B 型车模。 队伍名称: 光电一队 所属赛区: 华东赛区 提问时间: 2010年12月03日 16:56:39 问题标题: 禁止使用D C -D C 升压电路直接为驱动电机以及舵机提供动力 问题内容: 规则的这句话是什么意思,舵机可不可以用开关稳压芯片供电? 谢谢。 回 答: 规定禁止使用D C -D C 升压电路为点电机和舵机供电指的是电机和 舵机的供电电压不得高于电池的电压(7.2V )。 舵机可以使用开 关降压稳压电路供电。 队伍名称: 追风队 所属赛区: 西部赛区 提问时间: 2010年12月03日 22:21:53 问题标题: C 车模 问题内容: 请问C 车模的电机的电压,电流等参数是多少啊?我们好准备。 谢谢! 回 答: C 型车模的电机(马达)参数如下: 额定工作电压:7.2V ,最大工作电压 9.6V 最大效率点: 电流:0.679A ,转速:13050p r m 最大功率点: 电流1.537A ,转速:8044 堵转电流:2.916A C 型车模马达到后轮的传动比为7.46

飞思卡尔--智能车舵机讲解

飞思卡尔--智能车舵机讲解

2.2 舵机的安装 完成了玩具车的拆卸之后要做的第二步就是安装舵机,现在市场上卖的玩具车虽然也具有转向 功能,但是前轮的转向多是依靠直流电机来驱动,无论向哪个方向转都是一下打到底,无法控制转 过固定的角度,因此根据我们的设计需求,需要将原有的转向部分替换成现有的舵机,以实现固定 转角的转向。舵机的实物图如图 2.1所示。 需要说明的是由于小车系玩具车改装,在安装舵机是需要合理的利用小车的结构,将舵机安装 牢固,同时还需注意合理利用购买舵机是附赠的齿轮,从而将舵机固定在合适的位置。舵机的安装 方式有俯式、卧式多种,不同的安装方法力臂长短、响应速度都有所不同,这一点请自己根据实际 情况合理选择,图 2.2 为舵机的安装图。 5

图 2.1 舵机实物图图 2.2 舵机安装图 舵机安装过程中有一点需要尤其注意,由于舵机不是360°可转的,因此必须保证车轮左右转 的极限在舵机的转角范围之内。 舵机安装完毕之后就可以对小车的转角进行控制了,但是由于玩具车的车体设计往往限制了小 车的转角,因此可以对小车进行局部的“破坏”来增大前轮的转角,要知道在比赛中追求速度的同 时一个大的转角对小车的可控性会有一个很大的提升,如图2.3 所示,就是对增加小车转角的一个 改造,这是我在去年小车比赛中的用法。将阻碍前轮转角的一部分用烙铁直接烫掉。 但是这种做法也有风险,由于你的改造会破坏小车的整体 7

结构,有可能会对小车的硬件结构造 成破坏,因此如果你的小车在改造之后显得过于脆弱的话那你就要对你的小车采取些加固措施了。 3.4 舵机转向模块设计 舵机是小车转向的控制机构,具有体积小、力矩大、外部机械设计简单、稳定性高等特 点,无论是在硬件还是软件舵机设计是小车控制部分的重要组成部分,舵机的主要工作流程 为:控制信号→控制电路板→电机转动→齿轮组减速→舵盘转动→位置反馈电位计→控制电路板反馈。图 3.11 为舵机的实物图。 7

第二届全国大学生“飞思卡尔杯”智能汽车竞赛背景介绍概要

第二届全国大学生“飞思卡尔杯”智能汽车竞赛 背景介绍 全国大学生智能汽车竞赛于2005年11月正式启动,去年的第一届“飞思卡尔杯”全国大学生智能汽车邀请赛共有来自全国59所大学的112支队伍参加。今年,第二届全国大学生“飞思卡尔杯”智能汽车竞赛将规模扩大到全国超过100所院校,参赛队将近240支,并在全国分成五个赛区进行预赛,各区按照参赛队数量根据一定比例选拔出共76支队参加8月底在上海交通大学进行的全国总决赛。比赛将决出特等奖、一等奖和二等奖等奖项若干名。 该项竞赛是教育部为了加强大学生实践、创新能力和团队精神的培养而设立的。旨在进一步深化高等工程教育改革,培养本科生获取知识、应用知识的能力及创新意识;培养硕士生从事科学和技术研究能力,知识和技术创新能力。 全国大学生智能汽车竞赛与已在全国举办的数学建模、电子设计、机械设计、结构设计等专业竞赛不同,是以迅猛发展的汽车电子为背景,涵盖了控制、模式识别、传感技术、电子、电气、计算机、机械等多个学科交叉的科技创意性比赛。教育部委托高等学校自动化专业教学指导分委员会主办每年一度的全国大学生智能汽车竞赛;高等学校自动专业教学指导分委员会决定飞思卡尔半导体公司为协办单位,赛事冠名为“飞思卡尔杯”。第二届“飞思卡尔杯”全国大学生智能汽车竞赛分赛区和决赛的承办院校从自愿报名的院校中竞争选拔产生。 竞赛组委会成员 “飞思卡尔杯”全国大学生智能汽车竞赛组织委员会由高等学校自动化专业教学指导分委员会主任委员吴澄院士任主任委员,教育部高等教育司张尧学司长、飞思卡尔高级副总裁兼汽车与标准产品部总经理Paul Grimme先生、飞思卡尔高级副总裁兼亚太区主席姚天丛先生、清华大学副校长汪劲松教授、高等学校自动化专业教学指导分委员会副主任委员申功璋教授任副主任委员。 参赛队组成

飞思卡尔KE02系列简介

1Kinetis E series Kinetis E series provide the highly scalable portfolio of ARM ? Cortex ?-M0+ MCUs in the industry. With 2.7–5.5 V supply and focus on exceptional EMC/ESD robustness,Kinetis E series devices are well suited to a wide range of applications in electrical harsh environments, and is optimized for cost-sensitive applications offering low pin-count option.The Kinetis E series offers a broad range of memory,peripherals, and package options. They share common peripherals and pin counts allowing developers to migrate easily within an MCU family or among the MCU families to take advantage of more memory or feature integration. This scalability allows developers to standardize on the Kinetis E series for their end product platforms, maximising hardware and software reuse and reducing time-to-market. Following are the general features of the Kinetis E series MCUs. ?32-bit ARM Cortex-M0+ core ?Scalable memory footprints from 8 KB flash / 1 KB SRAM to 128 KB flash / 16 KB SRAM ?Precision mixed-signal capability with on chip analog comparator and 12-bit ADC ?Powerful timers for a broad range of applications including motor control ?Serial communication interfaces such as UART, SPI,I 2C, and others. ?High security and safety with internal watchdog and programmable CRC module Product Brief Rev 3, 07/2013 KE02 Product Brief Supports all KE02 devices ? 2013 Freescale Semiconductor, Inc. Contents 1Kinetis E series..........................................................12KE02 sub-family introduction..................................23Block diagram...........................................................34Features.....................................................................45Power modes.. (136) Revision history (14)

飞思卡尔单片机寄存器及汇编指令详解

附录I:寄存器地址列表 直接页面寄存器总结

高页面寄存器总结

非易失寄存器总结 注:直接页面寄存器表地址的低字节用粗体显示,直接寻址对其访问时,仅写地址低字节即可。第2列中寄存器名用粗体显示以区别右边的位名。有0的单元格表示未用到的位总是读为0,有破折号的单元格表示未用或者保留,对其读不定。

附录II 指令接与寻址方式 HCS08指令集概括 运算符 () = 括号种表示寄存器或存储器位置的内容 ← = 用……加载(读: “得到”) & = 布尔与 | = 布尔或 ⊕= 布尔异或 ×= 乘 ÷ = 除 : = 串联 + = 加 - = 求反(二进制补码) CPU registers A =>累加器 CCR =>条件代码寄存器 H =>索引寄存器,高8位 X => 索引寄存器,低8位 PC =>程序计数器 PCH =>程序计数器,高8位 PCL =>程序计数器,低8位 SP =>堆栈指针 存储器和寻址 M =>一个存储区位置或者绝对值数据,视寻址模式而定 M:M + 0x0001 => 两个连续存储位置的16位值.高8位位于M的地址,低8位位于更高的连续地址. 条件代码寄存器(CCR)位 V => 二进制补码溢出指示,第7位 H => 半进位,第4位 I => 中断屏蔽,第 3位 N => 求反指示器, 第2位 Z => 置零指示器, 第1位 C => 进/借, 第0位 (进位第 7位 ) CCR工作性符号 – => 位不受影响 0 = > 位强制为0 1 = > 位强制为1

= >根据运算结果设置或清除位 U = > 运算后没有定义 机器编码符号 dd =>一个直接寻址0x0000–0x00FF的低8位(高字节假设为0x00) ee => 16位偏移量的高8位 ff => 16位偏移量的低8位 ii => 立即数的一个字节 jj => 16位立即数值的高位字节 kk => 16位立即数值的低位字节 hh => 16位扩展寻址的高位字节 ll => 16位扩展寻址的低位字节 rr => 相对偏移量 n —任何表达范围在0–7之间的一个有符号数的标号或表达式 opr8i —任何一个表达8位立即值的标号或表达式 opr16 —任何一个表达16位立即值的标号或表达式 opr8a —任何一个表达一个8位值的标号或表达式.指令对待这个8位值为直接页面64K 字节地址空间(0x00xx)中地址的低8位. opr16a —任何一个表达16位值的标号或表达式.指令对待这个值为直接页面64K字节地址空间. oprx8 —任何一个表达8位无符号值的标号或表达式,用于索引寻址. oprx16 —任何一个16位值的标号或表达式.因为HCS08有一个16位地址总线,这可以为一个有符号或者无符号值. rel —任何指引在当前指令目标代码最后一个字节之后–128 to +127个字节之内的标号或表达式.汇编器会计算包括当前指令目标代码在内的8位有符号偏移量. 寻址方式 隐含寻址(Inherent)如CLRA,只有操作码,无操作数,需要操作的数据一般为CPU寄存器,因此不需要再去找操作数了。(INH) 立即寻址 (Immediate)如LDA #$0A,“$”表示16进制,此时操作数位于FLASH空间,与程序一起存放。(IMM) 直接寻址 (Direct)如 LDA $88,只能访问$0000-$00FF的存储器空间,指令短速度快; (DIR) 扩展寻址 (Extended)如果操作数地址超出了$00FF,自动为扩展寻址;(EXT) 相对寻址(Relative)如BRA LOOP,指令中一般给出8位有符号数表示的偏移量。(REL) 变址寻址 (Indexed) 采用[H:X]或SP作为指针的间接寻址方式。( IX )( IX1 )( IX2 ) 变址寻址 (Indexed) 1〉无偏移量:CLR ,X 简写(IX) 2〉无偏移量,指令完成后指针加1(H:X = H:X + 0x0001) ,简写(IX+)只用于指令MOV和CBEQ指令中;

飞思卡尔汽车芯片

飞思卡尔推出业界最强大的汽车动力总成系统微 控制器 2011-10-14 18:05:18 来源:与非网 关键字:飞思卡尔Qorivva MCU 动力总成控制系统 2011年10月12日-德国巴登(2011汽车电子系统展览会)–汽车厂商继续通过新的汽车设计将业界标准提升至新高度,通过交付具有更高燃油经济性和更低排放的汽车满足消费者的期望和政府的法规要求。高性能微控制器(MCU)在环保汽车设计领域扮演着重要角色,飞思卡尔半导体(NYSE:FSL)日前宣布推出强大的多核心汽车MCU系列中的第一款产品,帮助汽车设计者更加轻松地提高引擎效率并降低排放污染。 飞思卡尔新推出的多核心Qorivva 32位MPC5676R MCU在Power Architecture?技术的基础上构建,与上一代单核心MPC5566 MCU相比,性能提高了四倍、内存空间提高了一倍、并提供了更多功能。MPC5676R的多种优势允许全球汽车厂商在单一控制器中融合多种尖端技术,例如直喷、涡轮增压和有线系统全驱动。 飞思卡尔负责汽车MCU业务副总裁Ray Cornyn表示,“飞思卡尔充分了解帮助汽车厂商生产更加环保、燃油效率更高的汽车所需的关键技术及其重要性,长期以来我们一直与汽车行业合作,共同开发可以满足其最新一代设计需求的解决方案。在动力总成领域,我们的目标是生产最强大、最灵活的MCU,它可以同时管理最新引擎的所有复杂控制任务,为设计者提供了降低系统复杂性所需的工具和软件平台。” 90纳米双核心MPC5676R MCU配备了: ? 6 MB片上闪存 ?384 KB片上RAM ?三个高性能增强型时序处理器单元(eTPU)

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

S12的输入/输入端口(I/O口) I/O端口功能 可设置为通用I/O口、驱动、内部上拉/下拉、中断输入等功能。 设置I/O口工作方式的寄存器有: DDR、IO、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、DDRE DDRA、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口上拉控制寄存器PUCR PUCR为8位寄存器,复位后的值为0。当PUPAE、PUPBE、PUPEE被设置为1时,A口、B口、E口具有内部上拉功能;为0时,上拉无效。当A口、B口、E口为地址/数据总线时,PUPAE和PUPBE无效。 (3)A口、B口、E口降功率驱动控制寄存器RDRIV RDRIV为8位寄存器,复位后的值为0,此时,A口、B口、E口驱动保持全功率;当RDPA、RDPB、RDPE为1时,A口、B口、E口输出引脚的驱动功率下降 (4)数据寄存器PORTA、PORTB、PORTE PORTA、PORTB、PORTE均为8位寄存器,复位后的值为0,端口引脚输出低电平;要使引脚输出高电平,相应端口对应位应该置1。 由于PE0是/XIRQ、PE1是IRQ,因此,PE0和PE1只能设置为输入。

飞思卡尔智能车竞赛策略和比赛方案综述

飞思卡尔智能车竞赛策略和比赛方案综述 一、竞赛简介 起源: “飞思卡尔杯”智能车大赛起源于韩国,是韩国汉阳大学汽车控制实验室在飞思卡尔半导体公司资助下举办的以HCSl2单片机为核心的大学生课外科技竞赛。组委会提供一个标准的汽车模型、直流电机和可充电式电池,参赛队伍要制作一个能够自主识别路径的智能车,在专门设计的跑道上自动识别道路行驶,谁最快跑完全程而没有冲出跑道并且技术报告评分较高,谁就是获胜者。其设计内容涵盖了控制、模式识别、传感技术、汽车电子、电气、计算机、机械、能源等多个学科的知识,对学生的知识融合和实践动手能力的培养,具有良好的推动作用。 全国大学生“飞思卡尔”杯智能汽车竞赛是在规定的模型汽车平台上,使用飞思卡尔半导体公司的8位、16位微控制器作为核心控制模块,通过增加道路传感器、电机驱动电路以及编写相应软件,制作一个能够自主识别道路的模型汽车,按照规定路线行进,以完成时间最短者为优胜。因而该竞赛是涵盖了控制、模式识别、传感技术、电子、电气、计算机、机械等多个学科的比赛。 该竞赛以飞思卡尔半导体公司为协办方,自2006年首届举办以来,成功举办了五届,得到了教育部吴启迪副部长、张尧学司长及理工处领导、飞思卡尔公司领导与各高校师生的高度评价,已发展成全国30个省市自治区200余所高校广泛参与的全国大学生智能汽车竞赛。2008年第三届被教育部批准列入国家教学质量与教学改革工程资助项目中9个科技人文竞赛之一(教高函[2007]30号文,附件2),2009年第四届被邀申请列入国家教学质量与教学改革工程资助项目。 分赛区、决赛区比赛规则 在分赛区、决赛区进行现场比赛规则相同,都分为初赛与决赛两个阶段。在计算比赛成绩时,分赛区只是通过比赛单圈最短时间进行评比。决赛区比赛时,还需结合技术报告分数综合评定。 1.初赛与决赛规则 1)初赛规则 比赛场中有两个相同的赛道。 参赛队通过抽签平均分为两组,并以抽签形式决定组内比赛次序。比赛分为两轮,两组同时在两个赛道上进行比赛,一轮比赛完毕后,两组交换场地,再进行第二轮比赛。在每轮比赛中,每辆赛车在赛道上连续跑两圈,以计时起始线为计时点,以用时短的一圈计单轮成绩;每辆赛车以在两个单轮成绩中的较好成绩为赛车成绩;计时由电子计时器完成并实时在屏幕显示。 从两组比赛队中,选取成绩最好的25支队晋级决赛。技术评判组将对全部晋级的赛车进行现场技术检查,如有违反器材限制规定的(指本规则之第一条)当时取消决赛资格,由后备首名晋级代替;由裁判组申报组委会执委会批准公布决赛名单。 初赛结束后,车模放置在规定区域,由组委会暂时保管。

飞思卡尔智能车比赛个人经验总结

先静下心来看几篇技术报告,可以是几个人一起看,边看边讨论,大致了解智能车制作的过程及所要完成的任务。 看完报告之后,对智能车也有了大概的了解,其实总结起来,要完成的任务也很简单,即输入模块——控制——输出。 (1)输入模块:各种传感器(光电,电磁,摄像头),原理不同,但功能都一样,都是用来采集赛道的信息。这里面就包含各种传感器的原理,选用,传感器电路的连接,还有传感器的安装、传感器的抗干扰等等需要大家去解决的问题。 (2)控制模块:传感器得到了我们想要的信息,进行相应的AD转换后,就把它输入到单片机中,单片机负责对信息的处理,如除噪,筛选合适的点等等,然后对不同的赛道信息做出相应的控制,这也是智能车制作过程中最为艰难的过程,要想出一个可行而又高效的算法,确实不是一件容易的事。这里面就涉及到单片机的知识、C语言知识和一定的控制算法,有时为了更直观地动态控制,还得加入串口发送和接收程序等等。 (3)输出模块:好的算法,只有通过实验证明才能算是真正的好算法。经过分析控制,单片机做出了相应的判断,就得把控制信号输出给电机(控制速度)和舵机(控制方向),所以就得对电机和舵机模块进行学习和掌握,还有实现精确有效地控制,又得加入闭环控制,PID算法。 明确了任务后,也有了较为清晰的控制思路,接下来就着手弄懂每一个模块。虽然看似简单,但实现起来非常得不容易,这里面要求掌握电路的知识,基本的机械硬件结构知识和单片机、编程等计算机知识。最最困难的是,在做的过程中会遇到很多想得到以及想不到的事情发生,一定得细心地发现问题,并想办法解决这些问题。 兴趣是首要的,除此之外,一定要花充足的时间和精力在上面,毕竟,有付出就会有收获,最后要明确分工和规划好进度。

第四届全国大学生“飞思卡尔”杯智能汽车竞赛

比赛规则与赛场纪律 参赛选手须使用竞赛秘书处统一指定并负责采购竞赛车模套件,采用飞思卡尔半导体公司的8位、16位微控制器作为核心控制单元,自主构思控制方案进行系统设计,包括传感器信号采集处理、动力电机驱动、转向舵机控制以及控制算法软件开发等,完成智能车工程制作及调试,于指定日期与地点参加各分赛区的场地比赛,在获得决赛资格后,参加全国决赛区的场地比赛。参赛队伍之名次(成绩)由赛车现场成功完成赛道比赛时间为主,技术报告、制作工程质量评分为辅来决定。大赛分为光电与摄像头两个赛题组,在车模中使用透镜成像进行道路检测方法属于摄像头赛题组,除此之外则属于光电赛题组。 竞赛秘书处制定如下比赛规则适用于各分赛区预赛以及全国总决赛。在实际可操作性基础上力求公正与公平参与。秘书处将邀请独立公证人监督现场赛事及评判过程。 一、器材限制规定 1. 须采用统一指定的车模,细节及改动限制见附件一; 2. 须采用飞思卡尔半导体公司的 8 位、 16 位处理器 ( 单核 ) 作为唯一的微控制器,推荐使用 9S12XS128 , 9S08AW60 微控制器。有关细节及其它电子器件使用的限制见附件二; 3. 参加光电赛题组中不允许传感器获取道路图像信息进行路径检测,参加摄像头赛题组可以使用光电管作为辅助检测手段. 其他事项 ?如果损毁车模中禁止改动的部件,需要使用相同型号的部件替换; ?车模改装完毕后,尺寸不能超过:250mm 宽和400mm长。 二、有关赛场的规定 1. 赛道基本参数(不包括拐弯点数、位置以及整体布局)见附件三; 2. 比赛赛道实际布局将在比赛当日揭示,在赛场内将安排采用制作实际赛道的材料所做的测试赛道供参赛队进行现场调试; 三、裁判及技术评判 竞赛分为分赛区和全国总决赛两个阶段。其中全国总决赛阶段是在竞赛组委会和秘书处指导下,由决赛承办学校成立竞赛执行委员会,下辖技术租、裁判组和仲裁委员会,统一处理竞赛过程中遇到的各类问题。 所有竞赛组织委员会工作人员,包括技术评判组及现场裁判组人员均不得参与任何针对个别参赛队的指导或辅导工作(提供微控制器培训除外),不得泄

飞思卡尔智能车程序

Main.c #include /* common defines and macros */ #include /* derivative information */ #pragma LINK_INFO DERIVATIVE "mc9s12db128b" #include "define.h" #include "init.h" // variable used in video process volatile unsigned char image_data[ROW_MAX][LINE_MAX] ; // data array of picture unsigned char black_x[ROW_MAX] ; // 0ne-dimensional array unsigned char row ; // x-position of the array unsigned char line ; // y-position of the array unsigned int row_count ; // row counter unsigned char line_sample ; // used to counter in AD unsigned char row_image ; unsigned char line_temp ; // temperary variable used in data transfer unsigned char sample_data[LINE_MAX] ; // used to save one-dimension array got in interruption // variables below are used in speed measure Unsigned char pulse[5] ; // used to save data in PA process Unsigned char counter; // temporary counter in Speed detect Unsigned char cur_speed; // current speed short stand; short data; unsigned char curve ; // valve used to decide straight or turn short Bounds(short data); short FuzzyLogic(short stand); /*----------------------------------------------------------------------------*\ receive_sci \*----------------------------------------------------------------------------*/ unsigned char receive_sci(void) // receive data through sci { unsigned char sci_data; while(SCI0SR1_RDRF!=1); sci_data=SCI0DRL; return sci_data; } /*----------------------------------------------------------------------------*\ transmit_sci \*----------------------------------------------------------------------------*/ void transmit_sci(unsigned char transmit_data) // send data through sci { while(SCI0SR1_TC!=1); while(SCI0SR1_TDRE!=1);

相关文档
最新文档