导航: 老古网老古论坛XMOS公共讨论区XMOS开源项目区单片机程序设计嵌入式系统广告区域
→请大家帮我看看程序[czoowl]

 *第42989篇: 请大家帮我看看程序

  
楼 主:czoowl 2006年8月30日21:35
 请大家帮我看看程序
51单片机,用T2方波发生器发射方波,用74HC259分成八路分时输出由两个按键控制,一个按键P1_2控制通道的切换,另一个按键P1_3按下时发射方波。
  我的程序在KeilC编译的时候总是有Warning,下面把程序和Warning给大家看看,请多多指点,看看问题出在哪里了。


程序:
/************************************************************
SAmain.c
Name: 新背投六轴控制程序
Creat: 2006/08/29
************************************************************/
#define uchar unsigned char
#define uint unsigned int
//#include "89c55wd.h"

#include   <AT89X55.H>  
uchar bdata channel_num = 0x00;
uchar bdata work_flag = 0x00;
sbit one_pulse = work_flag^0;  // 1:single step complete
sbit run_stop = work_flag^1;    // 1:run     0:stop

void delay (uchar h_data)
{
   uchar bdata l_data;
   while (h_data--)
   {
      for (l_data = 0x00; l_data   < 0xff; l_data++);
   }
}

void initialize (void)
{
   EA = 0;
   EX0 = 0;
   T2CON = 0x00;
   T2MOD = T2MOD|0x02;
   RCAP2H = 0x00;
   RCAP2L = 0x00;
   IE = 0x01;    //INT0
   IT0 = 1;    //edge
   run_stop = 0;
}

uchar keyscan (void)
{
   uchar bdata time_delay = 0x10;
   uchar bdata p1_bak;
   uchar bdata result = 0x00;
   if (P1 & 0x0c != 0x0c)
   {
      delay (time_delay);
      if (P1 & 0x0c != 0x0c)
      {
          p1_bak = P1 & 0x0c;
          if (p1_bak == 0x08) result = 0x01;
          if (p1_bak == 0x04) result = 0x02;
      }
   }
   return (result);
}

void main(void)
{
   uchar bdata key_order;
   uchar bdata i, j;
   uchar bdata onestep_delay;
   initialize();
   EA = 1;
   while (1)
   {
      key_order = keyscan();
      if (key_order == 0x01)
      {
         channel_num++;
         if (channel_num >   0x06) channel_num = 0x00;
           
         switch (channel_num)
         {
            case 0:
               P1_4 = 0;
               P1_5 = 0;
               P1_6= 0;
               break;
            case 1:
               P1_4 = 1;
               P1_5 = 0;
               P1_6= 0;
               break;
            case 2:
               P1_4 = 0;
               P1_5 = 1;
               P1_6 = 0;
               break;
            case 3:
               P1_4 = 1;
               P1_5 = 1;
               P1_6 = 0;
               break;
            case 4:
               P1_4 = 0;
               P1_5 = 0;
               P1_6 = 1;
               break;
            case 5:
               P1_4 = 1;
               P1_5 = 0;
               P1_6 = 1;
               break;
            case 6:
               P1_4 = 0;
               P1_5 = 1;
               P1_6 = 1;
               break;
            default:
               P1_4 = 1;
               P1_5 = 1;
               P1_6 = 1;
         }//end switch (channel_num);
      }
      else if (key_order == 0x02)
      {
         if (~run_stop)
         {
            EX0 = 1;
            TR2 = 1;
            one_pulse = 0;
            i = 0x00;
            j = 0x00;
            while (~one_pulse)
            {
               i++;
               if (~i) j++;
               if (j == 0xff) break;
            }

         }
         else
         {
            onestep_delay ++;
            if (onestep_delay == 0xff)
            {
               EA = 1;
               TR2 = 1;
               onestep_delay++;
            }
            
         }
      }
      else
      {
         TR2 = 0;
         EX0 = 0;
         run_stop = 0;
      }
   }
}


void ext0_int(void) interrupt 0 using  2
{
   EA = 0;
   TR2 = 0;
   one_pulse = 1;
}

下面是编译时报的Warning:
Build target 'Target 1'
assembling STARTUP.A51...
compiling SAmain.c...
linking...
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?PR?_DELAY?SAMAIN
Program Size: data=19.0 xdata=0 code=379
"NewSix" - 0 Error(s), 1 Warning(s).

  
2楼:czoowl 2006年9月2日09:30
 方波脉冲八路分时输出程序
抱歉,原来的程序没有经过仿真验证就发出来了,结果漏洞百出,让大家见笑了。下面的是我上机仿真之后修改过的程序,修改了一些地方,此外加了一些注释,大家帮我看看,挑挑毛病,谢谢!

/************************************************************
SAmain.c
摘要: 新背投六轴控制程序
当前版本: 1.01
Writer: czoowl
完成日期: 2006/08/31
开始编写日期: 2006/08/29
功能简介: 按下按键1,切换方波输出通道,由P1.4~P1.6控制;按下按键2,发方波,先发一个脉冲,
          如果检测到按键没有抬起,过几百毫秒后则连续发方波。
************************************************************/
#define uchar unsigned char
#define uint unsigned int
//#include "89c55wd.h"

#include   <AT89X55.H>  
uchar bdata g_channel_num = 0x07;  //选择哪个通道输出方波
uchar bdata g_work_flag = 0x00;
sbit g_one_pulse = g_work_flag^0;  // 1:single step complete
sbit g_run_stop = g_work_flag^1;    // 1:run     0:stop

void Delay(uchar h_data)
{
   uchar bdata l_data = 0x00;
   while (h_data--)
   {
      for (l_data=0x00; l_data  <0x80; l_data++);
   }
}

void Initialize(void)
{
   EA = 0;
   EX0 = 0;
   T2CON = 0x00;
   T2MOD = T2MOD|0x02;
   RCAP2H = 0x00;
   RCAP2L = 0x00;
   IT0 = 1;    //edge
   g_run_stop = 0;
}

uchar Keyscan(void)  //按键扫描程序
{
   uchar bdata p1_bak = 0x00;
   uchar bdata result = 0x00;
   if ((P1 & 0x0c) != 0x0c)
   {
      Delay(0x80);
      if ((P1 & 0x0c) != 0x0c)  //去抖
      {
          p1_bak = P1 & 0x0c;
          if (0x08 == p1_bak) result = 0x01;
          if (0x04 == p1_bak) result = 0x02;
      }
   }
   return (result);
}

void Main(void)
{
   uchar bdata key_order = 0x00;
   uchar bdata i, j;
   uchar bdata onestep_delay = 0x00;
   Initialize();
   EA = 1;
   while (1)
   {
      key_order = Keyscan();
      if (0x01 == key_order)  //按键1,方波输出通道切换
      {
         g_channel_num++;
         if (g_channel_num >   0x07) 
         {
            g_channel_num = 0x00;
         }
           
         switch (g_channel_num)
         {
            case 0:
               P1_4 = 0;
               P1_5 = 0;
               P1_6 = 0;
               break;
            case 1:
               P1_4 = 1;
               P1_5 = 0;
               P1_6 = 0;
               break;
            case 2:
               P1_4 = 0;
               P1_5 = 1;
               P1_6 = 0;
               break;
            case 3:
               P1_4 = 1;
               P1_5 = 1;
               P1_6 = 0;
               break;
            case 4:
               P1_4 = 0;
               P1_5 = 0;
               P1_6 = 1;
               break;
            case 5:
               P1_4 = 1;
               P1_5 = 0;
               P1_6 = 1;
               break;
            case 6:
               P1_4 = 0;
               P1_5 = 1;
               P1_6 = 1;
               break;
            default:
               P1_4 = 1;
               P1_5 = 1;
               P1_6 = 1;
         }//end of switch (g_channel_num);
      }//end of if (0x01 == key_order)
      else if (0x02 == key_order)  //按键2,发方波
      {
         if (!g_run_stop)  //如果原来是停止状态,先发一个脉冲,单步走一下
         {
            EX0 = 1;
            IT0 = 1;    //edge
            EA = 1;
            TR2 = 1;
            g_one_pulse = 0;
            g_run_stop = 1;
            i = 0x00;
            j = 0x00;
            while (!g_one_pulse)  //等待第一个脉冲发完
            {
               i++;
               if (0 == i) 
               {
                  j++;
               }
               if (0xff == j) 
               {
                  break;
               }             
            }                
         }    
         else  //发完一个脉冲勒,进入连续发状态
         {    
            onestep_delay++;
            Delay(0x02);
            if (0x05 == onestep_delay)  //判断单步之后的延世到了否
            {
               EX0 = 0;
               EA = 1;
               TR2 = 1;
            }
            
         }
      }//end of if (0x02 == key_order)
      else  //无按键,电机停转
      {
         while (INT0);
         TR2 = 0;
         T2 = 0;
         EX0 = 0;
         g_run_stop = 0;
         onestep_delay = 0x00;
      }
   }//end while (1)
}//end main


void Ext0_int(void) interrupt 0 using  2  //EXT0,用来检测第一个脉冲
{
   TR2 = 0;
   EA = 0;
   g_one_pulse = 1;
}

  
3楼:czoowl 2006年9月7日16:41
 这是1.02版程序,请大家帮我看看,有什么不好的习惯,用法请大家指出来,谢谢!
/************************************************************
SAmain.c
摘要: 新背投六轴控制程序
当前版本: 1.02
Writer: czoowl
完成日期: 2006/09/06
开始编写日期: 2006/08/29
功能简介: 
          V1.01:
          按下按键1,切换方波输出通道;按下按键2,发方波,先发一个脉冲,
          如果检测到按键没有抬起,过毫秒后则连续发方波。

          V1.02:
          增加了按住按键后加速运动的功能,初始速度为10Hz,最高速为337Hz。
          硬件上加了一个CD4024分频器进行32分频。
************************************************************/
#define uchar unsigned char
#define uint unsigned int
//#include "89c55wd.h"

#include   <AT89X55.H>  
uchar bdata g_channel_num = 0x07;  //选择哪个通道输出方波
uchar bdata g_work_flag = 0x00;
sbit g_one_step_flag = g_work_flag^0;  // 1:single step complete
sbit g_run_stop_flag = g_work_flag^1;    // 1:run     0:stop

uchar bdata g_key_flag = 0x00;
sbit g_key_channel_flag = g_key_flag^0;  //一次按键切换通道一次

uchar bdata g_run_flag = 0x00;
sbit g_speed_up_down_flag = g_run_flag^0;  //1: speed up     0: speed down

uint bdata g_pulse_frequency = 0xF000;    //the frequency of pulse

void Delay(uchar h_data)  //延时程序,h_data = 1时为1.12ms。
{
   uchar bdata l_data = 0x00;
   while (h_data--)
   {
      for (l_data=0x00; l_data  <0x80; l_data++);
   }
}

void Initialize(void)   //初始化
{
   EA = 0;
   TR0 = 0;
   TR1 = 0;
   ET0 = 1;
   ET1 = 1;
   TMOD = 0x52;
   T2CON = 0x00;
   T2MOD = T2MOD|0x02;
   RCAP2H = 0xF0;
   RCAP2L = 0x00;
   g_pulse_frequency = 0xF000;
   g_run_stop_flag = 0;
   TH1 = 0xff;
   TL1 = 0xff;
   TH0 = 0x00;
   TL0 = 0x00;
   while (T1)  //等待脉冲为低电平
   {
      TR2 = 1;
   }
   TR2 = 0;
   T2 = 0;
}

uchar Keyscan(void)  //按键扫描程序
{
   uchar bdata p1_bak = 0x00;
   uchar bdata result = 0x00;
   if ((P1 & 0x0c) != 0x0c)
   {
      Delay(0x09);
      if ((P1 & 0x0c) != 0x0c)  //去抖 10ms
      {
          p1_bak = P1 & 0x0c;
          if (0x08 == p1_bak) result = 0x01;
          if (0x04 == p1_bak) result = 0x02;
      }
   }
   return (result);
}

void Frequency_change (uint t2_frequency)  //把设定的频率值给定
{
   RCAP2L = (t2_frequency & 0x00ff);
   RCAP2H = (t2_frequency>  >  8);
}

void Main(void)  //主程序
{
   uchar bdata key_order = 0x00;
   uchar bdata i, j;
   uchar bdata onestep_delay = 0x00;
   Initialize();
   EA = 1;
   while (1)
   {
      key_order = Keyscan();
      if (0x01 == key_order)  //按键1,方波输出通道切换
      {
         if (g_key_channel_flag)
         {
            g_channel_num++;
            if (g_channel_num >   0x07) 
            {
               g_channel_num = 0x00;
            }
              
            switch (g_channel_num)
            {
               case 0:
                  P1_4 = 0;
                  P1_5 = 0;
                  P1_6 = 0;
                  break;
               case 1:
                  P1_4 = 1;
                  P1_5 = 0;
                  P1_6 = 0;
                  break;
               case 2:
                  P1_4 = 0;
                  P1_5 = 1;
                  P1_6 = 0;
                  break;
               case 3:
                  P1_4 = 1;
                  P1_5 = 1;
                  P1_6 = 0;
                  break;
               case 4:
                  P1_4 = 0;
                  P1_5 = 0;
                  P1_6 = 1;
                  break;
               case 5:
                  P1_4 = 1;
                  P1_5 = 0;
                  P1_6 = 1;
                  break;
               case 6:
                  P1_4 = 0;
                  P1_5 = 1;
                  P1_6 = 1;
                  break;
               default:
                  P1_4 = 1;
                  P1_5 = 1;
                  P1_6 = 1;
            }//end of switch (g_channel_num);
            g_key_channel_flag = 0;  //防止一次按键执行两次命令
         }
      }//end of if (0x01 == key_order)
      else if (0x02 == key_order)  //按键2,发方波
      {
         if (!g_run_stop_flag)  //如果原来是停止状态,先发一个脉冲,单步走一下
         {
            RCAP2H = 0xF0;
            RCAP2L = 0x00;
            TH1 = 0xff;
            TL1 = 0xff;
            TR1 = 1;
            TR2 = 1;
            g_one_step_flag = 0;
            g_run_stop_flag = 1;
            i = 0x00;
            j = 0x00;
            while (!g_one_step_flag)  //等待第一个脉冲发完
            {
               i++;
               if (0 == i) 
               {
                  j++;
               }
               if (0xff == j) 
               {
                  break;  //超时退出
               }             
            }                
         }    
         else  //发完一个脉冲后,进入连续发状态
         {    
            onestep_delay++;
            Delay(0x10);
            if (0x05 == onestep_delay)  //判断单步之后的延世到了否
            {
               TR2 = 1;
               TR0 = 1;
            }
            
         }
      }//end of if (0x02 == key_order)
      else  //无按键,电机停转
      {
         while (T1)  //等待脉冲为低电平
         {
            TR2 = 1;
         }
         TR2 = 0;
         T2 = 0;
         TR1 = 0;
         TH1 = 0xff;
         TL1 = 0xff;
         g_run_stop_flag = 0;  //STOP
         g_speed_up_down_flag = 1;  //Speed Up
         g_pulse_frequency = 0xF000;
         g_key_channel_flag = 1;
         onestep_delay = 0x00;
      }
   }//end while (1)
}//end main

/*
void Ext0_int(void) interrupt 0 using  1  //EXT0,用来检测第一个脉冲
{
}

*/
void T0_int (void) interrupt 1 using 2  //T0中断,用来加减速
{
   if (0 == g_speed_up_down_flag)  //减速,暂时未用
   {
      g_pulse_frequency -= 0x02;
      if (g_pulse_frequency   < 0xF000)
      {
         while (T1)  //等待脉冲为低电平
         {
            TR2 = 1;
         }
         TR2 = 0;
         T2 = 0;
         TR0 = 0;
         g_pulse_frequency = 0xF000;
      }
      Frequency_change(g_pulse_frequency);
   }
   else  //加速
   {
      g_pulse_frequency += 0x02;
      if (g_pulse_frequency >   0xFF00)
      {
         TR0 = 0;
         g_pulse_frequency = 0xFF00;
      }
      Frequency_change(g_pulse_frequency);
   }
}

void T1_int (void) interrupt 3 using 3  //T1中断,用来测移动的位移和单步
{
   while (T1)  //等待脉冲为低电平
   {
      TR2 = 1;
   }
   TR2 = 0;
   T2 = 0;
   g_one_step_flag = 1;
}

  
4楼:czoowl 2006年9月7日16:45
 这是原理图

此主题相关图片如下:
按此在新窗口浏览图片

>>>>>>对该主题发表你的看法

本主题贴数4,分页: [第1页]


[上一篇主题]:驱动lcd各个引脚电压基本都对,但不能显示,背光都打不开,请教!

[下一篇主题]:紧急求购数码相框方案