⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 +Ҥ

📁 飞思卡尔摄像头组
💻
字号:
                      #include <hidef.h>      
#include <MC9S12XS128.h>
#include "UART.h"
#pragma LINK_INFO DERIVATIVE "mc9s12xs128"

unsigned  short int    chesudu;
   
#define turn_max  450    //最大转角对应的PWM值,最大的转角
 
 #define straight 3300 //直走的SteerPWM 也即是 1.5ms 宽度   调整机械,使机械居中    3999  
 int pos_;
//采集到的数据在二维数组ta[lie][hang_end]里;


//接口定义: 行同步接PT2  场同步接PT1 信号线是接A0                                                                          
 //串口波特率为57600    USB转TTL串口的RX接单片机的S1    观察数据
//------------------------------------------------
  
  #define lie_end  260
  #define hang_end  90   //这里只每行采多少个点  根据像素来 最右边采到0表示采多了减少该值。
  #define lie  32//51      

  #define delay(num)   \
  { \
     unsigned int i,j; \
    for(i=0;i<num;i++) \
       for(j=0;j<58;j++); \
  } 
  //延时去消隐信号。 最左边有0表示采到消隐了增加J
  unsigned char c_lie=0,g_lie=0;
  unsigned int lie_count=0,hang_count=0;
    unsigned int lie_uart=0,hang_uart=0; 
  unsigned char ta[lie][hang_end];
  unsigned int get_n[]={  29,41,52,62,71,79,86,92,98,
                         103,108,112,116,120,124,128,132,135,138,
                         141,144,147,150,153,156,159,162,165,168,
                         170,172,174,176,178,180,182,184,186,188,
                         190,192,194,196,198,200,202,204,206,208,
                         210,211,212,242,243,245,246,247,248,249,250};    //定每场采哪几行。 根据像素决定。上面下面采到0了说明超出像素了。
                         


#define uchar unsigned char 
#define uint unsigned int; 

void chaopin(void);         
void TIM_init(void);
void shijian(void);
void atd_init(void);             
void pwm_init(void);               
         
           
  void Pos_cal(void) 
{
        unsigned char i;

        char num_on=0;
        int i_sum;
  
        /////////////////////////////////////////////////////////
        num_on = 0;//获得压线传感器的个数 num_on,
	      i_sum =0;//压线传感器的标号(0~14)之和
	      

	      for(i=0; i<=89; i++)
	      {
		        if(ta[16][i]==1)//有一个压线 黑线=1
		        {
			         num_on = num_on + 1;   //压线传感器的个数
			         i_sum  = i_sum + (45-i);    //压线传感器的标号(0~14)之和
		        }
	      }
	      if(num_on!=0) //监测到有传感器压线
	      {
 			      pos_ = i_sum/num_on;  //重心
	      }
	      else//没有一个压线,则跑飞,保持上一次的位置。
	      {
		        pos_=pos_; 
	      }
}
 
        
void main(void) 
{     
int temp_=0; 
DDRA=0X00;
DDRJ=0X02;
DDRK=0X30;
PTJ_PTJ1=1;//RS 0输入指令 1输入数据
PORTK_PK5=1; //R/W  0向lcd输入指令或数据、1从lcd读取数据
PORTK_PK4=1; //E 使能信号  1读取信息  1到0的下降沿执行指令
  

   
   DisableInterrupts;                 
   {
    

                     
    chaopin();             
    atd_init();                      
    TIM_init();//计数器函数初始化   
    shijian();
    pwm_init();
      uart_init();
      delay(900) ;            
      EnableInterrupts; 
    
     {
      unsigned  int e,w;
       for(e=1;e<6;e++) 
        for(w=0;w<10;w++);
   
            
    }
   }
    
  
for(;;) 
  {

   
   
   
       Pos_cal();
       if(pos_<10&pos_>-10)
         pos_=0;
      
   temp_ = straight - 20*(pos_);  //如果转向正好相反,就改成:  straight + (Kp[abs(pos_)])*(pos_);特别注意!!!
	    
	            //temp_ = straight;   //测试居中语句
				         
		  if(temp_ <= straight-turn_max)//最大转角保护 
		  {
			   temp_ = straight-turn_max;	
		  }
		  else if(temp_ >= straight+turn_max)//最大转角保护 
		  {
			   temp_ = straight+turn_max;	
		  }
		  else
		  {
			   temp_ = temp_;
		  }
		  
		  
 PWMDTY23 = temp_;   
   
      
  
      for(hang_uart=0;hang_uart<=99;hang_uart++) {       //用串口观察。根据上面hang_end改这里

       
        printp("%d",ta[16][hang_uart]); 
        
                 {
      unsigned  int e,w;
       for(e=1;e<60;e++) 
        for(w=0;w<100;w++);
   
                 }
        
           
      }
     printp("\n");
  
  }
   
   }
   
  

   
 
 void chaopin(void)
{  
    CLKSEL=0X00;   
    PLLCTL_PLLON=1;   
    SYNR =0xc0 | 0x07;                        
    REFDV=0xc0 | 0x01; 
    POSTDIV=0x00;       
    _asm(nop);          
    _asm(nop);
    _asm(nop);
    _asm(nop);
    while(!(CRGFLG_LOCK==1));   
    CLKSEL_PLLSEL =1;                    
}
void atd_init(void)
{   
   ATD0CTL1=0x00;   
        ATD0CTL2=0X40;  //禁止中断 转换后自动清除寄存器 
        ATD0CTL3=0X88;  //没有断点  没有FIFO 通道0开始 单通道 继续转换右对齐 转换序列1
        ATD0CTL4=0X00;    //4周期,64/2,最快
        ATD0CTL5=0X30;  // 连续转换 多通道转换 通道AN0开始
       ATD0DIEN=0x00;   //相应的数字信号输入禁止

   
} 
void TIM_init(void)
{   
  PACTL=0X50;
  PACNT=0X0000; 
  
    TIOS =0x00;//定时器通道0,1 为输入捕捉 
    TSCR1=0x80;//定时器使能 
    TCTL4=0x18;//通道 1 捕捉下降沿通道 2 捕捉上升沿 
    TIE=0x06;  //通道 1,2 中断使能 
    TFLG1=0xFF;//清中断标志位
      
}
void shijian(void) {
   PITCFLMT_PITE=0;       
   PITCE_PCE0=1;          
   PITLD0=9999;  //1  毫秒
   PITMTLD0=5;      
   PITMUX=0X00;
   PITINTE_PINTE0=1;     
   PITCFLMT_PITE=1; 
   
                   
}
void pwm_init(void)
{
  /********PTTRR *****************************      
             7        6        5        4       3     2          1          0
          PTTRR7    PTTRR6   PTTRR5   PTTRR4    0    PTTRR2    PTTRR1     PTTRR0
            PWM7    PWM6      PWM5     PWM4     0     IOC2      IOC1       IOC0
复位值       0        0        0        0       0      0         0          0 
选择从哪个端口输出
          0->PP7    0->PP6    0->PP5   0->PP4         0->PP2    0->PP1    0->PP0
          1->PT7    1->PT6    1->PT5   1->PT4         1->PT2    1->PT1    1->PT0               
**********PTTRR *****************************************/
     
     // PTTRR = 0x00;         //选择PWM与IOC的端口:PWM对应PP口,IOC对应PT口 
      

     PWME=0x00;  //禁止PWM模块
     

   /* ************ PWMCTL     级联和工作模式控制寄存器  **************   
         7      6     5     4     3     2    1 0
        CON67 CON45 CON23 CON01 PSWAI PFRZ   0 0 
复位状态 0      0     0     0     0     0    0 0
 *******************PWMCTL***************************************/
  PWMCTL_CON23=1; // 二三两个八位的通道结合成十六位的通道从三通道输出
                  // 4高字节,5低字节;5的输出脚作为组合后的输出脚,
                  // 由5来时钟选择,使能,极性控制组合后的特性。
  
  /************* PWMCLK 时钟选择寄存器 ***************************
           7      6       5      4      3      2      1      0
         PCLK7  PCLKL6  PCLK5  PCLK4  PCLK3  PCLK2  PCLK1  PCLK0
复位状态   0      0       0      0      0      0      0      0
         0->B    0->B    0->A   0->A   0->B   0->B   0->A   0->A
         1->SB   1->SB   1->SA  1->SA  1->SB  1->SB  1->SA  1->SA
 *****************PWMCLK*************************************************/                                                           
    PWMCLK=0x00; //
 
/***************PWMPRCLK    设置A  B 时钟分频*************************
----------------------------------------------------------   
      7    6      5     4    3   2     1    0
      *  PCKB2  PCKB1 PCKB0  * PCKA2 PCKA1 PCKA0
Reset 0    0      0     0    0   0     0    0
---------------------------------------------------------  
PCKB2 PCKB1 PCKB0  Value of Clock B            PCKA2 PCKA1 PCKA0 Value of Clock A     
  0     0     0        Bus clock                 0     0     0      Bus clock
  0     0     1        Bus clock / 2             0     0     1      Bus clock / 2
  0     1     0        Bus clock / 4             0     1     0      Bus clock / 4
  0     1     1        Bus clock / 8             0     1     1      Bus clock / 8
  1     0     0        Bus clock / 16            1     0     0      Bus clock / 16
  1     0     1        Bus clock / 32            1     0     1      Bus clock / 32
  1     1     0        Bus clock / 64            1     1     0      Bus clock / 64
  1     1     1        Bus clock / 128           1     1     1      Bus clock / 128
  ***************PWMPRCLK*********************************************************************/
   PWMPRCLK=0x55; // 时钟预分频寄存器 ,时钟 B 频率为 Bus Clock/32 ,时钟 A 频率为 Bus Clock/32
 
  PWMSCLA=0x06;  // SA 时钟分频寄存器 Clock SA=Clock A/(2 * PWMSCLA) = Bus Clock/(32*2*6 =96) 384
  PWMSCLB=0x06;  // SB 时钟分频寄存器 Clock SB=Clock B/(2 * PWMSCLB) = Bus Clock/(2*2*6 =96)= 64/24=2.666M
  
  PWMPOL=0x3f; // PWMPOL_PPOL0=1--- 通道 0 在周期开始时输出为高电平,当计数器等于占空比寄存器的值时,输出为低电平。对外输出波形先是高电平然后再变为低电平
  
// PWMCAE=0x00;   //左对齐和中间对齐设置寄存器默认都为左对齐。
 
 
  PWMPER0=255;  // 周期设置寄存器 , 赋的数值即为每一个周期包含的时钟数 ,  bus Mhz/384  
                // 脉冲数设为200时,电机 8bit   频率为: 1khz     64/32=2M(2000K);0.0005*250=0.125;1/0.125=8KHZ    
                //左对齐输出频率=Clock (A, B, SA, or SB) / PWMPER     因此这里输出频率=64M/32/250=8K
                //右对齐输出频率=Clock (A, B, SA, or SB) / (2*PWMPER)  
 
  PWMDTY0=90;   // 占空比设置寄存器 , 赋的数值即为每一个周期内高电平所占的时钟数
                // 左对齐占空比= [(PWMPER-PWMDTY)/PWMPER] * 100%
                //右对齐占空比= [PWMDTY / PWMPER] * 100%
 
  PWMPER1=255;
  PWMDTY1=0;   // 通道 1 输出一直为低低电平 , 和通道 0 形成电压差 , 用于驱动电机
  
   
  PWMPER4=255;   //因此这里输出频率=80M/32/250=8K
  PWMDTY4=90;  // 左对齐占空比= [(PWMPER-PWMDTY)/PWMPER] * 100%
 
  PWMPER5=255;
  PWMDTY5=0;   // 通道 5 输出一直为低低电平 , 和通道 4 形成电压差 , 用于驱动电机


                    //  2,3 选用通道3作为最后的输出,通道3默认使用时钟 B 为 32 分频 
  PWMPER23 = 40000; // 周期为 20ms,  总线时钟为 64Mhz  32分频    40000*(1/2000) =20MS     
  //PWMPER45 = 25000; // 周期为 20*0.5ms,  总线时钟为:80Mhz  32分频
  //PWMPER45 = 10000; // 周期为 20*0.2ms,  总线时钟为:80Mhz  32分频
                  
  PWMDTY23 = straight;  // 为了设定占空比为 1.5ms , 直线前进
  
  
/*///////////////////////////////////////////////////////////////
  //  PWME 通道使能寄存器
            7    6     5     4     3     2     1     0 
          PWME7 PWME6 PWME5 PWME4 PWME3 PWME2 PWME1 PWME0
 复位状态   0    0     0     0      0     0     0    0
  ///////////////////////////////////////////////////////////////*/
 // PWME=0x3f; // 通道使能寄存器 , 电机 0,1   4,5 通道 , 舵机 3 通道使能
  
 PWME_PWME0 = 1;  // 前进pwm
  PWME_PWME1 = 1;
    PWME_PWME4 = 1;  // 前进pwm
  PWME_PWME5 = 1;
     PWME_PWME3 = 1;
}
      

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

//=======图像采集中断函数,已经完全可以采集图像的=========

 #pragma CODE_SEG NON_BANKED
 void interrupt 10 IC2ISR(void) { //行中断
  
     TFLG1_C2F=1;
   
  if(lie_count==get_n[c_lie]) {  //定距采集图像的判断条件
    delay(1);   //黑线中心矫正,确保不采集到消隐信号

    for(hang_count=0;hang_count<=hang_end;hang_count++){  //读取一行的数据
       
     
      ta[c_lie][hang_count]=PORTA_PA0; //采集数据的接口
   
      
      
    }
     
   c_lie++; //二维数组行自加
  }
  lie_count++; //摄像头行自加

}
  

void interrupt 9 IC1ISR(void){ //场中断,各数据清零              
   TFLG1_C1F=1;
   hang_count=0;
   lie_count=0;
   c_lie=0;   
   }  

void interrupt 66 PIT0Interrupt(void) //测速的中断程序
{
   chesudu=PACNT; //车速度值
    
   PITTF_PTF0=1;
    PACNT=0X0000; 

}   
#pragma CODE_SEG DEFAULT 
//接脚是行同步接pt2  场同步接pt1 

//如果数组ta[c_lie][hang_count]没有图像,请检查接线的问题,以及接口是否按我们所说的接口。

//感谢你对手创科技的支持和信任,我们将不断的努力争取做得更好。

//如果有什么问题,欢迎咨询我们的技术人员。在程序首段有我们的联系方式。

//衷心祝愿我们的客户取得好的成绩! 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -