第五届飞思卡尔智能车电磁组程序

更新时间:2024-03-04 23:24:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

第五届飞思卡尔智能车电磁组获奖程序

MC9S12XS128单片机、用前置线圈检测磁感线、用无线蓝牙采集数据、干簧管检测起跑线磁铁。

#include /* common defines and macros */

#include \ /* derivative-specific definitions */ #include

/************************************************************************************

一· 全局变量声明模块

*************************************************************************************/

typedef unsigned char INT8U; typedef unsigned int INT16U;

typedef int INT32; typedef struct {

INT8U d; //存放这一次AD转换的值 }DATA;

/**************************************************** 全局变量声明区

*****************************************************/

DATA data[6]={0}; //全局变量数组,存放赛道AD转换最终结果 INT8U a[6][8]={0}; //全局变量用来存放赛道AD转换中间结果 INT8U cross0,cross1; //记录十字叉线

#define LED PORTA_PA7 #define LED_CS PORTA_PA0 byte START ;

INT16U dianji0;//用来存放上次电机转速PWM,来判断是否减速 #define duojmax 9200 //向左转向最大值 #define duojmid 8400 //打在中间

#define duojmin 7600 //向右转向最小值 #define duojcs 8000; #define dianjmax 1200 #define dianjmin 10 #define dianjmid 600

static INT8U look=0,look1=0;

int road_change[100]={0}; //判断赛道情况数组 int roat_change0;

int *r_change0; //指向数组最后一位 int *r_change1; //指向数组倒数第二位

int sum_front=0,sum_back=0; //分别存储数组前后两部分的和 INT16U waittime=0;

INT8U choise; //读拨码开关数值

/******************************速度测量参数定时********************************/

#define PIT0TIME 800 //定时0初值: 设定为 4MS 测一次速度,采一次AD值 #define PIT1TIME 1390 //定时1初值: 设定为 7ms定时基值

/*******************************脉冲记数变量*******************************/ static INT16U PulseCnt;//最终的脉冲数

/******************************电机PID变量*********************************/

float speed_return_m ; struct {

int error0; int error1; int error2; int speed; int chage;

float q0,q1,q2,Kp,Kd,Ki; }static SpeedPid;

/********************************速度变量设定*******************************/ INT8U speedmax ; //直道加速 INT8U speedmin ; //急转弯刹车 INT8U speedmid ; //弯道内部限速 INT8U speedaveg ; //

INT8U breaktime ; //刹车时间

//////////////////////////////////////////////////////////////////////////// #define speederror_min 2 //允许的最小误差 static int NowSpeed;

static int speed_control; //存储pid输出值 static int speed_return;

/*******************************舵机PID参数******************************/

struct{

int error0;

int error1; int error2; int chage;

float Kp,Kd,Ki; }PositionPid;

int change; static INT16U angle_left [52]={8550,8562,8574,8586,8598,8610,8622,8634,8646,8658,8670,8682,8694,8706,8718,8730,8742,8754,8766,8778,8790,8802,8814,8826,8838,8850,8862,8874,8886,8898,8910,8922,8934,8946,8958,8970,8982,8994,9006,9018,9030,9042,9054,9066,9078,9090,9102,9114,9126,9138,9150,9150}; static INT16U angle_right[52]={8250,8238,8226,8214,8202,8190,8178,8166,8154,8142,8130,8118,8106,8094,8082,8070,8058,8046,8034,8022,8010,7998,7986,7974,7962,7950,7938,7926,7914,7902,7890,7878,7866,7854,7842,7830,7818,7806,7794,7782,7770,7758,7746,7734,7722,7710,7698,7686,7674,7662,7650,7650};

static INT16U *angle_l=angle_left ,*angle_r=angle_right;

static INT16U angle_control=duojmid; //舵机PWM最终控制量 static INT16U angle_control0=duojmid; static INT16U angle_control1=duojmid; static INT16U break_pwm=0; INT16U angle_return;

/****************************lcd液晶显示变量定义**************************/ #define LCD_DATA PORTB

#define LCD_RS PORTA_PA4 //PA6 #define LCD_RW PORTA_PA5 //PA7 #define LCD_E PORTA_PA6 //PA7 INT8U start[]={\INT8U date[]={\INT8U time[]={\INT16U Counter=0;

INT8U Counter0=0,select=0,min=0; INT8U Counter1=0; INT8U LCD_choice;

/**************************标志变量区*************************************/ INT8U stop_flag=0; INT8U start_flag=0; INT8U backflag=0; INT8U AD_start ; INT8U zhijwan=0 ; INT8U shizi=0;

/************************************************************************************

二· 初始化函数模块

*************************************************************************************/

/**************************************************************

1. 芯片初始化--------MCUInit()

**************************************************************/ void MCUInit(void){

//////////////////////////////////////////////////////////////////////////////////////////

// ********总线周期计算方法 ******** // // fBUS=fPLL/2 //

// fvoc=2*foscclk*(synr+1)/(refdv+1) //

// PLL=2*16M*(219+1)/(69+1)=96Mhz //

// //

/////////////////////////////////////////////////////////////////////////////////////////// CLKSEL=0X00;

PLLCTL_PLLON=1; //锁相环控制 SYNR = 0X40|0X05; REFDV =0X80|0X01; POSTDIV=0X00;

while( CRGFLG_LOCK != 1); //等待锁相环时钟稳定,稳定后系统总线频率为24MHz CLKSEL_PLLSEL = 0x01; //选定锁相环时钟 PLLCTL=0xf1; //锁相环控制

//时钟合成 fpllclk=2*foscclk*(synr+1)/(refdv+1) //synr=2;refdv=1;外部时钟foscclk=16mb //fpllclk=48mb 总线时钟24mb

// CRGFLG=0x40; //时钟复位控制

// CRGINT=0x00 ; //时钟复位中断使能

// CLKSEL =0xc0; //时钟选择 //COPCTL =0x00; // ARMCOP =0x00; //看门狗复位 // RTICTL =0x00; //实时中断

}

/**************************************************************

2. AD转换初始化--------ADCInit()

**************************************************************/ void ADCInit(void) {

ATD0CTL1=0x00;

ATD0CTL2=0x40; //0100,0000,自动清除使能控制位,忽略外部触发 //转换结束允许中断,中断禁止

ATD0CTL3=0xA4; //0100,0100,转换序列长度为4; FIFO模式,冻结模式下继续转换 ATD0CTL4=0x05; //00001000,8位精度,PRS=5,ATDCLOCK=BusClock(24mb)/(5+1)*2,约为2MHz,采样周期位4倍AD周期 ATD0DIEN=0x00; //输入使能禁止 }

/**************************************************************

3. PWM初始化--------PWMInit()

**************************************************************/

void PWMInit(void) //PWM初始化 {

//总线频率24mb

//1. 选择时钟:PWMPRCLK,PWMSCLA,PWMSCLB,PWMCLK PWME=0x00; //PWM通道关闭

PWMPRCLK=0x01; //00010011时钟源A=BusClockA/2=48M/2=24MB;

//低位clockA:01,45;高位clockB:23,67 时钟源B=48/1=48MB

PWMSCLA =2; //ClockSA=ClockA/2/2=24MB/4=6MB PWMSCLB =2; //ClockSB=ClockB/2/2=12MBHz PWMCLK =0xFF; //通道均级联,均用SA,SB ,且都为6MB

//2. 选择极性: PWMPOL PWMPOL =0xff; //电机正反转寄存器(PWMPOL)起始输出为高电平

speedmax =70; //直道加速 speedmin =0 ; //急转弯刹车 speedmid =32; //弯道内部限速 speedaveg=40; //平均速度 breaktime=13 ; //刹车时间 backflag=1; //采用反转刹车

break_pwm=1500; //反转刹车PWM值

};break;

/******方案9直道速度约为:3.222m/s,弯道保持的变速方案4******/

case 9:{

speedmax =75; //直道加速 speedmin =0 ; //急转弯刹车 speedmid =32; //弯道内部限速 speedaveg=40; //平均速度 breaktime=14 ; //刹车时间 backflag=1;

break_pwm=1800; //反转刹车PWM值 };break;

/******方案10直道速度约为:3.580m/s,弯道保持的变速方案5******/

case 10:{

speedmax =80; //直道加速 speedmin =0 ; //急转弯刹车 speedmid =32; //弯道内部限速 speedaveg=40; //平均速度 breaktime=15; //刹车时间 backflag=1; //采用反转刹车

break_pwm=1800; //反转刹车PWM值 };break;

/******方案11直道速度约为:3.580m/s,弯道保持的变速方案5******/

case 11:{

speedmax =85; //直道加速 speedmin =0 ; //急转弯刹车 speedmid =32; //弯道内部限速 speedaveg=40; //平均速度 breaktime=17; //刹车时间 backflag=1; //采用反转刹车

break_pwm=1800; //反转刹车PWM值 };break;

/******方案12直道速度约为:3.580m/s,弯道保持的变速方案5******/

case 12:{

speedmax =90; //直道加速 speedmin =0 ; //急转弯刹车 speedmid =32; //弯道内部限速 speedaveg=40; //平均速度 breaktime=18 ; //刹车时间 backflag=1; //采用反转刹车

break_pwm=1900; //反转刹车PWM值 };break;

/******方案13直道速度约为:3.580m/s,弯道保持的变速方案5******/

case 13:{

speedmax =100; //直道加速 speedmin =0 ; //急转弯刹车 speedmid =35; //弯道内部限速 speedaveg=45; //平均速度 breaktime=20 ; //刹车时间 backflag=1; //采用反转刹车

break_pwm=2000; //反转刹车PWM值 };break;

/******其它情况 直道速度约为:3.580m/s,弯道保持的变速方案******/

default:{

speedmax =100; //直道加速 speedmin =0 ; //急转弯刹车 speedmid =35; //弯道内部限速 speedaveg=45; //平均速度 breaktime=20 ; //刹车时间 backflag=1; //采用反转刹车

break_pwm=2000; //反转刹车PWM值 }break; }

return ; }

void delay(INT8U k) { // k=1 时约为1ms定时

INT8U i; INT16U j;

for(i=0;i<40;i++)

for(j=0;j<100*k;j++) asm(\ }

//----------------------------------------------------- //延时 based on an 48MHz clock //delay for 100us

void delay_100us(void) {

INT8U i,j;

for(i=0;i<6;i++) for(j=0;j<100;j++) asm(\}

//delay for 5ms

void delay_5ms(void) {

INT8U I; INT16U J;

for(I=0;I<6;I++) for(J=0;J<5000;J++) asm(\}

void start_delay(void) { //开始起跑延时 Counter=0;

while(Counter<100)asm(nop); start_flag=1; //开始起跑 Counter=0; //计数器置零 select=0; //秒计时器置零 }

/************************************************************************* 1602液晶显示模块程序

DM-162采用标准的14脚接口,其中VSS为地电源,VDD接5V正电源,V0为液晶显示器

对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会 产生\鬼影\,使用时可以通过一个10K的电位器调整对比度。RS为寄存器选择,高电 平时选择数据寄存器、低电平时选择指令寄存器。RW为读写信号线,高电平时进行 读操作,低电平时进行写操作。当RS和RW共同为低电平时可以写入指令或者显示地 址,当RS为低电平RW为高电平时可以读忙信号,当RS为高电平RW为低电平时可以写

入数据。E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令; D0~D7为8位双向数据线。

**************************************************************************/ /*液晶初始化设置函数LCD_Write_Cmd()*/

void LCD_Write_Cmd(uchar cmd) {

LCD_RS=0; //指令寄存器选择 LCD_RW=0; //1:读;2:写入指令 LCD_E=0;

LCD_DATA=cmd;

LCD_E=1;//当E端由低电平跳变成高电平时,液晶模块执行命令; delay_100us(); //显示地址用11个延时共约1.1ms delay_100us(); delay_100us(); delay_100us(); delay_100us(); delay_100us(); delay_100us(); delay_100us(); delay_100us(); delay_100us(); delay_100us(); LCD_E=0;

LCD_RS=1; //指令寄存器选择 LCD_RW=0; //1:读;2:写入指令 }

/*.液晶初始化LCD_INIT()*/ void LCD_init(void){ // delay_5ms();

LCD_Write_Cmd(0x38); //1.设置16*2显示,5*7点阵,八位数据接口 delay_5ms();

LCD_Write_Cmd(0x0c); //2.开显示,不显示光标 delay_5ms();

LCD_Write_Cmd(0x06); //3.当读或写一个字符后地址指针加一 delay_5ms();

LCD_Write_Cmd(0x01); //4.显示清屏 delay_5ms();

LCD_Write_Cmd(0x80); //5.从led第一行左边第一个位开始显示 delay_5ms(); }

//显示字形子函数

void LCD_Write_Data(uchar dat) {

LCD_RS=1; LCD_RW=0; LCD_E=0;

LCD_DATA=dat; LCD_E=1; delay_100us();

delay_100us(); //显示数据用一个延时 LCD_E=0;

LCD_RS=0; //电平恢复 LCD_RW=0; }

//LCM显示光标位置,行:ROW 列col void Write_Position(uchar row,uchar col) {

col &= 0x0f; //位屏蔽,限制X不能大于15,Y不能大于1 row &= 0x01; //row最大为一 if(row)

col |= 0x40; //当要显示第二行时:地址码+0x40

LCD_Write_Cmd(col|0x80); //这里不检测忙信号,发送地址码,显示码D7位必须为1 }

//按指定位置显示一串字符

void LCD_Disp_String(uchar row, uchar col, uchar *p) { Write_Position(row,col); while((*p)!='\\0') //字符串未结束就一直写 { LCD_Write_Data(*p); p++; } }

//显示部分主函数 void LCD_Disp(void){

LCD_Disp_String(0,0,start) ; //显示字符串 LCD_Write_Cmd(0x01); LCD_Disp_String(0,3,date); LCD_Disp_String(1,4,time);

本文来源:https://www.bwwdw.com/article/doxa.html

Top