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

📄 common_tasks.c

📁 飞思卡尔嵌入式微处理器S12控制程序
💻 C
字号:
#include <hidef.h>      //基本定义和宏定义
#include <mc9s12dg128.h>     //硬件定义
#include "..\Sources\common_defs.h" //自定义常量

#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"

//主循环任务例程
//文件名:main_task.c
//编码人:梁霄
//最后更新时间:2008.06.05 23:06

#define STARTLINE 15 //进行黑线识别的行组的开始行号
#define ENDLINE 20 //进行黑线识别的行组的结束行号
#define STARTDOT 4 //进行黑线识别的每行的开始跳过的无效像素点数目

extern unsigned int lineCounter; //行计数器
extern unsigned int dotCounter; //像素计数器
extern unsigned int processAllow; //允许处理标志

extern byte graph[GRAPHBLOCKNUM][MAX_LINES_PER_FIELD][MAX_DOTS_PER_LINE]; //图像存储区

extern unsigned int centers[LINESOFGROUP]; //每组行的黑线中心
extern unsigned int finalCenter[GROUP]; //每组的平均黑线中心
extern unsigned int total; //黑线中心的总和

void Delay(long); //延时例程(参数为要延时的微秒数)

void SwitchRead(void) 
{
  //开关8:控制电机起停
  if(PORTA_BIT0 == 0) 
  {
    //小灯4点亮
    PORTB_BIT3 = 1;
    //改变电机占空比调速
    PWMDTY23 = 0x0028;
    PWMDTY67 = 0x0000;
  } 
  else 
  {
    PORTB_BIT3 = 0;
    PWMDTY23 = 0x0000;
    PWMDTY67 = 0x0000;
  }
  
}

//舵机调节任务代码
void DirectionAdjust(void) 
{
  //依靠处理取得的前方黑线坐标进行刚性调节,不同
  //的黑线坐标对应不同的舵机转角,从而有不同的占
  //空比设置      
  switch(finalCenter[0]) 
  {
    case 5:
      PWMDTY01=1350;
      break;
    case 6:
      PWMDTY01=1305;
      break;
    case 7:
      PWMDTY01=1445;
      break;
    case 8:
      PWMDTY01=1485;
      break;
    case 9:
      PWMDTY01=1515;
      break;
    case 10:
      PWMDTY01=1545;
      break;
    case 11:
      PWMDTY01=1575;
      break;
    case 12:
      PWMDTY01=1600;
      break;
    case 13:
      PWMDTY01=1625;
      break;
    case 14:
      PWMDTY01=1650;
      break;
    case 15:
      PWMDTY01=1675;
      break;
    case 16:
      PWMDTY01=1700;
      break;
    case 17:
      PWMDTY01=1730;
      break;
    case 18:
      PWMDTY01=1760;
      break;
    case 19:
      PWMDTY01=1790;
      break;
    case 20:
      PWMDTY01=1810;
      break;
    case 21:
      PWMDTY01=1830;
      break;
  }
}

//电机调节任务代码
void SpeedAdjust(void) 
{
  
}

//数据处理任务代码
void DataProcess(void)
{
  unsigned int i,j,workGraph;
  unsigned int find; //每行找到黑线标志
  
  //临时指定一个固定的图像处理区域
  workGraph=0;
  //保存上一行的中心位置以防止找到没有黑线的行
  finalCenter[2] = finalCenter[0];
  
  //选取某一组行进行图像识别,以确定黑线中心的位置
  for(i=STARTLINE;i<ENDLINE;i++) 
  {
    find=0;
    for(j=STARTDOT;j<MAX_DOTS_PER_LINE-2;j++) 
    {
      //如果有三个连续的像素的电平低于指定的阈值,则
      //认为是黑线,并且将这三个像素的中间一个的坐标
      //定为该行的黑线中心坐标
      if((graph[workGraph][i][j])>5&&(graph[workGraph][i][j])<50) 
      {
        if((graph[workGraph][i][j+1])>5&&(graph[workGraph][i][j+1])<50) 
        {
          if((graph[workGraph][i][j+2])>5&&(graph[workGraph][i][j+2])<50) 
          {
            centers[i-STARTLINE]=j+1;
            //标记该行已经找到黑线
            find=1;
            //直接跳出循环,进行下一行分析
            break;
          }
        }
      }
    }
    //如果在某行没有找到黑线,若该行是最开始分析的一行,
    //则用上一次分析的平均黑线中心赋给该行;若该行不是最
    //开始的一行,则用它上面一行的黑线中心坐标作为这一行
    //的黑线中心坐标
    if(!find) 
    {
      if(i==STARTLINE)
        centers[i-STARTLINE]=finalCenter[2];
      else
        centers[i-STARTLINE]=centers[i-STARTLINE-1];
    }
  }
  
  //计算黑线平均中心位置
  total = 0;
  for(i = 0;i < LINESOFGROUP;i++)
    total += centers[i];
  //每组行的黑线中心位置取平均值
  finalCenter[0] = total / LINESOFGROUP;
  
  //如果已经出界,则按原方向转回
  /*if(finalCenter[0] == 0) 
  {
    if(finalCenter[1] == 21 || finalCenter[1] == 20)
    {
      finalCenter[0] = 21;
    } 
    else 
    {
      if(finalCenter[1] == 5 || finalCenter[1] == 6)
        finalCenter[0] = 5;
    }
  }*/
  
  //比较两次的黑线中心坐标,如果差距太大则抛弃
  if((finalCenter[0] - finalCenter[1] >= 7) || (finalCenter[1] - finalCenter[0] >= 7))
    finalCenter[0] = finalCenter[1];
  else
    //保存上一次的中心位置以便校正
    finalCenter[1] = finalCenter[0];
}
  
//延时例程(以微秒为单位)
void Delay(long i) 
{
  //根据第一届的程序可知,在总线频率为24MHz的情况下
  //每运行500次空操作可以延时1毫秒,因此,运行1次可
  //以延时2微秒,所以这个函数的输入最好是偶数
  long m,n;
  m = i / 2;
  for(n = 1;n < m;n++) 
  {
    asm NOP;
  }
}

⌨️ 快捷键说明

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