⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xiajie.c

📁 应用于AVR单片机对驱动控制芯片LM629的控制程序
💻 C
字号:
//ICC-AVR application builder : 2007-8-17 10:44:22
// Target : M16
// Crystal: 11.059Mhz

#include <iom16v.h>
#include <macros.h>

#define delay250ns asm("nop");asm("nop")
#define delay500ns asm("nop");asm("nop");asm("nop");asm("nop")


//////////////////////////////////////////////
//LM629片选读写命令
#define do_cs PORTA&=~BIT(7)
#define un_cs PORTA|=BIT(7)
#define comand_ps PORTA&=~BIT(3)
#define data_ps PORTA|=BIT(3)
#define do_rd PORTA&=~BIT(1)
#define un_rd PORTA|=BIT(1)
#define do_wr PORTA&=~BIT(2)
#define un_wr PORTA|=BIT(2)

/////////////////////////////////////////////
//LM629控制字
#define RESET  0x00
#define RSTI   0X1D
#define DFH    0X02
#define PORT8  0X05
#define MSKI   0X1C
#define LFIL   0X1E
#define UDF    0X04
#define LTRJ   0X1F
#define LPES   0X1A
#define STT    0X01
#define RDSIGS 0X0C
#define RDIP   0X09
#define RDDP   0X08
#define RDRP   0X0A
#define RDDV   0X07
#define RDRV   0X0B
#define RDSUM  0X0D
#define SBPR   0X21
#define SBPA   0X20
#define SIP    0X03
#define LPEI   0X1B
/////////////////////////////////////////////
//MC33035控制命令
#define DRIVEREN    PORTA|=BIT(6)
#define DRIVERUN    PORTA&=~BIT(6)
#define BRAKE       PORTA|=BIT(5)
#define UNBRAKE     PORTA&=~BIT(5)





/////////////////////////////////////////////
unsigned char rc_status;
//unsigned char rc_data;
unsigned char PID[12]={0x00,0x0f,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x5c};//存PID参数,依次为控制字,KP,KI,KD和iL
//unsigned long int ACC,VEL,POS
//unsigned char Vel[4]={0x01,0x02,0x03,0x04},Pos[4]={0x05,0x06,0x07,0x08};

//unsigned int ACCH,ACCL,VELH,VELL,POSH,POSL
unsigned int TCCW[16]={0x18,0x28,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0x00};//梯形控制命令,依次为控制字,加速度,速度,位置的高字节低字节
unsigned char runflag = 0;
unsigned char tem[20];
unsigned char motcw;//电机控制命令
unsigned char recv_num=0;
unsigned char snd_num=0;
unsigned char i=0;
unsigned char j=0;
unsigned char cmdtype;
unsigned char num;








/////////////////////////////////////////////
void port_init(void)
{
 PORTA = 0x9E;
 DDRA  = 0xFE;
 PORTB = 0x00;
 DDRB  = 0x00;
 PORTC = 0x00; //m103 output only
 DDRC  = 0x00;
 PORTD = 0x00;
 DDRD  = 0x00;
}

//UART0 initialize
// desired baud rate: 38400
// actual: baud rate:38399 (0.0%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
 UCSRB = 0x00; //disable while setting baud rate
 UCSRA = 0x00;
 UCSRC = BIT(URSEL) | 0x06;
 UBRRL = 0x47; //set baud rate lo
 UBRRH = 0x00; //set baud rate hi
 UCSRB = 0x98;

}

void USARTsnd(unsigned char snd_data)
{
 while(!(UCSRA&(1<<UDRE)));
 UDR = snd_data;
 }

#pragma interrupt_handler uart0_rx_isr:12
void uart0_rx_isr(void)
{
// USARTsnd(0xf1);
 //uart has received a character in UDR
 if(recv_num==0)
 {
   cmdtype=UDR;
   
   recv_num++;
   i=0;
  
 }
 else
 {
  tem[i]=UDR;
  if(tem[i]==0xff)
  {if(tem[i-1]==0xee)
   {if(tem[i-2]==0xdd)
     judcmd();
	   }
   } 
  i++;
  }
 }
 
/* if(cmdtype ==0xaa && i== 11)
  judcmd();
 if(cmdtype == 0xff && i==15)
  judcmd();
 if(cmdtype == 0xfe && i==11)
  judcmd();
 if(cmdtype == 0xee && i==1)
 judcmd();
/* if(cmdtype == 0xfd && i==11 )
  judcmd();*/

   
   
   
void judcmd(void)
{
 
 
 switch(cmdtype)
 {
  case 0xaa://修改PID参数值,以AA作为起始位,依次输入控制字,KP,KI,KD,IL
 {
   recv_num=0;
   do
   {
    PID[recv_num]=tem[recv_num];
    recv_num++;
    }while(recv_num<10);
	
	 filter_load(PID);
	 recv_num=0;
    break;
   }
  case 0xFF://位置模式修改P,V,A
 {
  recv_num=0;
  do
  {
   TCCW[recv_num]=tem[recv_num];
   recv_num++;
   }while(recv_num<14);
    num=14;
    motrun();
    recv_num=0;
   break;
  }
 case 0xFE://速度模式修改A,V
 {
  recv_num=0;
  do
  {
   TCCW[recv_num]=tem[recv_num];
   recv_num++;
   }while(recv_num<10);
    num=10;
    motrun();
   //执行运动命令
   recv_num=0;
   break;
 }
 case 0xEE:
 {
   if(tem[0]=0xe1)
   {
    if(tem[1]=0xe2)
	{
	 stopmotor();
	}
	}
   //停止转动
   break;
   }
 case 0xFD:
  {
     i=0;
     chk_bsy();
     wr_cmd(LTRJ);
	 do
     {
	  if(i<2||i>5)
	  {
      chk_bsy();
      wr_data(tem[i]);
	  i++;
	  chk_bsy();
      wr_data(tem[i]);
      i++;
	  }
	  else
	  {
	   i++;
	   }
	 }while(i<10);
    i=0;
    chk_bsy();
    wr_cmd(STT);
   break;
   }
   
 default:
 {
    USARTsnd(0xdd);
	USARTsnd(0xee);
	USARTsnd(0xdd);
    break;
	}
}
recv_num=0;
}

//call this routine to initialize all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();
 uart0_init();
 init_629();

 MCUCR = 0x00;
 GICR  = 0x00;
 TIMSK = 0x00; //timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}
//
void delayNms(unsigned int b)//延时b毫秒
{
 unsigned int c;
 unsigned int a;
 for (c=0;c<b;c++)
 for (a=1;a<1152;a++);
}
//
void hardwarereset629(void)//复位LM629
{
 DDRA|=BIT(4);
 PORTA&=~BIT(4);
 delayNms(10);
 PORTA|=BIT(4);
 delayNms(10);
}
//





//检查状态字busy位
void chk_bsy(void)
{
 do{
  rd_st();
  }while(rc_status&0x01);
}

//
void rd_st(void)//读取状态寄存器值,一个字节
{
 DDRC=0x00;
 PORTC=0xff;//方向输入,内部上拉
 do_cs;
 comand_ps; //命令
 delay250ns;
 do_rd;
 delay250ns;
 rc_status=PINC;
 un_rd;
 comand_ps;
 un_cs;
 DDRC=0x00;
 PORTC=0x00;
 delay250ns;
}
//
unsigned char rd_data(void)//读取一个字节的数据
{
 unsigned char tempdata;
 DDRC=0x00;
 PORTC=0xff;//方向输入,内部上拉
 do_cs;
 data_ps; //数据
 do_rd;
 delay250ns;
 tempdata=PINC;
 un_rd;
 comand_ps;
 un_cs;
 DDRC=0x00;
 PORTC=0x00;
 delay250ns;
 return tempdata;
}
// 
void wr_cmd(unsigned char cmd)//写入一个字节的命令
{
 DDRC=0xff;
 PORTC=cmd;
 do_cs;
 comand_ps;
 delay250ns;
 do_wr;
 delay250ns;
 un_wr;
 comand_ps;
 un_cs;
 DDRC=0x00;
 PORTC=0x00;
 delay250ns;

}
//
void wr_data(unsigned char data)//写入一个字节的数据
{
 DDRC=0xff;
 PORTC=data;
 do_cs;
 data_ps;
 do_wr;
 delay250ns;
 un_wr;
 comand_ps;
 un_cs;
 DDRC=0x00;
 PORTC=0x00;
 delay250ns;
}
//

void filter_load(unsigned char p[10])//装入PID 参数
{
 chk_bsy();
 wr_cmd(LFIL);
 i=0;
 do
 {
  chk_bsy();
  wr_data(p[i]);
  i++;
  wr_data(p[i]);
  i++;
  }while(i<10);
  i=0;
  chk_bsy(); 
  wr_cmd(UDF);
}

void rd_realP(void)
{
 chk_bsy();
 wr_cmd(RDRP);
 i=0;
 do 
 {
  chk_bsy();
  USARTsnd(rd_data());
  i++;
 }while(i<4);
 i=0;
}
 
void rd_realV(void)
{
 chk_bsy();
 wr_cmd(RDRV);
 i=0;
 do 
 {
  chk_bsy();
  USARTsnd(rd_data());
  i++;
  }while(i<2);
 i=0;
} 
 



//
void init_629(void)//LM629初始化命令
{
 do
 {
 do
 {
 hardwarereset629();
 rd_st();
// USARTsnd(rc_status);
 }while(rc_status!=0xc4&&rc_status!=0x84);
 chk_bsy();
 wr_cmd(RSTI);
 chk_bsy();
 wr_data(0x00);
 wr_data(0x00);
 chk_bsy();
 rd_st();
// USARTsnd(rc_status);
 }while(rc_status!=0xc0&&rc_status!=0x80);
 //复位完成
 chk_bsy();
 wr_cmd(PORT8);
 chk_bsy();
 wr_cmd(SIP);
 chk_bsy();
 wr_cmd(DFH);
 chk_bsy();
 wr_cmd(MSKI);
 chk_bsy();
 wr_data(0x00);
 wr_data(0xff);//开运动完成中断

 
 filter_load(PID);

}


void motrun(void)
{
   if(runflag==1)
   {
    stopmotor();
   }
    startmotor();
}
  
void startmotor(void)
{
   DRIVEREN;
   UNBRAKE;
   i=0;
   chk_bsy();
   wr_cmd(DFH);
   chk_bsy();
   wr_cmd(LTRJ);
   do
   {
    chk_bsy();
    wr_data(TCCW[i]);
	i++;
	chk_bsy();
    wr_data(TCCW[i]);
    i++;
	}while(i<num);
   i=0;
   chk_bsy();
   wr_cmd(STT);
   
   runflag = 1;

}  

void stopmotor(void)
{
   chk_bsy();
   wr_cmd(LTRJ);
   chk_bsy();
   wr_data(0x01);
   wr_data(0x00);
   chk_bsy();
   wr_cmd(STT);
   delayNms(40);
   chk_bsy();
   wr_cmd(LTRJ);
   chk_bsy();
   wr_data(0x01);
   wr_data(0x00);
   chk_bsy();
   wr_cmd(STT);
   runflag=0;
   delayNms(40);
   BRAKE;
   DRIVERUN;
}
 







void main(void)
{
 init_devices();
 //insert your functional code here...
 while(1)
 {
 while(runflag==1)
 {
  USARTsnd(0xFF);
  rd_realP();
  rd_realV();
  USARTsnd(0xee);

  delayNms(350);
  }
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -