智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 2515|回复: 4
打印 上一主题 下一主题

光电基础代码

[复制链接]

1

主题

8

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
246
威望
224
贡献
20
兑换币
0
注册时间
2010-3-4
在线时间
1 小时
跳转到指定楼层
1#
发表于 2010-3-12 10:34:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <hidef.h>      /* common defines and macros */
#include <MC9S12XS128.h>     /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12xs128"


#define ATD_SEQURE 8                  //定义转换序列长度
#define Steer_Center 1500            //设定舵机中间值
#define Speed_Wanted  10             //目标速度
#define Speed_K       100             //速度Kp
#define Steer_K       40              //舵机Kp
#define Steer_left    1250            //舵机左侧限幅
#define Steer_right   1750            //舵机右侧限幅

unsigned char LedCode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char LedData[]={0,0,0,0};
unsigned char LedNum = 0;

uchar ad_data[ATD_SEQURE];                       //存放AD转换结果
int  speed;                                    //存放脉冲累加结果
int  LED_offset;                                //光电管偏移量
uchar Black_num;                                 //检测到的黑线的数目
int  Line_center;                               //中心线位置
uchar Get_Line;                                  //指示此次有无检测到黑线
int  Pre_Control_Speed=0;
int  Control_Speed;
int  Control_Steer;
int  Pre_offset=0;
int  This_offset=0;
uchar b;   


#pragma CODE_SEG DEFAULT

void ATD_init(void){                   //ATD初始化
    ATD0CTL0 = 0x07;                  //多路转换时转换8路
    ATD0CTL1_SRES = 0;           //转换精度为8位
    ATD0CTL2_AFFC = 1;                //中断标志位自动清零
    ATD0CTL2_ASCIE = 1;               //一个序列传唤结束触发中断
    ATD0CTL3 = 0xC0;                  //结果寄存器对齐方式右对齐,转换序列长度为8,循环转换,freeze模式下继续转换
    ATD0CTL4 = 0x00;                  //采样周期为4个周期,atdclk=busclk/2*(0+1),无锁相环总线时钟为8M,故
                                     //ATDclk=4M
    ATD0CTL5_SCAN = 1;                //连续转换模式
    ATD0CTL5_MULT = 1;                //多通道采样
   
   
}   
void initGPIO(void){         //通用IO口初始化
    DDRA = 0x00;             //A口输入
    DDRB = 0xFF;             //B口输出
    DDRK = 0xFF;             //K口输出
}

void initPWM(void){                      //PWM初始化
     PWME=0x00;                          //关闭所有PWM通道
     PWMPOL = 0xFF;                      //PWM极性选择,选择一个周期开始时为高电平
     PWMPRCLK = 0x33;                    //CLOCK A,B时钟分频,均选择从总线四分频 1M
     //PWMSCLA  = 5;                       //CLOCK SA从CLOCK A十分频,1M
     //PWMSCLB  = 5;                       //CLOCK SB从CLOCK B十分频,1M
     PWMCTL = 0xF0;                      //01级联,23级联,45级联,67级联
     PWMCLK = 0x00;                      //PWM始终选择,选择CLOCK A B为PWM时钟
     
     PWMPER01=200;                       //电机PWM正转频率5k
     PWMDTY01=0;
     
     PWMPER23=200;
     PWMDTY23=0;                           //电机反转频率为1k
     
     PWMPER45=20000;                        //舵机PWM频率为50Hz  
     PWMDTY45=Steer_Center;                 //舵机占空比
     
     PWME_PWME3=1;   
     PWME_PWME1=1;                          //电机PWM波开始输出
     PWME_PWME5=1;                           //舵机PWM波开始输出
}

void InitRTI(void) {                      // 实时中断初始化                     
    RTICTL = 0x8F;                            //20ms中断一次
    CRGINT = 0x80;                            // 开实时中断
}

void InitPACNT(void){
    PACTL = 0x40;                        //脉冲累加功能,下降沿计数
    PACNT = 0;      
}

void main(void) {
  /* put your own code here */
  DisableInterrupts;
  ATD_init();
  InitRTI();
  initGPIO();
  initPWM();
  InitPACNT();
  EnableInterrupts;

  for(;;) {} /* wait forever */
  /* please make sure that you never leave this function */
}


#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 7 RTI_INT(void) {
   
    int j;
    uchar a;
    uchar i;
    DisableInterrupts; //关中断
    speed = PACNT;                          //读脉冲累加寄存器                       
    PACNT = 0;                              //脉冲累加器置0
    Pre_offset = This_offset;                //偏差信号赋值
    This_offset = (int)(Speed_Wanted)-speed;
   
    LED_offset = 0;
    Black_num = 0;                        
    /*for(i=0;i<ATD_SEQURE;i++){
        if(ad_data[i]<Threshold||ad_data[i]==Threshold){            
             Threshold = ad_data[i];    a=i;        
            Black_num++;              
        }
     } */
     if(ad_data[0]<10){  Black_num++;   a=0;              //第0个传感器阈值
     }                                                                     
     if(ad_data[1]< 60){   Black_num++;   a=1;             // 第1个传感器阈值
     }
     if(ad_data[2]<10){  Black_num++;      a=2;           // 第2个传感器阈值
     }
     if(ad_data[3]< 20){  Black_num++;     a=3;             // 第3个传感器阈值
     }
     if(ad_data[4]<80){   Black_num++;     a=4;            // 第4个传感器阈值
     }
     if(ad_data[5]< 20){   Black_num++;      a=5;            // 第5个传感器阈值
     }
     if(ad_data[6]< 10){   Black_num++;      a=6;            // 第6个传感器阈值
     }
     if(ad_data[7]< 20){    Black_num++;     a=7;            // 第7个传感器阈值
     }
     
    if(Black_num!=0){
    if(Black_num==1)   {
      
       //Line_center = LED_offset/(uint)(Black_num);
        Line_center = (uint)(a*2-7);
        Get_Line = 1;
      
    }  
        else   EnableInterrupts;
    }
    else{
        Get_Line = 0;   
    }
   
   
    Pre_Control_Speed = Control_Speed;
    Control_Speed = Pre_Control_Speed + (int)(Speed_K)*(This_offset-Pre_offset);         //P控制式,增量式
    if(Control_Speed>200){                                                             //限幅控制
       Control_Speed=200;
    }
    else if(Control_Speed<0){
       Control_Speed=0;
    }
   
    Control_Steer=(int)(Steer_Center) - (int)(Steer_K)*Line_center;                     //舵机P控制式,位置式
    if(Control_Steer<Steer_left){                                                  //舵机输出值限幅
        Control_Steer = Steer_left;
    }
    else if(Control_Steer>Steer_right){
        Control_Steer = Steer_right;
    }
   
   
    if(Control_Steer>1540||Control_Steer<1460)   {                  //如有拐弯,减速,转向
     PWMDTY01 = 0;  PWMDTY45 = Control_Steer;
   
     for(i=0;i<100;i++) {                                           //延时一段时间,减速
     for(j=0;j<3;j++){
     }                                                            
     }
     
      PWMDTY01 = 100;
   
    }
     else  {
      PWMDTY45 = Control_Steer;
      PWMDTY01 = Control_Speed;
    }
                 
   // PWMDTY01 = Control_Speed;          //舵机控制                  
                                             
              
            
      
   
    LedData[0] = 0;
    LedData[1] = Control_Speed/100%10;
    LedData[2] = Control_Speed/10%10;
    LedData[3] = Control_Speed%10;
    PORTK = 0x01 << LedNum;
    PORTB = LedCode[LedData[LedNum]];
    LedNum++;
    if(LedNum >= 4)
        LedNum = 0;
    CRGFLG = 0x80;
    EnableInterrupts;                            //开中断
}



interrupt 22 void ATD_Process(void){                //AD转换中断服务程序
      DisableInterrupts;                            //关中断
      ad_data[0] = ATD0DR0L;
      ad_data[1] = ATD0DR1L;
      ad_data[2] = ATD0DR2L;
      ad_data[3] = ATD0DR3L;
      ad_data[4] = ATD0DR4L;
      ad_data[5] = ATD0DR5L;
      ad_data[6] = ATD0DR6L;
      ad_data[7] = ATD0DR7L;
      EnableInterrupts;                            //开中断

}
#pragma CODE_SEG DEFAULT

0

主题

1

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
226
威望
189
贡献
33
兑换币
12
注册时间
2010-3-12
在线时间
2 小时
2#
发表于 2010-3-12 19:38:23 | 只看该作者
南京的
回复 支持 反对

使用道具 举报

0

主题

27

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
243
威望
198
贡献
41
兑换币
0
注册时间
2010-3-6
在线时间
2 小时
3#
发表于 2010-3-19 00:48:31 | 只看该作者
好资源  谢谢
回复 支持 反对

使用道具 举报

2

主题

67

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
473
威望
351
贡献
70
兑换币
28
注册时间
2010-1-9
在线时间
26 小时
4#
发表于 2010-3-19 09:40:21 | 只看该作者
谢谢
回复 支持 反对

使用道具 举报

0

主题

38

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
234
威望
209
贡献
19
兑换币
0
注册时间
2010-4-2
在线时间
3 小时
5#
发表于 2010-4-4 15:54:37 | 只看该作者
xiexie a
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2025-1-11 04:20 , Processed in 0.043264 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表