程序:
/************************************************************
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).
/************************************************************
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;
}
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;
}