社区导航

 
快捷导航
  • 首页
  • 论坛
  • 查看新帖
  • 最新回复
  • 社区活动
  • 联系管理员
  • 消灭零回复
  • E金币兑换
  • 干货
搜索
查看: 99|回复: 0

[经验] 简单的单片机和多轴SPI通讯TSSOP20封装运动控制芯片mpc02t的通讯程序

[复制链接]

16

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 5 天前 | 显示全部楼层 |阅读模式
#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];      
voidinitial()
{
SPI_CSHIGH;
SPI2_CSHIGH;                  
}
voiddelay_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 charoutdata)
{
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 intstartv ,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 charcardno ,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 charcardno ,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 charcardno,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);
       }
     }
   
}

此帖出自单片机论坛


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

小黑屋|手机版|Archiver|电子工程世界 ( 京ICP证 060456

GMT+8, 2017-12-12 12:42 , Processed in 0.158070 second(s), 15 queries , Redis On.

快速回复 返回顶部 返回列表