智能车电磁组完整程序
电磁组智能车原理

电磁组智能车原理智能车技术是近年来科技领域的热门话题之一,其中电磁组智能车更是备受关注。
本文将详细介绍电磁组智能车的原理,以及其在实践中的应用。
一、电磁组智能车的工作原理电磁组智能车是一种基于电磁感应技术的智能交通工具。
它主要依靠车身上的电磁感应器,通过感知周围电磁场的变化来判断出前方障碍物的位置和距离。
其工作原理如下:1. 电磁感应器电磁感应器通常由多个磁场传感器组成,布置在车身的前端。
这些传感器可以感知到周围环境中的电磁场变化,并将这些变化转化为电信号。
2. 信号处理电磁感应器采集到的电信号将通过信号处理模块进行处理。
该模块会对信号进行放大、滤波和分析,从而提取出有用的信息。
3. 障碍物检测通过信号处理后,可以获得前方障碍物的位置和距离信息。
智能车的控制系统会根据这些信息判断前方是否存在障碍物,从而做出相应的行驶决策。
4. 行驶决策根据障碍物的位置和距离信息,智能车的控制系统将做出行驶决策。
当前方没有障碍物时,智能车可以保持匀速直行;当有障碍物出现时,智能车会自动减速或变换方向以避让。
二、电磁组智能车的应用电磁组智能车在交通领域具有广泛的应用前景,以下是一些典型的应用场景:1. 智能巡航电磁组智能车可以通过感知前方障碍物的位置和距离,实现智能巡航功能。
它能够根据道路情况自动控制车速,避免与其他车辆发生碰撞。
2. 自动泊车电磁组智能车的电磁感应器还能够感知到停车位周围的电磁场变化。
通过对这些变化进行分析,智能车可以准确地判断出停车位的位置和大小,从而实现自动泊车功能。
3. 避障导航电磁组智能车在进行导航时,可以通过电磁感应器感知到道路上的障碍物。
根据障碍物的位置和距离信息,智能车可以选择合适的行驶路径,避免与障碍物发生碰撞。
4. 特殊环境下的应用电磁组智能车的电磁感应器对于特殊环境下的感知也具有一定的优势。
例如,在较为黑暗的地下停车场中,智能车可以借助电磁感应器的辅助实现车辆的准确定位和导航。
智能循迹小车电磁组C语言源代码(stc12c5a芯片)

智能循迹小车电磁组C语言源代码(stc12c5a芯片)#include#include#define FOSC 18432000L#define BAUD 9600#define ADC_POWER 0x80 //ADC power control bit 电源控制位#define ADC_FALG 0x10 //ADC complete flag 标志位#define ADC_START 0x08 //ADC start control bit 启动控制位#define ADC_SPEEDLL 0x00 //420 clocks#define ADC_SPEEDL 0x20 //280 clocks#define ADC_SPEEDH 0x40 //140 clocks#define ADC_SPEEDHH 0x60 //70 clockstypedef unsigned char BYTE;typedef unsigned int WORD;float bj1,bj2;int cg1,cg2,go;go=0x05; //电机驱动设为0101BYTE ch=0;void InitADC();void Delay(WORD n);void kongzhi();void PWM();void GetADCResult(BYTE ch);void main(){P0=0X00; //P0口的LED灯全亮InitADC(); //初始化ADIE=0xa0;PWM(); //调用PWM函数while(1){GetADCResult(ch); //读取AD值并赋值给变量kongzhi(); //调用控制函数}}void GetADCResult(BYTE ch) //读取AD的函数{ADC_CONTR &=!ADC_FALG;for(ch=0;ch<2;ch++){switch(ch){case 0: ADC_CONTR=0xe9; //定义P1.1为AD转换 1110 1001 _nop_();_nop_();_nop_();_nop_();while(!(ADC_CONTR&ADC_FALG));ADC_CONTR&=~ADC_FALG; //清除falg位cg1=ADC_RES; //把传到P1.1口的AD值(二进制)赋值给cg1 break;case 1: ADC_CONTR=0xea; //定义P1.2口为AD转换1110 1010_nop_();_nop_();_nop_();_nop_();while(!(ADC_CONTR&ADC_FALG));ADC_CONTR&=~ADC_FALG;cg2=ADC_RES; //把传到P1.2口的AD值(二进制)赋值给cg2 break;default: break;}}if(++ch>=2) ch=0;}void InitADC() //初始化AD函数{P1ASF=0XE7; // 1110 0111 //定义为AD转换的IO口P1M0=0xE7 ; // P1.7-P1.0:1110 0111P1M1=0xE7 ; // P1.7-P1.0:1110 0111ADC_RES=0;ADC_CONTR=0xe9;Delay(2);}void Delay(WORD n) //延时函数{WORD x;while(n--){x=5000;while(x--);}}void kongzhi(){bj1=((cg2*5/256)-(cg1*5/256)); //两个传感器所检测到的电压的差值bj2=((cg1*5/256)-(cg2*5/256));if((bj1<1)&&(bj2<1)) //全速{CCAP0H=0x08; //左轮CCAP1H=0x00; //右轮P3=go;}else if(bj1>4/3) //强左拐{CCAP0H=0x40; //左轮CCAP1H=0x00; //右轮P3=go;}else if(bj1>1&&bj1<4/3) //微左拐{CCAP0H=0x22; //左轮CCAP1H=0x00; //右轮P3=go;}else if(bj2>1&&bj2<4/3) //微右拐{CCAP0H=0x00; //左轮CCAP1H=0x18; //右轮P3=go;}else if(bj2>4/3) //强右拐{CCAP0H=0x00; //左轮CCAP1H=0x35; //右轮P3=go;}}void PWM(){CCON=0;CL=0;CH=0;CMOD=0X02;CCAP0H=CCAP0L=0X80;CCAPM0=0X42; //允许比较器功能、PWM脉宽输出CCAP1H=CCAP1L=0X80;PCA_PWM0=0x00; //组成9位P1.3PCA_PWM1=0x00; //组成9位P1.4CCAPM1=0X42;CR=1; //启动PCA计数器阵列}。
电磁智能车程序第五届

{int dty01,dty23;
if(ch0>=ch1&&ch1>=ch1_mid){
PWMDTY01=1550; // PWMDTY23=382; PWMDTY23=500;
}else if(ch0>ch1&&ch1>=10) { /* if(PWMDTY23==382) {
PWMDTY23=1000; PWMDTY45=382;
//7:1-外部触发,65:00-8 位精度,4:放电,3210:ch //启动 A/D 转换,快速清零,无等待模式,禁止外部触发, 中断禁止 //右对齐无符号,每次转换 13 个序列, No FIFO, Freeze 模式下继续转 //765:采样时间为 4 个 AD 时钟周期,ATDClock=[BusClock*0.5]/[PRS+1] //6:0 特殊通道禁止,5:1 连续转换 ,4:1 多通道轮流采样 //禁止数字输入
1550,
1580,1630,1655,1670,1685,1700,
};
unsigned int angle_table3[13]={
1400,1410,1420,1430,1450,1460,
1550,
1620,1630,1670,1680,1690,1700,
};
unsigned int angle_table4[13]={
unsigned int angle_table1[13]={
1400,1440,1480,1500,1520,1530,
1550,
1570,1590,1620,1640,1680,1700,
};
unsigned int angle_table2[13]={
【精品】车模电磁组方案

摘要本文以智能汽车为模型,基于电磁传感器,采用MC9S12XS128微控制器,构建自主寻迹控制系统.系统的硬件设计采用模块化的设计方法.主要包括:微控制器模块、电源模块、光电传感器模块、速度检测模块、舵机驱动模块,电机驱动模块。
系统的软件设计采用结构化程序设计方法。
从结构上看,软件程序主要包括以下几个部分:主体循环程序,增量式PID速度控制程序,中断服务程序,舵机控制算法程序,速度控制算法程序以及一些其他控制程序。
软件设计重点研究PID控制算法、PWM控制、模糊控制、闭环控制在该系统中的应用。
PID及PWM控制主要运用于电机的控制,模糊控制运用于道路信息的采集中,闭环控制系统是针对整个系统而构建的。
关键词:MC9S12XS128,电磁传感器,H桥,PID控制一、总体结构设计本模型车采用电感来判别跑道上的电磁引导线,通过MC9S12XS128单片机来控制模型车各个模块的工作。
路径识别系统电路由14个电感组成。
通过传感器的不同方位设计,来判断车的行进角度,速度加减,赛道预测等等。
路径识别模块会将当前采集到的一组信号值传递给微控制器。
转速测量模块采用光电编码器,安装在车尾部,用来测量模型车行驶过程中的瞬时速度。
测量出的瞬时速度将输入到单片机中,以帮助分析确定模型车下一步的速度、转角等。
为了能够及时设置调整一些重要的控制参数,如速度档位,需增加一个8路的拨码开关.总体设计分为控制系统设计、硬件设计、软件设计三大部分.1、控制系统设计智能车系统的控制结构是以微处理器为核心,车速控制器、直流电机和测速传感器构成一个闭环,该闭环的输入为路径判别后经模糊控制处理后的速度给定,输出直接驱动后轮;而舵机控制器构成一个控制系统通道,其输入为模糊处理后的路径转角偏差,输出直接控制前轮转向;最后以车体位置情况作为道路识别反馈控制器的输入,其输出直接与道路中心线参数比较从而构成一个大的闭环控制系统.在控制策略的选择方面,遵循以下几点原则:(1)对于驱动电机,必须使用闭环控制。
电磁组程序

{
uint i,j;
for(i=k;i>0;i--)
for(j=9650;j>0;j--);
}
void SetBusCLK_32M(void)
{
CLKSEL=0x00; //disengage PLL to system
ATD0CTL5=0x30; //多通道转换
ATD0DIEN=0x00; //缓冲区无效,禁止输入
}
void PWM_init()
{
PWME=0x88; //6、7 通道级联,3、2通道级联
PWMPOL=0x88; //先输出高电平后输出低电平
PWMCLK=0x80; //6、7选择SB作为时钟源,2、3选择B作为时钟源
PWMPRCLK=0x40; //B clock=1/16 BUS Clock ,2、3 chanel's frequency is 2 MHz
PWMCAE=0x00; //二者都选择左对齐显示波形
PWMCTL=0xa0; // 级联方式使能
PWMSCLB=20; //Clock SB = Clock B / (2 * PWMSCLB)设置为 50K HZ ,6、7 chanel --50K Hz
ATD0CTL3=0xc0; //right justified result data.,conversion 8 channes(结果寄存器数据右对齐,一个转换序列由8个ATD转换次数)
ATD0CTL4=0x01; //4 ATD conversion clock cycles,conversion cycle is 1/2us ATDClock=8MHz
第五届飞思卡尔智能车电磁组程序

第五届飞思卡尔智能车电磁组获奖程序MC9S12XS128单片机、用前置线圈检测磁感线、用无线蓝牙采集数据、干簧管检测起跑线磁铁。
#include <hidef.h> /* common defines and macros */#include "derivative.h" /* derivative-specific definitions */#include <stdio.h>/****************************************************************************** ******一·全局变量声明模块******************************************************************************* ******/typedef unsigned char INT8U;typedef unsigned int INT16U;typedef int INT32;typedef struct {INT8U d; //存放这一次AD转换的值}DATA;/****************************************************全局变量声明区*****************************************************/DA TA data[6]={0}; //全局变量数组,存放赛道AD转换最终结果INT8U a[6][8]={0}; //全局变量用来存放赛道AD转换中间结果INT8U cross0,cross1; //记录十字叉线#define LED PORTA_PA7#define LED_CS PORTA_PA0byte START ;INT16U dianji0;//用来存放上次电机转速PWM,来判断是否减速#define duojmax 9200 //向左转向最大值#define duojmid 8400 //打在中间#define duojmin 7600 //向右转向最小值#define duojcs 8000;#define dianjmax 1200#define dianjmin 10#define dianjmid 600static 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,8 742,8754,8766,8778,8790,8802,8814,8826,8838,8850,8862,8874,8886,8898,8910,8922,8934,894 6,8958,8970,8982,8994,9006,9018,9030,9042,9054,9066,9078,9090,9102,9114,9126,9138,9150,9 150};static INT16U angle_right[52]={8250,8238,8226,8214,8202,8190,8178,8166,8154,8142,8130,8118,8106,8094,8 082,8070,8058,8046,8034,8022,8010,7998,7986,7974,7962,7950,7938,7926,7914,7902,7890,787 8,7866,7854,7842,7830,7818,7806,7794,7782,7770,7758,7746,7734,7722,7710,7698,7686,7674,7 662,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 //PA7INT8U start[]={"WELCOME TO LZJTU"};INT8U date[]={"2011-3-15 TUS"};INT8U time[]={"00:00:00"};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){A TD0CTL1=0x00;A TD0CTL2=0x40; //0100,0000,自动清除使能控制位,忽略外部触发//转换结束允许中断,中断禁止A TD0CTL3=0xA4; //0100,0100,转换序列长度为4;FIFO模式,冻结模式下继续转换A TD0CTL4=0x05; //00001000,8位精度,PRS=5,ATDCLOCK=BusClock(24mb)/(5+1)*2,约为2MHz,采样周期位4倍AD周期A TD0DIEN=0x00; //输入使能禁止}/**************************************************************3. PWM初始化--------PWMInit()**************************************************************/void PWMInit(void) //PWM初始化{//总线频率24mb//1. 选择时钟:PWMPRCLK,PWMSCLA,PWMSCLB,PWMCLKPWME=0x00; //PWM通道关闭PWMPRCLK=0x01; //00010011时钟源A=BusClockA/2=48M/2=24MB;//低位clockA:01,45;高位clockB:23,67 时钟源B=48/1=48MBPWMSCLA =2; //ClockSA=ClockA/2/2=24MB/4=6MBPWMSCLB =2; //ClockSB=ClockB/2/2=12MBHzPWMCLK =0xFF; //通道均级联,均用SA,SB ,且都为6MB//2. 选择极性:PWMPOLPWMPOL =0xff; //电机正反转寄存器(PWMPOL)起始输出为高电平//3. 选择对齐方式:PWMCAEPWMCAE=0x00; //输出左对齐//4.PWMCTL PWM控制寄存器PWMCTL=0xF0; //01,23,45,67通道都级连,输出风别由1,3,5,7口控制//5. 使能PWM通道; PWME//6. 对占空比和周期编程//周期计算公式:输出周期=通道时钟周期*(PWMPERX+1)//占空比:=(PWMPERYX+1)/(PWMPERX+1)//开始时刻应使舵机打直,电机不转//1.通道45用来控制舵机PWMPWMPER45=60000-1; //PWM01=6MB/(60000)=100HzPWME_PWME5 =0; //舵机PWM通道开//2.通道23用来控制电机PWM1,通道01用来作为电机PWM2PWMPER23=1200-1;//电机正转PWM周期初始化。
电磁组入门程序

#include "common.h"#include "include.h"/*!* @brief main函数* @since v5.0*/float kp=0; //PI 调节的比例常数float ek=0; //偏差e[k]float ukl=0; //u[k]float ukr=0;int i=0;int j=0;int adjust; //调节器输出调整量int AD1[100];int AD2[100];int ad=0;int count=0;int sum1=0;int flag1=0;int flag2=0;void main(){// float kp; //PI 调节的比例常数// float ek; //偏差e[k]// float ukl; //u[k]// float ukr;// int i=0;// int j=0;// int adjust; //调节器输出调整量// int AD1[100];// int AD2[100];// int ad;// int count;// int sum;adc_init (ADC0_SE0);adc_init (ADC0_SE3);tpm_pwm_init(TPM0, TPM_CH3,50,750);tpm_pwm_init(TPM2, TPM_CH0,20000, 0);tpm_pwm_init(TPM2, TPM_CH1,20000, 2300);kp=5000;while(1){for(i=0;i<100;i++){AD1[i]=adc_once(ADC0_SE0, ADC_8bit);AD2[i]=adc_once(ADC0_SE3, ADC_8bit);}for(i=0;i<99;i++){for(j=0;j<98;j++){if(AD1[j]>AD1[j+1]){ad = AD1[j];AD1[j] = AD1[j+1];AD1[j+1] = ad;}}}for(count=10;count<90;count++){sum1 += AD1[count];}ukl =(sum1/80);sum1=0;for(i=0;i<99;i++){for(j=0;j<98;j++){if(AD2[j]>AD2[j+1]){ad = AD2[j];AD2[j] = AD2[j+1];AD2[j+1] = ad;}}}for(count=10;count<90;count++){sum1 += AD2[count];}ukr = (sum1/80);sum1=0;if(ukl<100&&ukr<100&&ukl>ukr&&flag1==0&&flag2==0){flag1=1;}else if(ukl<100&&ukr<100&&ukl<ukr&&flag1==0&&flag2==0){flag2=1;}else{if(ukl>115||ukr>115){flag1=0;flag2=0;}}if(flag1==1&&flag2==0){tpm_pwm_duty(TPM0, TPM_CH3, 850);}else if(flag1==0&&flag2==1){tpm_pwm_duty(TPM0, TPM_CH3, 630);}else{ek=(ukl-ukr)/(ukl*ukr);adjust=(int)(750+kp*ek);if(adjust>870){adjust=870;}if(adjust<630){adjust=630;}tpm_pwm_duty(TPM0, TPM_CH3, adjust);}}// Ki=KpT/Ti=0.8,微分系数Kd=KpTd/T=0.8,Td=0.0002,根据实验调得的结果确定这些参数}。
智能小车电磁组技术报告

4 硬件结构设计及实现-------------------------------------------------4
4.1 单片机----------------------------------------------------------------------------------------4 4.2 路径信息采集模块-------------------------------------------------------------------------4 4.3 舵机及电机驱动模块----------------------------------------------------------------------4 4.4 测速模块-------------------------------------------------------------------------------------4 4.5 电源系统-------------------------------------------------------------------------------------4 4.6 单片机最小系统电路----------------------------------------------------------------------4
根据电磁学,我们知道在导线中通入变化的电流(如按正弦规律变化的电 流),则导线周围会产生变化的磁场,且磁场与电流的变化规律具有一致性。如 果在此磁场中置一由线圈组成的电感,则该电感上会产生感应电动势,且该感应 电动势的大小和通过线圈回路的磁通量的变化率成正比。 由于在导线周围不同位 置, 磁感应强度的大小和方向不同,所以不同位置上的电感产生的感应电动势也 应该是不同。据此,则可以确定电感的大致位置。 首先,由毕奥-萨伐尔定律知:通有稳 恒电流I长度为L的直导线周围会产生磁场, 距离导线距离为r处P点 2 I 0 的磁感应强度为: B sin d 1 4 r ( 0 4 107 N / A2 ) 由此得 B
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include <hidef.h> /* common defines and macros */#include "derivative.h" /* derivative-specific definitions */int left1=0;int left2=0;int right1=0;int right2=0;int AR_LEFT=0;//left2-right2int AR_RIGHT=0;int CR=0;//左边相加减右边相加int preCR=0;int ppreCR=0;int mkp=0;int mki=0;int mkd=0;int ideal_speed=0; //设定速度int speed=0;int s_ideal0[6]={75,80,42,42,42,42}; //普通道、长直道、普通到弯、长直道到弯、弯内、偏离黑线int s_ideal1[6]={70,75,42,42,42,42};int s_ideal2[6]={62,70,42,40,41,40};int s_ideal3[6]={54,66,42,40,41,40};int table_mkp0[6]={30,30,30,30,30,30}; //ni 16.31 ,shun 15.16int table_mkp1[6]={25,25,25,25,25,25};int table_mkp2[6]={5,4,4,20,20,20};int table_mkp3[6]={4,4,4,10,8,9}; //稳定速度int table_mki0[6]={0,0,20,20,20,20};int table_mki1[6]={0,0,20,20,20,20};int table_mki2[6]={0,0,0,10,10,20};int table_mki3[6]={0,0,0,0,0,0};int table_mkd0[6]={0,0,0,0,0,0};int table_mkd1[6]={0,0,0,0,0,0};int table_mkd2[6]={0};int table_mkd3[6]={0,0,0,0,0,0};int s_table[6];int b_mkp[6]=0;int b_mki[6]=0;int b_mkd[6]=0;int table_rkp0[7]={5,3,2,550,550,550,8};//普通道中间、长直道低速、长直道高速、普到弯、直到弯、弯、普通道两边int table_rkp1[7]={7,5,4,450,450,400,9};int table_rkp2[7]={6,3,2,150,150,150,9};int table_rkp3[7]={5,3,2,150,150,150,9};int table_rkd0[7]={0,0,0,400,400,400,100};int table_rkd1[7]={0,0,0,500,500,500,100};int table_rkd2[7]={0,0,0,200,300,400,100};int table_rkd3[7]={0,0,0,200,300,400,100};int b_rkp[7]=0;int b_rkd[7]=0;int rkp=0;int rkd=0;int f=0;// pwmDTY要加的值int pref=0;int Pulse_count=0; //脉冲数int ganhuang=0;unsigned int ting=0;int i=0;int Flag_Chute=0; //道路标志int GeneralCtn=0;int CurveCtn=0;int ChuteCtn=0;int WANCtn=0;int Flag_gaosu=0;unsigned char Flag_Pwm;//知道转弯道标志int flag=0;/***********************//PLL超频到40MHZ****************/void PLL_Init(void) {CLKSEL=0X00;PLLCTL_PLLON=1;REFDV=0X80|0X01;SYNR=0X40|0X04;POSTDIV=0X00;asm nop;asm nop;while(!(CRGFLG_LOCK==1));CLKSEL_PLLSEL=1;}//延时函数cnt*1ms;void delay(unsigned int cnt) {unsigned int loop_i,loop_j;for(loop_i=0;loop_i<cnt;loop_i++) {loop_j=0x1300;while(loop_j--);}}/*******************************///////////////\\计数程序//\\\\\\\\\\\\\\\*********************************/void PACBInit() //PT7 获得脉冲值{PACTL=0X40; //PT7 PIN,PACN32 16BIT,Rising edge,NOT INTERRUPTTCTL3=0x40; //c-输入捕捉7 上升沿有效,TIE_C7I=0; //通道7 禁止中断TIOS_IOS7=0; //每一位对应通道的: 0 输入捕捉,1 输出比较PACNT = 0;}void RTI_init(void) //RTI 产生10ms 的中断定时{asm sei; //关闭中断RTICTL=0xC7; //中断周期设置10ms 中断一次(或者让RTICTL=0x59<为10.24ms 定时>)CRGINT_RTIE=1; //实时中断有效,一旦RTIF=1 则发出中断请求asm cli; //开放中断}//舵机初始化void PWM_rudder_init(void) {PWME_PWME3=0;PWME_PWME2=0;PWMPRCLK_PCKB=2;//CLOCKB=BUS/4=10MHz PWMSCLB=2;//CLOCCSB=10/(2*2)=2.5MHzPWMCTL_CON23=1;//组合PWM23PWMCLK_PCLK3=1;//PWM3使用SBPWMPER23=50000;//写PWM23的周期寄存器,周期是20ms PWMPOL_PPOL3=1;//极性为正PWMCAE_CAE3=0;//左对齐PWME_PWME3=1;//使能PWM23}//电机初始化void PWM_init_motor(void){ //电机初始化PWME_PWME0=0;PWME_PWME1=0;PWMPRCLK_PCKA=2; //Clock A=40M/4=10MPWMPOL_PPOL1=1;//通道1 正极性输出PWMCLK_PCLK1=0;//通道1 选择A 时钟PWMCAE_CAE1=0;//左对齐PWMCTL_CON01=1;PWMPER01=1000;//输出频率=10M/1000=10KhzPWMDTY01=0;//通道1 占空比为100/250PWME_PWME1=1;//通道1 使能PWME_PWME4=0;PWME_PWME5=0;PWMPRCLK_PCKA=1; //Clock A=40M/2=20MPWMPOL_PPOL5=1;//通道5 正极性输出PWMCLK_PCLK5=1;//通道5 选择SA 时钟PWMSCLA=1; //ClockSB=20M/(2*1)=10M PWMCAE_CAE5=0;//左对齐PWMCTL_CON45=1;PWMPER45=1000;//输出频率=10M/1000=10KhzPWMDTY45=0;//初始通占空比0PWME_PWME5=1;//通道5 使能}void AD_Init(void){A TD0CTL1=0x20; //选择AD通道为外部触发,10位精度,采样前不放电A TD0CTL2=0x40; //标志位自动清零,禁止外部触发, 禁止中断A TD0CTL3=0xA0; //右对齐无符号,每次转换4个序列, No FIFO, Freeze模式下继续转A TD0CTL4=0x09; //采样时间为4个AD时钟周期,PRS=9,A TDClock=40/(2*(9+1))2MHz A TD0CTL5=0x30; //特殊通道禁止,连续转换4个通道,多通道转换,起始通道为0转换A TD0DIEN=0x00; //禁止数字输入}/************************/////////检测起跑线\\\\\\\\\\\*****************/void Checkstart(){asm sei;TIOS_IOS0=0; //输入捕捉TSCR1=0X80;TSCR2=0X07;TCTL4=0X01;//上升沿捕捉TIE=0X01; //允许硬件中断asm cli;}//拨码开关void boman(){if(PORTA_PA0==1) {b_rkp[0]=table_rkp0[0];b_rkp[1]=table_rkp0[1];b_rkp[2]=table_rkp0[2];b_rkp[3]=table_rkp0[3];b_rkp[4]=table_rkp0[4];b_rkp[5]=table_rkp0[5];b_rkp[6]=table_rkp0[6];b_rkd[0]=table_rkd0[0];b_rkd[1]=table_rkd0[1];b_rkd[2]=table_rkd0[2];b_rkd[4]=table_rkd0[4]; b_rkd[5]=table_rkd0[5]; b_rkd[6]=table_rkd0[6];b_mkp[0]=table_mkp0[0]; b_mkp[1]=table_mkp0[1]; b_mkp[2]=table_mkp0[2]; b_mkp[3]=table_mkp0[3]; b_mkp[4]=table_mkp0[4]; b_mkp[5]=table_mkp0[5];b_mki[0]=table_mki0[0]; b_mki[1]=table_mki0[1]; b_mki[2]=table_mki0[2]; b_mki[3]=table_mki0[3]; b_mki[4]=table_mki0[4]; b_mki[5]=table_mki0[5];b_mkd[0]=table_mkd0[0]; b_mkd[1]=table_mkd0[1]; b_mkd[2]=table_mkd0[2]; b_mkd[3]=table_mkd0[3]; b_mkd[4]=table_mkd0[4]; b_mkd[5]=table_mkd0[5];s_table[0]=s_ideal0[0];s_table[1]=s_ideal0[1];s_table[2]=s_ideal0[2];s_table[3]=s_ideal0[3];s_table[4]=s_ideal0[4];s_table[5]=s_ideal0[5];}if(PORTA_PA1==1) {b_rkp[0]=table_rkp1[0]; b_rkp[1]=table_rkp1[1]; b_rkp[2]=table_rkp1[2]; b_rkp[3]=table_rkp1[3]; b_rkp[4]=table_rkp1[4]; b_rkp[5]=table_rkp1[5]; b_rkp[6]=table_rkp1[6];b_rkd[1]=table_rkd1[1]; b_rkd[2]=table_rkd1[2]; b_rkd[3]=table_rkd1[3]; b_rkd[4]=table_rkd1[4]; b_rkd[5]=table_rkd1[5]; b_rkd[6]=table_rkd1[6];b_mkp[0]=table_mkp1[0]; b_mkp[1]=table_mkp1[1]; b_mkp[2]=table_mkp1[2]; b_mkp[3]=table_mkp1[3]; b_mkp[4]=table_mkp1[4]; b_mkp[5]=table_mkp1[5];b_mki[0]=table_mki1[0]; b_mki[1]=table_mki1[1]; b_mki[2]=table_mki1[2]; b_mki[3]=table_mki1[3]; b_mki[4]=table_mki1[4]; b_mki[5]=table_mki1[5];b_mkd[0]=table_mkd1[0]; b_mkd[1]=table_mkd1[1]; b_mkd[2]=table_mkd1[2]; b_mkd[3]=table_mkd1[3]; b_mkd[4]=table_mkd1[4]; b_mkd[5]=table_mkd1[5];s_table[0]=s_ideal1[0];s_table[1]=s_ideal1[1];s_table[2]=s_ideal1[2];s_table[3]=s_ideal1[3];s_table[4]=s_ideal1[4];s_table[5]=s_ideal1[5];}if(PORTA_PA2==1) {b_rkp[0]=table_rkp2[0]; b_rkp[1]=table_rkp2[1]; b_rkp[2]=table_rkp2[2]; b_rkp[3]=table_rkp2[3]; b_rkp[4]=table_rkp2[4]; b_rkp[5]=table_rkp2[5]; b_rkp[6]=table_rkp2[6];b_rkd[0]=table_rkd2[0]; b_rkd[1]=table_rkd2[1]; b_rkd[2]=table_rkd2[2]; b_rkd[3]=table_rkd2[3]; b_rkd[4]=table_rkd2[4]; b_rkd[5]=table_rkd2[5]; b_rkd[6]=table_rkd2[6];b_mkp[0]=table_mkp2[0]; b_mkp[1]=table_mkp2[1]; b_mkp[2]=table_mkp2[2]; b_mkp[3]=table_mkp2[3]; b_mkp[4]=table_mkp2[4]; b_mkp[5]=table_mkp2[5];b_mki[0]=table_mki2[0]; b_mki[1]=table_mki2[1]; b_mki[2]=table_mki2[2]; b_mki[3]=table_mki2[3]; b_mki[4]=table_mki2[4]; b_mki[5]=table_mki2[5];b_mkd[0]=table_mkd2[0]; b_mkd[1]=table_mkd2[1]; b_mkd[2]=table_mkd2[2]; b_mkd[3]=table_mkd2[3]; b_mkd[4]=table_mkd2[4]; b_mkd[5]=table_mkd2[5];s_table[0]=s_ideal2[0];s_table[1]=s_ideal2[1];s_table[2]=s_ideal2[2];s_table[3]=s_ideal2[3];s_table[4]=s_ideal2[4];s_table[5]=s_ideal2[5];}if(PORTA_PA3==1) {b_rkp[0]=table_rkp3[0]; b_rkp[1]=table_rkp3[1]; b_rkp[2]=table_rkp3[2]; b_rkp[3]=table_rkp3[3];b_rkp[4]=table_rkp3[4];b_rkp[5]=table_rkp3[5];b_rkp[6]=table_rkp3[6];b_rkd[0]=table_rkd3[0];b_rkd[1]=table_rkd3[1];b_rkd[2]=table_rkd3[2];b_rkd[3]=table_rkd3[3];b_rkd[4]=table_rkd3[4];b_rkd[5]=table_rkd3[5];b_rkd[6]=table_rkd3[6];b_mkp[0]=table_mkp3[0];b_mkp[1]=table_mkp3[1];b_mkp[2]=table_mkp3[2];b_mkp[3]=table_mkp3[3];b_mkp[4]=table_mkp3[4];b_mkp[5]=table_mkp3[5];b_mki[0]=table_mki3[0];b_mki[1]=table_mki3[1];b_mki[2]=table_mki3[2];b_mki[3]=table_mki3[3];b_mki[4]=table_mki3[4];b_mki[5]=table_mki3[5];b_mkd[0]=table_mkd3[0];b_mkd[1]=table_mkd3[1];b_mkd[2]=table_mkd3[2];b_mkd[3]=table_mkd3[3];b_mkd[4]=table_mkd3[4];b_mkd[5]=table_mkd3[5];s_table[0]=s_ideal3[0];s_table[1]=s_ideal3[1];s_table[2]=s_ideal3[2];s_table[3]=s_ideal3[3];s_table[4]=s_ideal3[4];s_table[5]=s_ideal3[5];}}/**************************////////赛道特征识别///////****************************/void Roadjudge(void){if(Flag_Chute==0) //普通弯道情况0{ GeneralCtn=0;CurveCtn=0;if(CR>=-23&&CR<=40) //此时对应一个车轮的内侧压线@@@@@@@@@@@@@@@@@@@@@@@@@@@@{ChuteCtn++;W ANCtn=0;}if(CR<-23||CR>40) { // @@@@@@@@@@@@@@@@@@@@@@@@@@if(CR<-85||CR>90){ //对应车轮的外侧压线@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ChuteCtn=0;W ANCtn++;}else {ChuteCtn=0;WANCtn=0;}}if(ChuteCtn>10000) // 300{Flag_Chute=1;}if(W ANCtn<-10000){Flag_Chute=2;}}if(Flag_Chute==1) //长直道情况 1{ChuteCtn=0;GeneralCtn=0;W ANCtn=0;if(CR>40)CurveCtn++; // 60 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@if(CR<-23)CurveCtn--; // -60 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@if(CurveCtn>1||CurveCtn<-1){if(Flag_gaosu==1) //高速时转入大弯道情况{Flag_Chute=2;}if(Flag_gaosu==0)Flag_Chute=0; //低速时转入普通弯道情况}}if(Flag_Chute==2) //大弯道情况 2{ChuteCtn=0;CurveCtn=0;W ANCtn=0; // @@@@@@@@@@@@@@@@@@@@@@@if(CR>-23&&CR<35)GeneralCtn++;else GeneralCtn=0;if(GeneralCtn>1300)Flag_Chute=0;//if(GeneralCtn>130)Flag_Ct=1;//else Flag_Ct=0;//if(k_abs(Turn_C-Turn<54)// {// Flag_Zhj=1;// }// else// {// Flag_Zhj=0;// }// if(Flag_Pwm==1&&Flag_Ct==1)Flag_Chute=1;}}/******************************\\\\\\\\\\\\\\\\\\\\//舵机控制\\\\\\\\\\\\\\\\\*********************************/void rudder_ctrl(void){if(Flag_Chute==0) //普通道{Flag_Pwm=0;if(CR<40&&CR>-23){rkp=b_rkp[0];rkd=b_rkd[0];}else{rkp=b_rkp[6];rkd=b_rkp[6];}}else if(Flag_Chute==1) //长直道{Flag_Pwm=1;if(Flag_gaosu==0) //disu{rkp=b_rkp[1]; //5rkd=b_rkd[1];}else //gaosu{rkp=b_rkp[2]; //4rkd=b_rkd[2];}}else if(Flag_Chute==2) //大弯道{if(Flag_Pwm==0) //普通道到大弯道{rkp=b_rkp[3];rkd=b_rkd[3];}else if(Flag_Pwm==1) //直道到大弯道{rkp=b_rkp[4];rkd=b_rkd[4];}else{rkp=b_rkp[5];rkd=b_rkd[5];}}f=3800+rkp*CR+rkd*(CR-2*preCR+ppreCR); //舵机的PID算式ppreCR=preCR;//计算之后向前推进赋值为下次计算做准备preCR=CR;}/***********************************\\\\\\\\\\\\电机控制\\\\\\\\\\\\\\\\\\************************************/void motor_ctrl1(void){if(Flag_Chute==0) //普通道{Flag_Pwm=0;mkp=b_mkp[0];mki=b_mki[0];mkd=b_mkd[0];ideal_speed=s_table[0];}else if(Flag_Chute==1) //长直道{Flag_Pwm=1;// Flag_PIDRev=0;mkp=b_mkp[1];mki=b_mki[1];mkd=b_mkd[1];ideal_speed=s_table[1];}else if(Flag_Chute==2) //大弯道{if(Flag_Pwm==0) //普通道进大弯道{mkp=b_mkp[2];mki=b_mki[2];mkd=b_mkd[2];ideal_speed=s_table[2];}else if(Flag_Pwm==1) //直道进大弯道{mkp=b_mkp[3];mki=b_mki[3];mkd=b_mkd[3];ideal_speed=s_table[3];}else{mkp=b_mkp[4];mki=b_mki[4];mkd=b_mkd[4];ideal_speed=s_table[4];}Flag_Pwm=2;}}//电机控制void motor_ctrl2(void){int error,m_perror,m_ierror,m_derror;int pre_error=0;int ppre_error=0;error=ideal_speed-Pulse_count;m_perror = error - pre_error;m_ierror=error;m_derror=error-2*pre_error+ppre_error;ppre_error=pre_error;pre_error=error;speed+=mkp*m_perror + mki*m_ierror + mkd*m_derror; //速度PID控制算式if(speed>=9000) speed=9000;if(speed<=-4000) speed=-4000;if(speed>=0){PWMDTY45=0;PWMDTY01=(int)speed/10;}else{PWMDTY45=(int)(-speed)/10;PWMDTY01=0;}}//主函数//void main(void) {DisableInterrupts;PWMDTY23=3800;PLL_Init();DDRA=0X00;//输入boman();PACBInit();RTI_init();PWM_rudder_init();PWM_init_motor();AD_Init();DDRB=0XFF;//输出PORTB=0X03;//1号与2号灯亮delay(5000); //4000 3s左右PORTB=0xFC;//3号与4号灯亮Checkstart();EnableInterrupts;/* put your own code here */for(;;) {while(!ATD0STA T2_CCF0); // 等待转换结束while(ATDOSTA T2_CCF0==1)left1=ATD0DR0;//读取结果寄存器left1的值while(!ATD0STAT2_CCF2); // 等待转换结束while(ATDOSTAT2_CCF1==1) left2=ATD0DR2;//读取结果寄存器的值while(!ATD0STAT2_CCF1); // 等待转换结束while(ATDOSTAT2_CCF2==1) right1=ATD0DR1;//读取结果寄存器的值while(!ATD0STAT2_CCF3); // 等待转换结束while(ATDOSTAT2_CCF3==1)right2=ATD0DR3;//读取结果寄存器的值AR_LEFT=left1+left2;AR_RIGHT=right1+right2;CR=(AR_RIGHT-AR_LEFT)/10;if(Pulse_count>65)Flag_gaosu=1;else Flag_gaosu=0;if(AR_RIGHT<110||AR_LEFT<95)//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ left93 {if(pref>3800) //if(AR_RIGHT<110)f=4500; //f=3100;if(pref<3800) //if(AR_LEFT<95)f=3100; //f=4500;mkp=b_mkp[5];mki=b_mki[5];mkd=b_mkd[5];ideal_speed=s_table[5];}else{Roadjudge(); //先对道路进行判断rudder_ctrl(); //调整舵机motor_ctrl1(); //调整电机的pid参数}if(f>4500)f=4500;if(f<3100)f=3100;PWMDTY23=f;pref=PWMDTY23;motor_ctrl2();}} /* loop forever */#pragma CODE_SEG __NEAR_SEG NON_BANKEDinterrupt 7 void Int_TimerOverFlow(void){Pulse_count= PACNT; //脉冲计数赋值PACNT = 0X0000;CRGFLG_RTIF=1;if(ting<1100)ting++;else ting=1100;}interrupt VectorNumber_Vtimch0 void stop(void){DisableInterrupts;TFLG1_C0F=1; //清除中断标志位//PORTB=0X03;//1号与2号灯亮// delay(20);// PORTB=0xFC;//3号与4号灯亮// ganhuang++;//if(ganhuang%4==0){// ganhuang=0;//PORTB=0xFC;//3号与4号灯亮//ganhuang=0;//TIE=TIE&0X0FE;flag=1;if(ting==1100){flag=2;PORTB=0xF6;for(i=0;i<3000;i++){while(!ATD0STA T2_CCF0); // 等待转换结束while(ATDOSTA T2_CCF0==1)left1=ATD0DR0;//读取结果寄存器left1的值while(!ATD0STAT2_CCF2); // 等待转换结束while(ATDOSTAT2_CCF1==1) left2=ATD0DR2;//读取结果寄存器的值while(!ATD0STAT2_CCF1); // 等待转换结束while(ATDOSTAT2_CCF2==1) right1=ATD0DR1;//读取结果寄存器的值while(!ATD0STAT2_CCF3); // 等待转换结束while(ATDOSTAT2_CCF3==1) right2=ATD0DR3;//读取结果寄存器的值AR_LEFT=left1+left2;AR_RIGHT=right1+right2;CR=(AR_RIGHT-AR_LEFT)/10;rkp=9;rkd=0;f=3800+rkp*CR+rkd*(CR-preCR);preCR=CR;if(f>4500)f=4500;if(f<3100)f=3100;PWMDTY23=f;pref=PWMDTY23;//mkp=20;//mki=0;//mkd=0;//ideal_speed=0;//motor_ctrl2();PWMDTY01=0;PWMDTY45=0;delay(2);}}EnableInterrupts;}// asm cli;#pragma CODE_SEG DEFAULT//结论3800中间;3100(-700)左打死,4500(700)右打死//7.11当右边两个相加小于40时往左打死,此时左车轮大概偏黑线2cm,当左边两个相加小于100时右打死//此时右轮偏2cm。