完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
以下是飞思卡尔智能车dg128单片机控制程序代码介绍:
#include #include #pragma LINK_INFO DERIVATIVE "mc9s12dg128b" #pragma CODE_SEG __NEAR_SEG NON_BANKED //定义全局变量 int blackline=500; unsigned int Get_pulse; int qian[11]; //AD转换结果 int hou[3]; int dw_result[4]; //档位信号 int dangwei; int pianxin_a[11]={115,85,62,41,20,0,-20,-41,-62,-85,-115}; //两排灯距离中线的偏移量 int go=0; int qidian,once; int speed; //要求速度 int counter_a,counter_1,counter_2,counter_3,counter_b; //前后两排在黑线阀值上的灯数 int one,two,three; int x; //前后排灯在黑线上的灯编号 int biga,bigb,bigc; int bigd; //前排最大的三个电压值he后排的最大值 int tan_o,tan_n1,tan_n2,tan_n3,tan_n4,tan_n5,tan_n6; int tan_n; //前,后次偏角正弦 int away_o,away_n; //前后次车身中线偏移量 int kj;int kp;int zhuan,o; //控制舵机的参数 int jia_1,jia_2,jia_3; //速度参数 int sudu; //真实速度 //函数声明 void system_init(void); //模块初始化函数 void clock_init(void); void PWM_init(void); void AD_Init(void); void set_parameter(void); //键盘输入参数显示 void Infrared_detect(void); //红外检测速 void data_handle(void); void direct_ctl(void); //方向控制 void steer_ctl(void); //舵机控制 void slow1(void); void slow2(void); void slow3(void); void slow4(void); void slow5(void); void slow6(void); //刹车程序 void speed_ctl(void); //速度控制 void motor_ctl(void); //电机控制 void PACBInit(void); void MDCInit(void); //++++++++++++++++++++++++++++++++++++++++++++ //主函数开始 void main(void) { DisableInterrupts; system_init(); //系统初始化 set_parameter(); PACBInit(); MDCInit(); EnableInterrupts; for(;;) { Infrared_detect(); data_handle(); motor_ctl(); steer_ctl(); } } void interrupt 26 MDC_ISR(void) { static unsigned int number_count=0; static unsigned int start=0; static unsigned int begin=0; MCFLG = 0x80; { number_count ++; if( number_count==125) //0.125秒取一次 { number_count=0; Get_pulse = PACN10; //get pluse 脉冲数 PACN10 = 0X0000; } } { start++; if(start>100) //3sec {begin++; start=0; if(begin>22) go=1; if(begin<150&&begin>22) go=2; if(begin>=150) go=3; } } } //-----系统初始化----------------------- void system_init(void) //system initiat {DDRB=0xff; clock_init(); //clock initiat PWM_init(); //pwm initiat AD_Init(); //ATD initiat } void clock_init(void) //时钟初始化 { CLKSEL=0X00; //disengage PLL to system PLLCTL_PLLON=1; //turn on PLL SYNR=2; REFDV=1; //pllclock=2*osc*(1+SYNR)/(1+REFDV)=24MHz; _asm(nop); //BUS CLOCK=16M _asm(nop); while(!(CRGFLG_LOCK==1)); //when pll is steady ,then use it; CLKSEL_PLLSEL =1; //engage PLL to system; } void AD_Init(void) { ATD0CTL2=0xC0; //AD模块上电, 快速清零, 无等待模式, 禁止外部触发, 中断禁止 ATD0CTL3=0x44; //每次转换8个序列, FIFO, Freeze模式下继续转 ATD0CTL4=0x02; //10位精度, 采样时间为2个AD时钟周期,ATDClock=4MHz ATD0CTL5=0xB0; //右对齐无符号,,连续转换 ,8轮流通道采样 ATD0DIEN=0x00; //禁止数字输入 ATD1CTL2=0xC0; //AD模块上电, 快速清零, 无等待模式, 禁止外部触发, 中断禁止 ATD1CTL3=0x44; //每次转换8个序列, FIFO, Freeze模式下继续转 ATD1CTL4=0x02; //10位精度, 采样时间为2个AD时钟周期,ATDClock=4MHz ATD1CTL5=0xB0; //右对齐无符号,,连续转换 ,8轮流通道采样 ATD1DIEN=0x00; //禁止数字输入 } void PWM_init(void) { PWME =0x00; //关闭 PWMPOL=0xff; //先高电平 PWMCAE=0x00; //左对齐 PWMCLK=0x0c; //选择0,1,4,5通道时钟源头A 2,3通道时钟源头SB,6,7为时钟B PWMPRCLK=0x33; //时钟预分频0通道为8 //设置舵机 PWMCTL_CON01=1; //使得通道0,1成为16位pwm PWMPER0 =0x75; PWMPER1 =0x30; //舵机的频率是: 24M/8/30000=100Hz,T=10ms PWMDTY01=4500; // 对应为4500/30000的占空比,待调整 //设置电机 PWMSCLB =50; // 24MHZ/8/2/50=300K PWMPER2 =100; //电机的频率是: 24M/8/2/50/500=300Hz,T=5ms PWMDTY2 =0; //用于测试电机 PWMPER3 =100; //电机的频率是: 24M/8/2/50/500=300Hz,T=5ms PWMDTY3 =0; //用于测试电机 //小灯输出 PWMPER4 =79; //小灯的频率是: 24M/8/79=38kHz PWMDTY4 =30; PWMPER7 =79; //小灯的频率是: 24M/8/79=38kHz PWMDTY7 =30; DDRP =0xff; //控制输出 PWME =0x9f; //开放通道0,1 ,3,4,5,6,7 } void PACBInit() { TCTL4 = 0X02; //下降沿捕捉脉冲 PBCTL = 0x40; //级联两个8位累加器(PAC0和PAC1) ICPAR = 0X03; //使能累加器 PACN10 = 0X0000; } void MDCInit(void) { MCCTL = MCCTL&0Xfb; //模数计数器禁止运行 MCCTL = 0Xe3; //允许中断,模数计数方式 //返回时重新加载所用的常数,分频常数为16 MCCTL = MCCTL|0X04; //模数计数器使能 MCCNT = 1500; //(1/24M)*16*1500= 1ms MCCTL = MCCTL|0X08 ; //把模数常数寄存器的值加载到模数计数器FLMC; } void set_parameter(void)//----------参数设置---------- { blackline=500; tan_n=0; qidian=0,once=0; speed=0; counter_a=0,counter_b=0; //前后两排在黑线阀值上的灯数 one=5;two=4;three=6;x=1; //前后排灯在黑线上的灯编号 biga=0;bigb=0;bigc=0; bigd=0; //前排最大的三个电压值he后排的最大值 tan_o=0,tan_n=0; //前,后次偏角正弦 tan_n1=0;tan_n2=0;tan_n3=0;tan_n4=0;tan_n5=0; away_o=0,away_n=0; //前后次车身中线偏移量 kj=0;kp=0; zhuan=0; } //----------红外检测--------- void Infrared_detect(void) { while(!ATD0STAT1_CCF0); qian[0] = ATD0DR0; while(!ATD0STAT1_CCF1); qian[1] = ATD0DR1; while(!ATD0STAT1_CCF2); qian[2] = ATD0DR2; while(!ATD1STAT1_CCF4); qian[3] = ATD1DR4; while(!ATD0STAT1_CCF3); qian[4] = ATD0DR3; while(!ATD0STAT1_CCF4); qian[5] = ATD0DR4; while(!ATD0STAT1_CCF5); qian[6] = ATD0DR5; while(!ATD1STAT1_CCF5); qian[7] = ATD1DR5; while(!ATD0STAT1_CCF6); qian[8] = ATD0DR6; while(!ATD0STAT1_CCF7); qian[9] = ATD0DR7; while(!ATD1STAT1_CCF0); qian[10] = ATD1DR0; while(!ATD1STAT1_CCF1); hou[0] = ATD1DR1; while(!ATD1STAT1_CCF2); hou[1] = ATD1DR2; while(!ATD1STAT1_CCF3); //AD0所有和AD1前4个用作探测信号接受 hou[2] = ATD1DR3; while(!ATD1STAT1_CCF6); //档位通道开始 dw_result[0] = ATD1DR6; while(!ATD1STAT1_CCF7); dw_result[1] = ATD1DR7; //档位通道结束 } void data_handle(void) //数据处理 { int n; counter_a=0,counter_b=0; for(n=0;n<=10;n++) { if(qian[n]>blackline) counter_a++; } for(n=0;n<=2;n++) { if(hou[n]>blackline) counter_b++; } dangwei=0; for(n=0;n<3;n++) { if(dw_result[n]>600) dangwei++; // 统计档位数目 } switch( one ) //for testing { case 10: PORTB=0xf0;break; case 9: PORTB=0xfe;break; case 8: PORTB=0xfd;break; case 7: PORTB=0xfb;break; case 6: PORTB=0xf7;break; case 5: PORTB=0xaa;break; case 4: PORTB=0xef;break; case 3: PORTB=0xdf;break; case 2: PORTB=0xbf;break; case 1: PORTB=0x7f;break; case 0: PORTB=0x0f;break; default:break; } {//判断起始点,参数待调整 if(((qian[1]>blackline&&qian[9]>blackline&&qian[2]>blackline &&qian[10]>blackline)||(qian[1]>blackline&&qian[9]>blackline &&qian[0]>blackline&&qian[8]>blackline))&&(qian[3] ||qian[4] &&(counter_a>4&&counter_a<8)) { once++;tan_n=tan_o;away_n=away_o; } if(once>1&&counter_a<4) { if(go==2){qidian=1;once=0;} if(go==3){qidian++;once=0;} } } if(counter_a>5&&qian[4]>blackline&&qian[5]>blackline&&qian[6]>blackline&& (qian[3]>blackline||qian[7]>blackline)) //过十字交叉线时或过起始线 {tan_n=tan_o; away_n=away_o;} biga=0; for(n=0;n<=10;n++) //寻找最大值 {if(biga for(n=0;n<=10;n++) //寻找第二大值 {if((bigb for(n=0;n<=10;n++) //寻找第三大值 {if((bigc bigd=0; for(n=0;n<=2;n++) {if(bigd one=5; if((one-two)==1||(two-one)==1) { if(counter_a>0&&counter_a<3) { if( (biga-bigb)<=(bigb-bigc) ) tan_n=(pianxin_a[one]+pianxin_a[two])/2; else tan_n=pianxin_a[one]; if(counter_b>0) { switch(x) {case 1: { away_n=0; break; } case 0: { away_n=34; break; } case 2: { away_n=-34; break; } } } if(counter_b==0) { if(tan_n<=20&&tan_n>=-20)away_n=0; if(tan_n>20)away_n=17; if(tan_n<-20)away_n=-17; } } if(counter_a==0) { if(tan_o<-100) tan_n=-120; if(tan_o>100) tan_n=120; if(tan_o<100&&tan_o>-100) tan_n=tan_o; away_n=away_o; } } tan_n1=tan_n2;tan_n2=tan_n3;tan_n3=tan_n4;tan_n4=tan_n5;tan_n5=tan_n6;tan_n6=tan_n; tan_n=(tan_n4+tan_n5+tan_n6+tan_n3+tan_n2+tan_n1)/6; if(tan_o<50&&tan_n>-50){ if(tan_n-tan_o<-10||tan_n-tan_o>10) { tan_n=tan_o; if((tan_n5-tan_n4>5&&tan_n4-tan_n3>4&&tan_n3-tan_n2>3)||(tan_n5-tan_n4<-5&&tan_n4- tan_n3<-4&&tan_n3-tan_n2<-3) ||(tan_n5-tan_n4>0&&tan_n4-tan_n3>0&&tan_n3-tan_n2>0&&tan_n2-tan_n1>0) ||(tan_n5-tan_n4<0&&tan_n4-tan_n3<0&&tan_n3-tan_n2<0&&tan_n2-tan_n1<0)) tan_n=tan_n6; } } if(tan_o>50||tan_n<-50){ if(tan_n-tan_o<-15||tan_n-tan_o>15) { tan_n=tan_o; if((tan_n5-tan_n4>5&&tan_n4-tan_n3>4&&tan_n3-tan_n2>3)||(tan_n5-tan_n4<-5&&tan_n4- tan_n3<-4&&tan_n3-tan_n2<-3) ||(tan_n5-tan_n4>0&&tan_n4-tan_n3>0&&tan_n3-tan_n2>0&&tan_n2-tan_n1>0) ||(tan_n5-tan_n4<0&&tan_n4-tan_n3<0&&tan_n3-tan_n2<0&&tan_n2-tan_n1<0)) tan_n=tan_n6; } } tan_o=tan_n;away_o=away_n; } void direct_ctl(void) { if(tan_n>=-120&&tan_n<-90){kj=46;kp=12;} if(tan_n>=-90&&tan_n<-60) {kj=47;kp=13;} if(tan_n>=-60&&tan_n<-20) {kj=48;kp=14;} if(tan_n>=-20&&tan_n<-8) {kj=46;kp=15;} if(tan_n>=-8&&tan_n<0) {kj=45;kp=14;} if(tan_n>=0&&tan_n<8) {kj=45;kp=14;} if(tan_n>=8&&tan_n<20) {kj=46;kp=15;} if(tan_n>=20&&tan_n<60) {kj=48;kp=14;} if(tan_n>=60&&tan_n<90) {kj=47;kp=13;} if(tan_n>=90&&tan_n<=120) {kj=47;kp=12;} zhuan=(tan_n*kj+away_n*kp)/10; } void steer_ctl(void) //舵机控制 { direct_ctl(); PWMDTY01=4620+zhuan; } //刹车函数参数待调整 j void slow1(void) { int i;int j; for(i=1;i<6;i++) for(j=1;j<6;j++) { PWMDTY2=0; PWMDTY3=10;} PWMDTY3=0; } void slow2(void) { int i;int j; for(i=1;i<8;i++) for(j=1;j<7;j++) { PWMDTY2=0; PWMDTY3=12;} PWMDTY3=0; } void slow3(void) { int i;int j; for(i=1;i<8;i++) for(j=1;j<8;j++) { PWMDTY2=0; PWMDTY3=14;} PWMDTY3=0; } void slow4(void) { int i;int j; for(i=1;i<10;i++) for(j=1;j<15;j++) { PWMDTY2=0; PWMDTY3=16;} PWMDTY3=0; jia_1++;} void slow5(void) { int i;int j; for(i=1;i<12;i++) for(j=1;j<15;j++) { PWMDTY2=0; PWMDTY3=18;} PWMDTY3=0; jia_2++;} void slow6(void) { int i;int j; for(i=1;i<15;i++) for(j=1;j<13;j++) { PWMDTY2=0; PWMDTY3=20;} PWMDTY3=0; jia_3++;} void speed_ctl(void) { sudu=167*Get_pulse/10; //单位cm/s if(zhuan<50&&zhuan>-50)speed=42; if((zhuan<80&&zhuan>=50)||(zhuan<=-50&&zhuan>-80))speed=41; if((zhuan<110&&zhuan>=80)||(zhuan<=-80&&zhuan>-110))speed=40; if((zhuan<140&&zhuan>=110)||(zhuan<=-110&&zhuan>-140))speed=39; if((zhuan<170&&zhuan>=140)||(zhuan<=-140&&zhuan>-170))speed=38; if((zhuan<200&&zhuan>=170)||(zhuan<=-170&&zhuan>-200))speed=37; if((zhuan<230&&zhuan>=200)||(zhuan<=-200&&zhuan>-230))speed=38; if((zhuan<270&&zhuan>=230)||(zhuan<=-230&&zhuan>-270))speed=39; if((zhuan<310&&zhuan>=270)||(zhuan<=-270&&zhuan>-310))speed=40; if((zhuan<350&&zhuan>=310)||(zhuan<=-310&&zhuan>-350))speed=40; if((zhuan<380&&zhuan>=350)||(zhuan<=-350&&zhuan>-380))speed=40; if((zhuan<400&&zhuan>=380)||(zhuan<=-380&&zhuan>-400))speed=40; if((zhuan<440&&zhuan>=400)||(zhuan<=-400&&zhuan>-440))speed=39; if((zhuan<490&&zhuan>=440)||(zhuan<=-440&&zhuan>-490))speed=38; if((zhuan<550&&zhuan>=490)||(zhuan<=-490&&zhuan>-550))speed=37; if((zhuan<600&&zhuan>=550)||(zhuan<=-550&&zhuan>-600))speed=36; if(zhuan>600||zhuan<-600)speed=35; } void motor_ctl(void) { int i; int t; speed_ctl(); if(go>0) { if(qidian<2){ switch(dangwei){ case 0: { if(zhuan>530||zhuan<-530) { if(sudu>230)slow3(); } t=speed+25-sudu/10; if(t>30&&t<70) PWMDTY2=speed+25-sudu/10;break; } case 1: { if(zhuan>300||zhuan<-300) { if(sudu>300)slow2(); if(sudu>330)slow3(); } if((zhuan<=500&&zhuan>300)||(zhuan<-300&&zhuan>=-500)) { if(sudu>280)slow4(); } if(zhuan>500||zhuan<-500) { if(sudu>220)slow5(); } if(jia_1+jia_2+jia_3>1) { for(i=0;i<500;i++) { PWMDTY2= 75; } jia_1=0;jia_2=0;jia_3=0; } t=speed+35-sudu/10; if(t>20&&t<70) PWMDTY2=speed+38-sudu/12;break; } case 2: { if(zhuan>280||zhuan<-280) { if(sudu>250)slow2(); if(sudu>290)slow3(); } if((zhuan<=360&&zhuan>200)||(zhuan<-200&&zhuan>=-360)) { if(sudu>240)slow4(); } if((zhuan<=530&&zhuan>360)||(zhuan<-360&&zhuan>=-530)) { if(sudu>220)slow5(); } if(zhuan>520||zhuan<-520) { if(sudu>220)slow6(); } if(jia_1+jia_2+jia_3>2) { for(i=0;i<600;i++) { PWMDTY2= 80; } jia_1=0;jia_2=0;jia_3=0; } t=speed+70-sudu/9; if(t>20&&t<90) PWMDTY2=speed+70-sudu/9;break; } default: PWMDTY2=50;break; } } else { PWMDTY2=0; } } |
|
相关推荐
2 个讨论
|
|
这个是干什么的?
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
1925个成员聚集在这个小组
加入小组我的项目我做主,使用GN+Ninja来完成构建系统(VSCode开发RT106X)
36400 浏览 0 评论
NXP IMX8应用处理器快速入门必备:技巧、使用、设计指南
4640 浏览 1 评论
6090 浏览 1 评论
6798 浏览 0 评论
NXP i.MX6UL开发板(linux系统烧录+规格+硬件+模块移植)使用手册
4236 浏览 0 评论
634浏览 2评论
求助,S32G上Core M启动后如何让Core A在Flash指定位置加载uboot?
631浏览 2评论
ESP32-WROVER-IE + LAN8720以太网,GPIO0电压只有1.6v,无法正常进入spi flash boot模式如何解决?
633浏览 2评论
求分享适用于PN7160 Android的NFC工厂测试应用程序
716浏览 2评论
819浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-12 12:46 , Processed in 1.352040 second(s), Total 48, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号