智能车制作

标题: 模拟摄像头程序代码 [打印本页]

作者: zhye3690592    时间: 2013-3-27 15:29
标题: 模拟摄像头程序代码
[attach]42861[/attach]

#include <hidef.h>
#include "derivative.h"
#include <MC9S12XS128.h>
#include "5X8ziku.h"
#define uchar unsigned char
#define uint unsigned int
//LCD_RST
#define LCD_RST_SET    PORTB_PB1=1 //PC1
#define LCD_RST_RESET           PORTB_PB1=0//PC1
//LCD_SCLK
#define LCD_SCLK_SET    PORTB_PB4=1 //PC4
#define LCD_SCLK_RESET       PORTB_PB4=0//PC4
//LCD_SDA  
#define LCD_SDA_SET        PORTB_PB3=1 //PA3
#define LCD_SDA_RESET               PORTB_PB3=0//PA3
//LCD_RS
#define LCD_RS_SET        PORTB_PB2=1 //PC2
#define LCD_RS_RESET        PORTB_PB2=0//PC2
//LCD_CS  
#define LCD_CS_SET        PORTB_PB0=1 //PA0
#define LCD_CS_RESET      PORTB_PB0=0//PA0

#define ROW 40
#define COLUMN 120
#define txd PORTA_PA0
uchar Image_Data[ROW][COLUMN];
static uchar  sz[40]={ 30,31,32,
                34,36,38,
                41,44,47,
                51,55,59,
                64,69,74,
                80,86,92,
                98,104,110,
                116,122,128,
                134,140,146,
                152,158,164,
                170,176,182,
                188,194,200,
                206,212,218,
                224//,230
                };
static int turn;
static uchar Line_CL=0,Line_C=0,md,MP0,MP1,MP2;
static uint yw; //目标车速
static int wc1,wc2,PWM,yjwc,new,old;//误差 1 2 3
static uchar VSYN_C=0; //场数

/***************************************************
** 函数名称: PLL_Init
** 功能描述: 时钟初始化函数
** 说明: PLLCLK=2*OSCCLK(外部晶振时钟)*(SYNR+1)/(REFDV=+1)
****************************************************/
void PLL_Init(void)        //(以下带括号的都是标注的查询信息)
                    
{     
   CLKSEL=0x00;   //(PLL系统脱离)
   PLLCTL_PLLON=1;    //(打开PLL)
   SYNR=0XC0 | 0X08;   // 08,01 72MHz  0B,01 96MHz     (时钟合成寄存器)
   REFDV=0X80 | 0X01;                       //(时钟分频寄存器)
   POSTDIV=0X00;
   _asm(nop);                //(执行一个空语句 null opreation 延时有时软件抗干扰时要用到,使跑飞的程序入正轨)
   _asm(nop);
   while(0==CRGFLG_LOCK);//锁相环锁定        (是不是需改成这个while(!(CRGFLG_LOCK==1));     //when pll is steady ,then use it;)
   CLKSEL_PLLSEL=1;//选定外部时钟       (PLL系统进行)
}

void Delay(uint cs)
{  uint csbl;
   for(csbl=0;csbl<cs;csbl++)
   _asm(nop);
}
  
/***************************************************
** 函数名称: TIM_Init
** 功能描述: 行场中断初始化函数
** 说明:   ECT模块
****************************************************/
void TIM_Init(void)
{
   TIOS=0x00;          //外部输入捕捉 0,1 通道  
   TCTL4=0x09;         //通道 0上升沿触发,通道 1 下降沿触发    (TCTL4=0x06;    //通道0上升沿触发,通道 1 下降沿触发)
   TSCR1=0x80;         //使能
   TIE=0x02;           //通道 1中断使能  这里只开启场中断  后面场中断中开启行中断 (TIE=0x03;//通道 0,1 中断使能)
   TFLG1=0xFF;         //清中断标志位
}

/***************************************************
** 函数名称: SCI_Init
** 功能描述: 串口初始化函数
** 说明: 当PLLSET=1时BusClock=PLLCLK/2  当PLLSET=0时BusClock=OSCCLK/2
** 比特率:Baud Rate=BusClock/(16*SCIBD)
****************************************************/
void SCI_Init()
{
    SCI0BD=0xEA;     // Baud Rate=BusClock/(16*SCIBD)
                     //BusClock 72MHz, 19200bps,SCI0BD=0xEA     
                     //BusClock 96MHz, 19200bps,SCI0BD=0x138  
    SCI0CR1=0x00;         //正常8位模式,无奇偶校验
    SCI0CR2=0x2C;      //发送允许   接受中断允许  
}
/**************************************************
** 函数名称: SCI_Write
** 功能描述: 给串行口写一个字符数据
** 输    入: SendChar为写入字符
** 输    出: 无
** 说明:  
***************************************************/
void SCI_Write(uchar SendChar)
{
    while (!(SCI0SR1&0x80));  
    SCI0DRH=0;                //高位寄存器一般用不到
    SCI0DRL=SendChar;         //SCI0D RL相当于51中的SUBBF寄存器
}


/*---------------读取图像数值------------------*/
void Read_sz(uchar lie,uchar hang)
{   
   
   if(txd==1)
    Image_Data[lie][hang]=0x00;
   else
    Image_Data[lie][hang]=0xff;        
}
/**************************************************
** 函数名称: 减速控制
** 功能描述: 入弯减速
** 输    入:
** 输    出:  
***************************************************/
void jian_su(uint i)
{  
  PWMPER23=0;
  
  wc2=wc1-(i-yw);
  //SCI_Write(yw);
  PWM=PWM+ wc1*wc1*wc1+wc2*wc2*wc2;
  if (PWM>1800)
    PWM=1800;
  else if (PWM < 0)
    PWM=0;
  PWMPER45=PWM;
  wc1=i-yw;
}

//---------------------中断定义---------------------
#pragma CODE_SEG NON_BANKED
/**************************************************
** 函数名称: 中断处理函数
** 功能描述: 行中断处理函数
** 输    入: 无
** 输    出: 无
** 说明: 中断8
***************************************************/
interrupt 8 void HREF_Count(void)
{  
   uchar j;
   
   TFLG1_C0F = 1; //清8中断
   
   
   if(Line_CL == sz[Line_C])
    {  
     
     Delay(30);
     for(j=0;j<COLUMN; j++)
      {
       _asm(nop);//yanshi
       Image_Data[Line_C][j]=PORTA;
      }
      Line_C++;
      
    }
   if( Line_C < 40)   
     Line_CL++;     //行数加一  
}


/**************************************************
** 函数名称: 中断处理函数
** 功能描述: 场中断处理函数
** 输    入: 无
** 输    出: 无
** 说明: 中断9
***************************************************/
interrupt 9 void VSYN_Interrupt(void)//优先级高
{   
     VSYN_C++;      //场数加一
     //PORTB=VSYN_C;  //PORTB口输出当前场数
     Line_CL = 0;   //行中断次数清零
      Line_C = 0;
   
     
     TIE=0x03;      //行场中断同时开启
     TFLG1_C1F = 1; //清9中断
     TFLG1_C0F = 1; //清8中断
     yw=PACNT&0X0fff;  
     PACNT=0x0000;
}
/***********************************液晶lcd12864**********************************************/
void delay_us(uint  time)
{     
   while (time--);
}

/*     毫秒级延时函数 */
void delay(uint  time)               
{
while(time--) delay_us(100);
}

void FSPI_SendData(uchar data1)
{
  uchar i;
for(i=0;i<8;i++)
   {
  LCD_SCLK_RESET;
  if(data1&0x80)
   LCD_SDA_SET;
  else
   LCD_SDA_RESET;
    LCD_SCLK_SET;
  data1=data1<<=1;
   }
}

/*******************************************************************************
//函数名: Lcdwritecom
//功能:lcd写指令
//输入:com指令
//输出:无
********************************************************************************/
void Lcdwritecom(uchar com)
{
LCD_CS_RESET;  //片选拉低,选中LCD
LCD_RS_RESET;  //设置为写命令
FSPI_SendData(com);
    LCD_CS_SET;   //片选拉高,释放LCD
}
/*******************************************************************************
//函数名:Lcdwritedata
//功能:lcd写数据
//输入:dat数据
//输出:无
********************************************************************************/
void Lcdwritedata(uchar dat)
{
LCD_CS_RESET;  //片选拉低,选中LCD
LCD_RS_SET;  //设置为写数据
    FSPI_SendData(dat);
    LCD_CS_SET;  //片选拉高,释放LCD
}
/*LCD模块初始化*/
void initial_lcd()
{
LCD_CS_RESET;
LCD_RST_RESET;        /*低电平复位*/
delay(20);
LCD_RST_SET ;      /*复位完毕*/
delay(20);        
Lcdwritecom(0xe2);  /*软复位*/
delay(5);
Lcdwritecom(0x2c);  /*升压步聚1*/
delay(5);
Lcdwritecom(0x2e);  /*升压步聚2*/
delay(5);
Lcdwritecom(0x2f);  /*升压步聚3*/
delay(5);
Lcdwritecom(0x24);  /*粗调对比度,可设置范围0x20~0x27*/
Lcdwritecom(0x81);  /*微调对比度*/
Lcdwritecom(0x20);  /*0x28,微调对比度的值,可设置范围0x00~0x3f*/
Lcdwritecom(0xa2);  /*1/9偏压比(bias)*/
Lcdwritecom(0xc8);  /*行扫描顺序:从上到下*/
Lcdwritecom(0xa0);  /*列扫描顺序:从左到右*/
Lcdwritecom(0x40);  /*起始行:第一行开始*/
Lcdwritecom(0xaf);  /*开显示*/
LCD_CS_SET;
}
void lcd_address(uint page,uint column)
{
column=column-0x01;
Lcdwritecom(0xb0+page-1);   /*设置页地址*/ //1-8
Lcdwritecom(0x10+(column>>4&0x0f)); /*设置列地址的高4位*///0-128
Lcdwritecom(column&0x0f); /*设置列地址的低4位*/
}
/*全屏清屏*/
void clear_screen()
{
unsigned char i,j;
LCD_CS_RESET;
for(i=0;i<9;i++)
{
  Lcdwritecom(0xb0+i);
  Lcdwritecom(0x10);
  Lcdwritecom(0x00);
  for(j=0;j<132;j++)
  {
   Lcdwritedata(0x00);
  }
}
  LCD_CS_SET;
}
/*显示128x64点阵图像*/
void display_128x64(uchar *dp)
{
uint i,j;
LCD_CS_RESET;
for(j=0;j<8;j++)
{
  lcd_address(j+1,1);
  for (i=0;i<128;i++)
  {
    Lcdwritedata(*dp);   /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
    dp++;
  }
}
LCD_CS_SET;
}

/*显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标*/
void display_graphic_16x16(uint page,uint column,uchar *dp)
{
uint i,j;
  LCD_CS_RESET;
for(j=0;j<2;j++)
{
  lcd_address(page+j,column);
  for (i=0;i<16;i++)
  {
   Lcdwritedata(*dp);  /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
   dp++;
  }
}
LCD_CS_SET;

}

/*显示8x16点阵图像、ASCII, 或8x16点阵的自造字符、其他图标*/
void display_graphic_8x16(uint page,uchar column,uchar *dp)
{
uint i,j;
LCD_CS_RESET;
for(j=0;j<2;j++)
{
  lcd_address(page+j,column);
  for (i=0;i<8;i++)
  {
   Lcdwritedata(*dp);   /*写数据到LCD,每写完一个8位的数据后列地址自动加1*/
   dp++;
  }
}
LCD_CS_SET;
}

/*显示5*8点阵图像、ASCII, 或5x8点阵的自造字符、其他图标*/
void display_graphic_5x8(uint page,uchar column,uchar *dp)
{
uint col_cnt;
    LCD_CS_RESET;
    lcd_address(page,column);
for (col_cnt=0;col_cnt<5;col_cnt++)
{
  Lcdwritedata(*dp);
  dp++;
}
LCD_CS_SET;
}
void ASCII_function(uint page,uchar column,uchar zz)
{
uchar *dp;
dp=ziku5x8+zz*5-0xA0;
display_graphic_5x8(page,column,dp);     
}
void lcd_xianshi(uint page,uchar column,uint i)
{
uint j,z;
uchar n=0,wz,m[20];
j=i;
while(j > 0)
{
  z=j/10;
  m[n]=j-z*10;
  j=z;
  n++;
}
wz=column;
for(;n>0;n--)
{
ASCII_function(page,wz,m[n-1]+0x30);
wz=wz+5;
}
ASCII_function(page,wz,0x20);
}


void String_function(uint page,uchar column,uchar *dp)
{

  
  while(dp[0] != 0x20)
   {
  ASCII_function(page,(column-1)*5+1,dp[0]);
  column++;
  dp++;
   }

}


void xstx()
{
    uchar i,j,tx,u,m;
            for(j=0;j<120;)
               {
                 for(u=0;u<5;)
                    {
                      m=u*8+i;
                      switch (i)
                       {
                       case 0:  tx=Image_Data[m][j]+tx;break;
                       case 1:  tx=Image_Data[m][j]*2+tx;break;
                       case 2:  tx=Image_Data[m][j]*4+tx;break;
                       case 3:  tx=Image_Data[m][j]*8+tx;break;
                       case 4:  tx=Image_Data[m][j]*16+tx;break;
                       case 5:  tx=Image_Data[m][j]*32+tx;break;
                       case 6:  tx=Image_Data[m][j]*64+tx;break;
                       case 7:  tx=Image_Data[m][j]*128+tx;break;
                       }
                     i++;
                     if(i==8)
                       {
                        lcd_address(u+4,j+1);
                        Lcdwritedata(tx);
                        tx=0;
                        i=0;
                        u++;  
                       }
                    }
                    j++;
                }
}

/**************************************************
** 函数名称: zongxiang
** 功能描述: 纵向查找边界
** 输    入:位置 横向:hang 纵向:lie
** 输    出: 查找的位置
** 说明:   
***************************************************/
uchar zongxiang(uchar hang,uchar lie) //纵向查找
{
   while(Image_Data[hang][lie]==0x00)//白色查找  00为黑
   {
      hang--;
      if(hang==0)
        break;
   }
   return hang ;  //列中线上黑白交界的行数
}
/**************************************************
** 函数名称: Left_find
** 功能描述: 查找左边界
** 输    入: 位置 横向:hang 纵向:lie  
** 输    出: 查找的左边界
** 说明:
***************************************************/
uchar Left_find(uchar hang,uchar lie)
{
      uchar i,j;
       i=hang; j=lie;
      while(Image_Data[j]==0x00)//白色查找
       {
        j--;
        if(j==0)
          break;
       }
      return j;//左边界
}
/**************************************************
** 函数名称: Right_find
** 功能描述: 查找右边界
** 输    入: 位置 横向:hang 纵向:lie  
** 输    出: 查找的右边界
** 说明:
***************************************************/
uchar Right_find(uchar hang,uchar lie)
{
      uchar i,j;
       i=hang; j=lie;
      while(Image_Data[j]==0x00)//白色查找
       {
        j++;
        if(j==COLUMN)
          break;
       }
     return j;//右边界
}

/**************************************************
** 函数名称: Middle_find
** 功能描述: 查找中间列上与行的交点
** 输    入: 位置 横向:hang 纵向: lie
** 输    出: 与中间列相交的行数
** 说明:
***************************************************/
uchar Middle_find(uchar hang ,uchar lie)
{
    uchar zb,yb,md;
    zb=Left_find(hang,lie);
    yb=Right_find(hang,lie);
    md=(zb+yb)/2;
    //lcd_xianshi(1,1,md);
    //PORTB=md;
    return md;
}

void yunxing()
{

  uchar md,zb,yb;//中线数值 左边  右边
  MP1=zongxiang(40,60);//中间列数据
  //lcd_xianshi(2,20,MP1);
  if (MP1==0) //直道
    {
      md=Middle_find(20,60);
      
      turn=(md-60)*10;
    }
else if(MP1 < 18 )//微调入弯
   {
     MP0=zongxiang(40,30);
     MP2=zongxiang(40,90);
     if(MP0>MP2)
     {
      turn=MP1*25;
     }
     else if (MP0<MP2)
     {
     turn=-MP1*25;
     }
   }
  else
   {
     new=MP1-18;
     yjwc=new-old;
     MP0=zongxiang(40,40);
     MP2=zongxiang(40,80);
     if(MP0>MP2)
     {
      turn=turn+new*10+yjwc*2;
     }
     else if (MP0<MP2)
     {
     turn=turn-(new*10+yjwc*2);
     }
     old=new;
   }
   
   if (turn>400)
     turn=400;
   else if(turn<-400)
     turn=-400;
   
  PWMDTY01 = 1500-turn;
}
/*************************************************************
      舵机初始化        
*************************************************************/
void PWM_01(void)
{   
    PWME_PWME1 = 0;   
    PWMCTL_CON01=1;    //0和1联合成16位PWM;
    PWMCAE_CAE1=0;     //选择输出模式为左对齐输出模式
    PWMCNT01 = 0;      //计数器清零;
    PWMPOL_PPOL1=1;    //先输出高电平,计数到DTY时,反转电平
    PWMPRCLK = 0X22;   //clockA 不分频,clockB=busclock;clockA 4分频:18Mhz
    PWMSCLA = 0x09;    //对clockSA 18分频,clockSA=clockA/(2*PWMSCLA);     
    PWMCLK_PCLK1 = 1;  //选择clockSA做时钟源 1Mhz 周期为1微秒
    PWMPER01 = 20000;   //0x57 PWM1的周期16ms 50Hz PWMx的周期=通道时钟周期*PWMPERx
    PWMDTY01 = 1500;    //0x6 当PWMPOL_PPOLx为高电平时 占空比=PWMDTYx/PWMPERx
    PWME_PWME1 = 1;   
}


/*************************************************************/
/*                    电机初始化                             */
/*************************************************************/
void PWM_35(void)
{
  
  PWMCTL_CON23= 1;   //通道23为16位的PWM
  PWMCTL_CON45= 1;   //通道01为16位的PWM


  PWMPOL_PPOL5= 1;   //通道的极性为高电平有效
  PWMPOL_PPOL3= 1;   //通道的极性为高电平有效
  PWMPRCLK = 0x22;   //总线时钟72mhz,A时钟和B时钟的分频系数为4,频率为18MHz
  PWMSCLA  =    9;   //SA时钟频率为1MHz
  PWMSCLB  =    9;
  PWMCLK_PCLK5= 0;   //45和23用A,B时钟
  PWMCLK_PCLK3= 0;
  PWMCAE   = 0x00;   //脉冲模式为左对齐模式
  
  PWMPER45  = 1800;   //通道01的周期为10KHz
  PWMPER23  = 1800;   //通道23的周期为10KHz
  
  PWMDTY23  = 0;     //通道23的占空比设置
  PWMDTY45  =900;  //通道01的占空比设置 最大1800

  PWME_PWME5=1;  
  PWME_PWME3=1;

}

/**************************************编码器***********************************************/

void TIM_Init1(void)//脉冲累计初始化
{
    PACTL=0x50;//下降沿触发kongzhi寄存器
    PACNT=0x0000;//清0缓冲寄存器
}









/***************************************************
** 函数名称: main
** 功能描述: 主函数
** 说明:
****************************************************/  
void main(void)
{

  
  VSYN_C=0;
  DisableInterrupts;
  DDRA=0X00; //将PA口设为输入
  DDRB=0Xff;//将PB口设为输出
  PLL_Init();
  SCI_Init();
  TIM_Init();
  TIM_Init1();
  PWM_01();
  PWM_35();
  /*初始化lcd*/
  initial_lcd();
  clear_screen();
  EnableInterrupts;
      
  PORTA=0X00;

  
  for(;;) //括号内是什么意思啊     死循环可用while(1)替代
  {   
           
        if(VSYN_C==2)
        {
         
         TIE=0x02;  //只开场中断?
          //xstx() ;   //显示图像
          yunxing();
        
        
         VSYN_C=0;
        }
        
        jian_su(25); //15指的是什么??目标车速
  }
}
        
本人不发无聊的代码 下载后认真测试评论
尊重他人,尊重自己!!!谢谢!!!

作者: dlyt03    时间: 2013-3-29 14:05
顶!!!
作者: 可欣    时间: 2013-3-30 07:26
学习了
作者: oscarpanpan    时间: 2013-4-15 22:09
我们用的是K60 求程序移植 方法
1743479982@qq.com
作者: 与狼共舞    时间: 2013-4-16 16:28
怎么电机抖动的厉害???

作者: 岁月SongY    时间: 2013-5-11 15:37
lz这个用cw哪个 版本的???
作者: lpyifendou    时间: 2013-5-27 20:13
#include "5X8ziku.h"这个头文件没有,能告诉下内容是什么吗,求学习指导。
作者: 简单丹    时间: 2013-5-30 14:21
”interrupt 9 void VSYN_Interrupt(void)//优先级高“是默认高优先级还是哪儿设置的呀............
作者: 大葱160811204    时间: 2013-8-23 09:14

作者: 残风依旧    时间: 2013-12-8 22:20
我用的也是k60,求移植程序!
作者: 空心杯    时间: 2014-3-16 17:14

作者: 健马行风    时间: 2014-4-4 12:57
求k60摄像头程序啊!!!
作者: 殇夜    时间: 2014-5-31 16:28
只有采集部分的代码吗?





欢迎光临 智能车制作 (http://111.231.132.190/) Powered by Discuz! X3.2