#include <reg52.h>
//-----STC89C2051-------
sfr IPH =0XB7;
sfr CCON =0XD8;
sfr CMOD =0XD9;
sfr CL =0XE9;
sfr CH =0XF9;
sfr CCAP0L =0XEA;
sfr CCAP0H =0XFA;
sfr CCAPM0 =0XDA;
sfr CCAPM1 =0XDB;
sfr P3M1= 0XB1;
sfr P3M0= 0XB2;
sfr P1M1= 0X91;
sfr P1M0= 0X92;
sfr WAKE_CLKO= 0X8f;
sfr BRT =0x9c;
sfr AUXR =0x8E;
sfr AUXR1 = 0xA2;
sfr WDT_CONTR = 0xc1;
sfr T2MOD = 0xC9;
//////////////////
sbit s1 = P1^6;
sbit s2 = P1^7;
sbit b1 = P3^7;
sbit cs2 = P1^4;
sbit cs = P1^3;
sbit sck = P1^2;
sbit out = P1^0;
sbit in = P1^1;
#define SPI2_CSHIGH cs2=1 // CS2
#define SPI2_CSLOW cs2=0
#define SPI_CSHIGH cs=1 // CS
#define SPI_CSLOW cs=0
#define SPI_SCKHIGH sck=1 //SCLK
#define SPI_SCKLOW sck=0
#define SPI_OUTHIGH out=1
#define SPI_OUTLOW out=0//MOSI
#define SPI_IN in//MISO
unsigned char inbuf[12];
void initial()
{
SPI_CSHIGH;
SPI2_CSHIGH;
}
void delay_nus(unsigned long n)
{
unsigned long j;
while(n--)
{
j=8;
while(j--);
}
}
//延时n ms
void delay_nms(unsigned long n)
{
while(n--)
delay_nus(1100);
}
/*
函数名: SPI_SendData
功能:软件模拟SPI通讯发送并接收一个8位字节数据。
*/
unsigned char SPI_SendData(unsigned char outdata)
{
unsigned char RecevieData=0,i;
for(i=0;i<8;i++)
{
SPI_SCKLOW;
if(outdata&0x80)
{
SPI_OUTHIGH;
}
else
{
SPI_OUTLOW;
}
outdata<<=1;
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
SPI_SCKHIGH;
RecevieData <<= 1;
if(SPI_IN)
{
RecevieData |= 1;
}
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
SPI_SCKLOW;
}
return RecevieData;
}
/*
函数名: enabled_cs
功能:使能对应芯片的CS脚
参数:
cardno 卡号
用单片机不同引脚去控制不同芯片的CS脚,以便多个芯片关联使用。
*/
void enabled_cs(unsigned char cardno)
{
if(cardno==1)
{
SPI_CSLOW;
}
else if(cardno==2)
{
SPI2_CSLOW;
}
}
/*
函数名: disabled_cs
功能:禁止对应芯片的CS脚
参数:
cardno 卡号
用单片机不同引脚去控制不同芯片的CS脚,以便多个芯片关联使用。
*/
void disabled_cs(unsigned char cardno)
{
if(cardno==1)
{
SPI_CSHIGH;
}
else if(cardno==2)
{
SPI2_CSHIGH;
}
}
/*
函数名: set_speed
功能:设置轴速度
参数:
cardno 卡号
axis 轴号(1-6)
acc 加速时间(ms)
dec 减速时间(ms)
startv 启动频率为:值*频率倍率(Hz)
speed 运行频率为:值*频率倍率(Hz)
range 频率倍率(1-100)
*/
unsigned char set_speed(unsigned char cardno ,unsigned char axis ,unsigned int acc ,unsigned int dec ,unsigned int startv ,unsigned int speed ,unsigned char range)
{
unsigned char OutByte[25];
OutByte[0] = 1;
OutByte[1] = axis;
OutByte[2] = acc >>8;
OutByte[3] = acc ;
OutByte[4] = dec >>8;
OutByte[5] = dec ;
OutByte[6] = startv >>8;
OutByte[7] = startv ;
OutByte[8] = speed >>8;
OutByte[9] = speed ;
OutByte[10] = range;
enabled_cs(cardno);
SPI_SendData(OutByte[0]);
SPI_SendData(OutByte[1]);
SPI_SendData(OutByte[2]);
SPI_SendData(OutByte[3]);
SPI_SendData(OutByte[4]);
SPI_SendData(OutByte[5]);
SPI_SendData(OutByte[6]);
SPI_SendData(OutByte[7]);
SPI_SendData(OutByte[8]);
SPI_SendData(OutByte[9]);
SPI_SendData(OutByte[10]);
disabled_cs(cardno);
}
/*
函数名: pmove
功能:单轴运行
参数:
cardno 卡号
axis 轴号(1-2)
pulse 输出的脉冲数 >0:正方向移动 <0:负方向移动 范围(-268435455~+268435455)
mode 0:相对位移 1:绝对位移 2:连续位移
*/
unsigned char pmove(unsigned char cardno ,unsigned char axis,long pulse , unsigned char mode)
{
unsigned char OutByte[25];
OutByte[0] = 2 ;
OutByte[1] = axis;
OutByte[2] = pulse >>24;
OutByte[3] = pulse >>16;
OutByte[4] = pulse >>8;
OutByte[5] = pulse ;
OutByte[6] = mode ;
enabled_cs(cardno);
SPI_SendData(OutByte[0]);
SPI_SendData(OutByte[1]);
SPI_SendData(OutByte[2]);
SPI_SendData(OutByte[3]);
SPI_SendData(OutByte[4]);
SPI_SendData(OutByte[5]);
SPI_SendData(OutByte[6]);
SPI_SendData(0);
disabled_cs(cardno);
}
/*
函数名: set_command_pos
功能: 设置轴逻辑位置
参数:
cardno 卡号
axis 轴号(1-2)
pulse 位置脉冲数,范围(-268435455~+268435455)
*/
unsigned char set_command_pos(unsigned char cardno ,unsigned char axis, long value )
{
unsigned char OutByte[25];
OutByte[0] = 0x12 ;
OutByte[1] = axis ;
OutByte[2] = value >>24;
OutByte[3] = value >>16;
OutByte[4] = value >>8;
OutByte[5] = value ;
enabled_cs(cardno);
SPI_SendData(OutByte[0]);
SPI_SendData(OutByte[1]);
SPI_SendData(OutByte[2]);
SPI_SendData(OutByte[3]);
SPI_SendData(OutByte[4]);
SPI_SendData(OutByte[5]);
disabled_cs(cardno);
}
/*
函数名: sudden_stop
功能: 轴停止
参数:
cardno 卡号
axis 停止的轴号(1-2) 1-2:1-2轴停
*/
unsigned char sudden_stop(unsigned char cardno ,unsigned char axis)
{
unsigned char OutByte[25];
OutByte[0] = 0x17 ;
OutByte[1] = axis ;
enabled_cs(cardno);
SPI_SendData(OutByte[0]);
SPI_SendData(OutByte[1]);
disabled_cs(cardno);
}
/*
函数名: get_command_pos
功能: 获取轴逻辑位置或状态。
本函数先发一条指令过去让芯片准备相应的数据,等待1MS后,再从芯片读取4个字节的相应数据。
参数:
cardno 卡号
axis 轴号 1,1轴 2,2轴 100,会返回两个轴的状态。0位为第一轴状态。1位为第二轴状态。0表示停止中,1表示运行中。
返回值: 位置脉冲数,范围(-268435455~+268435455)或者两个轴的状态
*/
long get_command_pos( unsigned char cardno, unsigned char axis)
{
unsigned char OutByte[25];
unsigned char inbuf[12];
long tmp=0;
OutByte[0] = 0x06;
OutByte[1] = axis ;
enabled_cs(cardno);
SPI_SendData(OutByte[0]);
SPI_SendData(OutByte[1]);
disabled_cs(cardno);
delay_nms(1);
enabled_cs(cardno);
inbuf[0]=SPI_SendData(0);
inbuf[1]=SPI_SendData(0);
inbuf[2]=SPI_SendData(0);
inbuf[3]=SPI_SendData(0);
disabled_cs(cardno);
delay_nms(1);
tmp= (long)inbuf[0]<<24;
tmp+= (long)inbuf[1]<<16;
tmp+= (long)inbuf[2]<<8;
tmp+= (long)inbuf[3];
return tmp;
//return(((long)inbuf[0]<<24)+((long)inbuf[1]<<16)+((long)inbuf[2]<<8)+((long)inbuf[3]));
}
/*
函数名: set_special
功能:设置特别功能
参数:
cardno 卡号(1-128)芯片地址
value
0xf1 停止时缓慢
0xf2 停止时急速
0xfa 重新启动
0xfb 急停
*/
unsigned char set_special(unsigned char cardno,unsigned char value)
{
unsigned char OutByte[25];
OutByte[0] = 0xFA ;
OutByte[1] = value;
enabled_cs(cardno);
SPI_SendData(OutByte[0]);
SPI_SendData(OutByte[1]);
disabled_cs(cardno);
}
void main(void)
{
initial();
set_speed(1 ,1,1000,1000,10,200,100); // 设1轴速度
set_speed(1 ,2,1000,1000,10,200,100); // 设2轴速度
/*1轴2轴回原点*/
pmove(1,1,-1000000,0); // 1轴多脉冲负方向运动
pmove(1,2,-1000000,0); // 2轴多脉冲负方向运动
while(s1); //检测1轴状态引脚电平,如变低表示已停,且在原点
while(s2); //检测2轴状态引脚电平,如变低表示已停,且在原点
//while(get_command_pos(1, 100)) ; //通过指令也能获取各轴状态 ,与S1,S2两个状态指示输入口功能相同。
set_command_pos(1,1,0); // 设1轴此时坐标为0
set_command_pos(1,2,0); // 设2轴此时坐标为0
while(1)
{
if((!b1)&&(!s1))//按键按下 ,并且1轴停止状态
{
pmove(1,1,32000,0); // 1轴正向运动 32000个脉冲
while(!b1);
}
if((!b1)&&(inbuf[0]>0))//按键按下, 并且1轴在运动中
{
sudden_stop(1,1); // 1轴停止
while(!b1);
}
}
}