请指点,类似PLC,可以控制3轴
本帖最后由 wangyy@dianzi 于 2013-8-23 09:58 编辑[有好多人都说STC不好。但我一直用这个片子做项目,感觉良好,没出现过大的问题。STC是有一些缺陷,但是看你怎么用了,“不是GF太狡猾,而是我们太无能”,没别的意思。
STC带领很多玩电子的人入了们,等这些人入门了,技术有了大的提升,就开始骂大街了。STC是国产!!
带有MODBUS通信协议,可以根据自己的项目需求更改
/*------------------------------------------------------------------*/
#include "board.h"
#include "config.h"
/*------------------------------------------------------------------*/
/********************************************************************
*********************************************************************/
bit g_bFlagRunXY = 0;
bit g_bFlagRunZ = 0;
bit g_bFlagRunX2 = 0;
bit g_bFlagRunY2 = 0;
bit g_bFlagRunZ2 = 0;
unsigned char g_ucStepCount = 1;
unsigned int g_unXD = 0; //X轴移动距离
unsigned int g_unYD = 0; //Y轴移动距离
unsigned int g_unZD = 0; //Z轴移动距离
unsigned long g_ulXPlus1 = 0; //X轴脉冲数
unsigned long g_ulYPlus1 = 0; //Y轴脉冲数
unsigned long g_ulZPlus1 = 0; //Z轴脉冲数
unsigned long g_ulXPlus2 = 0; //X轴脉冲数
unsigned long g_ulYPlus2 = 0; //Y轴脉冲数
unsigned long g_ulZPlus2 = 0; //Z轴脉冲数
unsigned int g_unXAbs = 0; //X轴绝对坐标
unsigned int g_unYAbs = 0; //Y轴绝对坐标
unsigned int g_unZAbs = 0; //Z轴绝对坐标
unsigned int g_unXSpeed = 0; //X轴速度
unsigned int g_unYSpeed = 0; //Y轴速度
unsigned int g_unZSpeed = 0; //Z轴速度
unsigned int g_unXC = 0; //X轴频率计数
unsigned int g_unYC = 0; //Y轴频率计数
unsigned int g_unZC = 0; //Z轴频率计数
struct StructData g_strData; //数据
/******************************************************************/
void Port_Init(void);
void Timer0Init(void);
void Timer1Init(void);
void Beep(unsigned int t);
void Delay1ms(void);
void DelayNms(unsigned int t);
void MoveXY(unsigned int XYS, unsigned int X, unsigned int Y);
void MoveZ(unsigned int ZS, unsigned int Z);
void XPulseOut1(void);
void YPulseOut1(void);
void ZPulseOut1(void);
void XPulseOut2(void);
void YPulseOut2(void);
void ZPulseOut2(void);
void Delay2us();
/******************************************************************/
void main()
{
Port_Init();
Timer0Init();
Timer1Init();
UART1_INIT();
Beep(100);
EA = 1;
while(1)
{
if ( g_bFlagRdyOK == 1 ) //接收到完整的数据包后处理
{
//Beep(100);
EA = 0;
askCommModbus(); //判断CRC码,处理数据,发送应答数据
EA = 1;
g_bFlagRdyOK = 0;
g_ucRXData_Counter = 0;
TR1 = 1;
}
//再次添加用户的应用代码
}
}
/*--------------------------------
函数名称: void Port_Init(void)
函数功能: 端口初始化
入口参数: 无
返 回 值: 无
其他说明: 无
---------------------------------*/
void Port_Init(void)
{
P0M1 = 0xFF;
P0M0 = 0x00; //仅为输入
P1M1 = 0x3F;
P1M0 = 0x00; //0-5输入 6,7准双向
P2M1 = 0x00;
P2M0 = 0xFF; //仅为输出
P3M1 = 0x00;
P3M0 = 0xFC; // 2-7输出。0,1准双向
P4M1 = 0x00;
P4M0 = 0x00; // 准双向输出
P0 = 0xFF;
P1 = 0xFF;
P2 = 0xFF;
P3 = 0xFF;
P4 = 0xFF;
RS485_RDE1 = 0; //接受状态
Buzzer = 0;
}
/*--------------------------------
函数名称: void Timer0Init(void)
函数功能: 定时器0初始化
入口参数: 无
返 回 值: 无
其他说明: 无
---------------------------------*/
void Timer0Init(void) //10微秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x02; //设置定时器模式
TL0 = 0x91; //设置定时初值
TH0 = 0x91; //设置定时重载值
TF0 = 0; //清除TF0标志
TR0 = 0;
ET0 = 1;
}
/*--------------------------------
函数名称: void Timer1Init(void)
函数功能: 定时器1初始化
入口参数: 无
返 回 值: 无
其他说明: 无
---------------------------------*/
void Timer1Init(void) // 1毫秒@11.0592MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x10; //设置定时器模式
TH1 = (65536 - (int)((UART0FRAMETESTMS * 11.0592 * 1000)/12)) / 256;
TL1 = (65536 - (int)((UART0FRAMETESTMS * 11.0592 * 1000)/12)) % 256;
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1;
}
/*-----------------------------------------------------------
函数名称: void Timer0_ISR(void) interrupt 1
函数功能: 中断函数
入口参数: 无
返 回 值: 无
其他说明: 无
-----------------------------------------------------------*/
void Timer0_ISR(void) interrupt 1
{
TR0 = 0;
TF0 = 0; //清除TF0标志
//X轴
if(g_bFlagRunXY == 1)
{
XPulseOut1();
}
//Y轴
if(g_bFlagRunXY == 1)
{
YPulseOut1();
}
if((g_ulYPlus1 == 0) && (g_ulXPlus1 == 0))
{
g_bFlagRunXY = 0;
}
//Z轴
if(g_bFlagRunZ == 1)
{
ZPulseOut1();
}
if(g_ulZPlus1 == 0)
{
g_bFlagRunZ = 0;
}
/////////////////////////////////////////////////////////
//X轴
if(g_bFlagRunX2 == 1)
{
XPulseOut2();
}
//Y轴
if(g_bFlagRunY2 == 1)
{
YPulseOut2();
}
//Z轴
if(g_bFlagRunZ2 == 1)
{
ZPulseOut2();
}
TR0 = 1;
}
/*-----------------------------------------------
函数名称:void Timer1_ISR(void) interrupt 1
函数功能:Timer1中断服务
入口参数:无
返回值:无
------------------------------------------------*/
void Timer1_ISR(void) interrupt 3
{
TF1 = 0; //清除TF1标志
TR1 = 0; //关定时器
TH1 = (65536 - (int)((UART0FRAMETESTMS * 11.0592 * 1000)/12)) / 256;
TL1 = (65536 - (int)((UART0FRAMETESTMS * 11.0592 * 1000)/12)) % 256;
if(g_ucRX_Buffer == SLAVEADDRESS)
{
g_bFlagRdyOK = 1;
}
else
{
g_ucRXData_Counter = 0;
TR1 = 1;
}
}
/*-----------------------------------------------------------
函数名称: void MoveXY(unsigned int XYS, unsigned int X, unsigned int Y)
函数功能: XY联动函数
入口参数: XYS: XY轴速度 X,Y: 坐标
返 回 值: 无
其他说明: 无
------------------------------------------------------------*/
void MoveXY(unsigned int XYS, unsigned int X, unsigned int Y)
{
unsigned int a = 0; //加速度
unsigned int k = 0; //分档计数
unsigned int fk = 0;//每一档的频率
if((X > XLENMAX) || (Y > YLENMAX))
{
return;
}
//得到移动距离
g_unXD = abs(g_unXAbs - X);
g_unYD = abs(g_unYAbs - Y);
//判断移动方向
if(g_unXAbs > X) //X轴方向
{
Y6 = 1;
}
else
{
Y6 = 0;
}
if(g_unYAbs > Y) //Y轴方向
{
Y4 = 1;
}
else
{
Y4 = 0;
}
//更新坐标
g_unXAbs = X;
g_unYAbs = Y;
g_unXC = 0;
g_unYC = 0;
//g_unX1msCounter = 0;
//g_unY1msCounter = 0;
g_bFlagRunXY = 1;
g_bFlagRunZ = 1;
//得到设置脉冲数
g_ulXPlus1 = g_unXD * 10;
g_ulXPlus1 = g_ulXPlus1 * XSTEPSREV / XDAOCHENG;
g_ulXPlus1 = 2 * g_ulXPlus1 / 10;
g_ulYPlus1 = g_unYD * 10;
g_ulYPlus1 = g_ulYPlus1 * YSTEPSREV / YDAOCHENG;
g_ulYPlus1 = 2 * g_ulYPlus1 / 10;
g_ulXPlus2 = g_ulXPlus1;
g_ulYPlus2 = g_ulYPlus1;
//计算速度
g_unXSpeed = TDATA(XYS);
g_unYSpeed = TDATA(XYS);
}
/*-----------------------------------------------------------
函数名称: void MoveZ(unsigned int ZS, unsigned int Z)
函数功能: Z移动函数
入口参数: ZS: Z轴速度 Z: 坐标
返 回 值: 无
其他说明: 无
------------------------------------------------------------*/
void MoveZ(unsigned int ZS, unsigned int Z)
{
unsigned int a = 0; //加速度
unsigned int k = 0; //分档计数
unsigned int fk = 0;//每一档的频率
if(Z > ZLENMAX)
{
return;
}
//得到移动距离
g_unZD = abs(g_unZAbs - Z);
//判断移动方向
if(g_unZAbs > Z) //Z轴方向
{
Y12 = 1;
}
else
{
Y12 = 0;
}
//更新坐标
g_unZAbs = Z;
g_unZC = 0;
//得到设置脉冲数
g_ulZPlus1 = g_unZD * 10;
g_ulZPlus1 = g_ulZPlus1 / ZDAOCHENG;
g_ulZPlus1 = g_ulZPlus1 * ZSTEPSREV;
g_ulZPlus1 = 2 * g_ulZPlus1 / 10;
g_ulZPlus2 = g_ulZPlus1;
//计算速度
g_unZSpeed = TDATA(ZS);
}
/*-----------------------------------------------------------
函数名称: void Beep(unsigned int t)
函数功能: 蜂鸣器响函数
入口参数: t: 延时时间
返 回 值: 无
其他说明: 无
-----------------------------------------------------------*/
void Beep(unsigned int t)
{
unsigned int i;
Buzzer = 1;
for(i = 0; i < t; i++)
{
Delay1ms();
}
Buzzer = 0;
for(i = 0; i < t; i++)
{
Delay1ms();
}
}
/*-----------------------------------------------------------
函数名称: void DelayNms(unsigned int t)
函数功能: 延时函数
入口参数: 延时t毫秒
返 回 值: 无
其他说明: 无
-----------------------------------------------------------*/
void DelayNms(unsigned int t)
{
unsigned int i;
for(i = 0; i < t; i++)
{
Delay1ms();
}
}
/*-----------------------------------------------------------
函数名称: void Delay1ms()
函数功能: 1ms延时函数
入口参数: 无
返 回 值: 无
其他说明: 无
-----------------------------------------------------------*/
void Delay1ms(void) //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
/*-----------------------------------------------------------
函数名称: void Delay5us()
函数功能: 5us延时函数
入口参数: 无
返 回 值: 无
其他说明: 无
-----------------------------------------------------------*/
void Delay5us() //@11.0592MHz
{
unsigned char i;
_nop_();
i = 11;
while (--i);
}
/*-----------------------------------------------------------
函数名称: void XPulseOut1(void)
函数功能: X轴脉冲输出1
入口参数: 无
返 回 值: 无
其他说明: 无
-----------------------------------------------------------*/
void XPulseOut1(void)
{
//X轴脉冲输出1
if((g_ulXPlus1 > 0) && (++g_unXC > g_unXSpeed))
{
Delay5us();
Y0 = !Y0;
g_unXC = 0;
--g_ulXPlus1;
}
}
/*-----------------------------------------------------------
函数名称: void XPulseOut2(void)
函数功能: X轴脉冲输出2
入口参数: 无
返 回 值: 无
其他说明: 无
-----------------------------------------------------------*/
void XPulseOut2(void)
{
//X轴脉冲输出2
if(++g_unXC > g_unXSpeed)
{
Delay5us();
Y0 = !Y0;
g_unXC = 0;
}
}
/*-----------------------------------------------------------
函数名称: void YPulseOut1(void)
函数功能: Y轴脉冲输出1
入口参数: 无
返 回 值: 无
其他说明: 无
-----------------------------------------------------------*/
void YPulseOut1(void)
{
//Y轴脉冲输出1
if((g_ulYPlus1 > 0) && (++g_unYC > g_unYSpeed))
{
Delay5us();
Y1 = !Y1;
g_unYC = 0;
--g_ulYPlus1;
}
}
/*-----------------------------------------------------------
函数名称: void YPulseOut2(void)
函数功能: Y轴脉冲输出2
入口参数: 无
返 回 值: 无
其他说明: 无
-----------------------------------------------------------*/
void YPulseOut2(void)
{
//Y轴脉冲输出2
if(++g_unYC > g_unYSpeed)
{
Delay5us();
Y1 = !Y1;
g_unYC = 0;
}
}
/*-----------------------------------------------------------
函数名称: void ZPulseOut1(void)
函数功能: Z轴脉冲输出1
入口参数: 无
返 回 值: 无
其他说明: 无
-----------------------------------------------------------*/
void ZPulseOut1(void)
{
//Z轴脉冲输出1
if((g_ulZPlus1 > 0) && (++g_unZC > g_unZSpeed))
{
Delay5us();
Y2 = !Y2;
g_unZC = 0;
--g_ulZPlus1;
}
}
/*-----------------------------------------------------------
函数名称: void ZPulseOut2(void)
函数功能: Z轴脉冲输出2
入口参数: 无
返 回 值: 无
其他说明: 无
-----------------------------------------------------------*/
void ZPulseOut2(void)
{
//Z轴脉冲输出2
if(++g_unZC > g_unZSpeed)
{
Delay5us();
Y2 = !Y2;
g_unZC = 0;
}
} 有程序吗,支持什么软件, 这楼主需要怎么的样子的解释啊
一块电路板而已啊 PCH 发表于 2013-8-23 07:57 static/image/common/back.gif
有程序吗,支持什么软件,
STC的芯片,C语言编程 xou822 发表于 2013-8-23 08:22 static/image/common/back.gif
这楼主需要怎么的样子的解释啊
一块电路板而已啊
对啊就是电路板,多路输入输出,支持485通信,现在用于机械臂控制 控制机械臂?牛叉呀{:titter:} wangyy@dianzi 发表于 2013-8-23 08:33 static/image/common/back.gif
对啊就是电路板,多路输入输出,支持485通信,现在用于机械臂控制
你不是多轴吗?多轴应该是脉冲输出吧,要不就是DA输出的啊!我还没有下载图看看,你说的多路输入输出应该指的是开关量吧. wangyy@dianzi 发表于 2013-8-23 08:33 static/image/common/back.gif
对啊就是电路板,多路输入输出,支持485通信,现在用于机械臂控制
看原理图了,貌似全部是开关量输入输出?轴的输出体现在哪呢?没有哪个体现出来啊! kinsno 发表于 2013-8-23 09:44 static/image/common/back.gif
你不是多轴吗?多轴应该是脉冲输出吧,要不就是DA输出的啊!我还没有下载图看看,你说的多路输入输出应该 ...
可以作多轴,输出是光耦+高速的开关管,能做脉冲输出,说白了就是开关量。我先面接的是驱动器,驱动器再接步进电机。控制板直接控制驱动器! wangyy@dianzi 发表于 2013-8-23 09:49 static/image/common/back.gif
可以作多轴,输出是光耦+高速的开关管,能做脉冲输出,说白了就是开关量。我先面接的是驱动器,驱动器再 ...
你是这样接的吧:
你的多轴控制器 -> 步进/伺服驱动器 -> 电机
问题1:你是说你这个开关量输出,Y0-Y12全部可以作脉冲输出? 还是特指哪几路? 在图上看着是一样的。
问题2:如果是光藕+高速管,光藕的速度上得去吗?脉冲会变形吧。
问题3:楼主现在实测过最高脉冲量有多少呢? 100K? 500K? 1M?
控制电流多大,好像线有点小 不错,要给STC一个发展的空间。 学习下modbus {:handshake:}{:victory:} kinsno 发表于 2013-8-23 09:54 static/image/common/back.gif
你是这样接的吧:
你的多轴控制器 -> 步进/伺服驱动器 -> 电机
Y0-Y12都可以做脉冲
应为缺少示波器,没有用仪器查看波形,这个会受元器件质量和电阻配置的影响
没有示波器手动算的理论是6.7KHZ
都是实际在设备上测的,调整定时器赋值和定时计数,来达到要求。当然这个要求是在STC的能力范围内的,在要求高就得上STM32了,下一步打算用STM32做CPU wangyy@dianzi 发表于 2013-8-23 10:30 static/image/common/back.gif
Y0-Y12都可以做脉冲
应为缺少示波器,没有用仪器查看波形,这个会受元器件质量和电阻配置的影响
没有示波 ...
6K是理论上的,估计实测5K。
上高速的,比如100K,估计你得上6N137了啊!
kinsno 发表于 2013-8-23 11:11 static/image/common/back.gif
6K是理论上的,估计实测5K。
上高速的,比如100K,估计你得上6N137了啊!
是的,手头还有6N137{:lol:} 中央那个芯片上面写着什么呢 好东西,有参考价值,学习,可以加入类似PLC的时间函数吗
xou822 发表于 2013-8-24 11:22 static/image/common/back.gif
中央那个芯片上面写着什么呢
老妖的。。。 PCH 发表于 2013-8-25 06:27 static/image/common/back.gif
好东西,有参考价值,学习,可以加入类似PLC的时间函数吗
可以的,软件的技术 照着PCB和程序我可以做出来么 我支持国产STC benqme 发表于 2013-8-26 09:32 static/image/common/back.gif
照着PCB和程序我可以做出来么
可以,下一步打算用STM32做 楼主这个牛皮,学习了,希望能多交流,我也做工控.
页:
[1]