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

📄 lm629.txt

📁 伺服直流电机专用IC高精确度的PID位置控制,闭环控制
💻 TXT
字号:
给你一份程序:

from dingo北航
AVR mega128,A口为8位数据线。 
//lm629.h 
//lm629驱动程序 
/////////////////////////////////////////////////////////////OK 
unsigned char LM629_RDSTAT(void)//ReaD STATus Byte 
{ 
unsigned char rt; 
RD_STATUS(); 
DDRA=0X00; 
rt=PINA; //读取Status byte 
DDRA=0XFF; 
RD_HIGH(); 
return rt; 
} 
/////////////////////////////////////////////////////////////OK 
void LM629_BUSY(void) 
{ 
while(LM629_RDSTAT()&0X01); // if busy then loop 
} 
///////////////////////////////////////////////////////////// 
// LM629 共22条指令 所有指令定义为同名函数加前缀LM629_ 
// 1.初始化指令(3条)================================================== 

/////////////////////////////////////////////////////////////OK 
//循环直到复位成功 
void LM629_RESET_CHK(void) 
{ 
unsigned char chk_char1,chk_char2;//应该是0xC4 
BREAK_ON();//复位前先停止电机 
while(chk_char1!=0xC4 || chk_char2!=0xC0) 
{ 
LM629_RESET(); 
delay_ms(2); 
chk_char1=LM629_RDSTAT(); 
// UDR1=LM629_RDSTAT(); 
LM629_MSKI(0x0000); 
LM629_RSTI(0x0000); 
delay_ms(2); 
chk_char2=LM629_RDSTAT(); 
// UDR1=LM629_RDSTAT(); 
delay_ms(2); 
} 
LED1_ON(); 
BREAK_OFF();//重新打开电机 
flag_629_OK=TRUE; 
} 
/////////////////////////////////////////////////////////////OK 
void LM629_RESET(void)//RESET the LM629 
{ 

PORTD&=0x7F;//PD.7=0,Low reset 
delay_ms(2); 
PORTD|=0x80;//PD.7=0,Low reset 
delay_ms(2); 
// DELAY 1.5 ms 
} 
/////////////////////////////////////////////////////////////not tested 
void LM629_PORT8(void)//Set Output PORT Size to 8 Bits 
{ 
DDRA=0xFF; 
PORTA=0X05; 
WR_COMMAND(); 
WR_HIGH(); 
LM629_BUSY(); 
} 
/////////////////////////////////////////////////////////////not tested 
void LM629_DFH(void)//DeFine Home 
{ 
DDRA=0xFF; 
PORTA=0X02; 
WR_COMMAND(); 
WR_HIGH(); 
LM629_BUSY(); 
} 

// 2.中断指令 (6条)================================================== 

/////////////////////////////////////////////////////////////not tested 
void LM629_SIP(void)//Set Index Position 
{ 
DDRA=0xFF; 
PORTA=0X03; 
WR_COMMAND(); 
WR_HIGH(); 
LM629_BUSY(); 
} 
///////////////////////////////////////////////////////////// 
void LM629_LPEI(unsigned int PositionError)//Load Position Error for Interrupt 
{ 
DDRA=0xFF; 
PORTA=0X1B; 
WR_COMMAND(); 
WR_HIGH(); 
LM629_BUSY(); 
PORTA=(unsigned char)((PositionError&0xff00)>>; 
WR_DATA(); 
WR_HIGH(); 
PORTA=(unsigned char)(PositionError&0x00ff); 
WR_DATA(); 
WR_HIGH(); 
LM629_BUSY(); 
} 
///////////////////////////////////////////////////////////// 
void LM629_LPES(unsigned int PositionError)//Load Position Error for Stopping 
{ 
DDRA=0xFF; 
PORTA=0X1A; 
WR_COMMAND(); 
WR_HIGH(); 
LM629_BUSY(); 
PORTA=(unsigned char)((PositionError&0xff00)>>; 
WR_DATA(); 
WR_HIGH(); 
PORTA=(unsigned char)(PositionError&0x00ff); 
WR_DATA(); 
WR_HIGH(); 
LM629_BUSY(); 
} 
///////////////////////////////////////////////////////////// 
void LM629_SBPA(unsigned long BreakPoint) // 设置绝对位置断点 
{ 
LM629_BUSY(); 
PORTA=0X20; 
WR_COMMAND(); 
WR_HIGH(); 
LM629_BUSY(); 
PORTA=(unsigned char)((BreakPoint&0xff000000)>>24); 
WR_DATA(); 
WR_HIGH(); 
PORTA=(unsigned char)((BreakPoint&0x00ff0000)>>16); 
LM629_BUSY(); 
WR_DATA(); 
WR_HIGH(); 
PORTA=(unsigned char)((BreakPoint&0x0000ff00)>>; 
WR_DATA(); 
WR_HIGH(); 
PORTA=(unsigned char)(BreakPoint&0x000000ff); 
WR_DATA(); 
WR_HIGH(); 
} 
///////////////////////////////////////////////////////////// 
void LM629_SBPR(unsigned long BreakPoint)// 设置相对断点 
{ 
LM629_BUSY(); 
PORTA=0X21; 
WR_COMMAND(); 
WR_HIGH(); 
LM629_BUSY(); 
PORTA=(unsigned char)((BreakPoint&0xff000000)>>24); 
WR_DATA(); 
WR_HIGH(); 
PORTA=(unsigned char)((BreakPoint&0x00ff0000)>>16); 
LM629_BUSY(); 
WR_DATA(); 
WR_HIGH(); 
PORTA=(unsigned char)((BreakPoint&0x0000ff00)>>; 
WR_DATA(); 
WR_HIGH(); 
PORTA=(unsigned char)(BreakPoint&0x000000ff); 
WR_DATA(); 
WR_HIGH(); 
} 
/////////////////////////////////////////////////////////////OK 
void LM629_MSKI(unsigned int mask)//MaSK Interrupts 
{ 
DDRA=0xFF; 
PORTA=0X1c; 
WR_COMMAND(); 
WR_HIGH(); 
LM629_BUSY(); 
PORTA=(unsigned char)((mask&0xff00)>>; 
WR_DATA(); 
WR_HIGH(); 
PORTA=(unsigned char)(mask&0x00ff); 
WR_DATA(); 
WR_HIGH(); 
LM629_BUSY(); 
} 
///////////////////////////////////////////////////////////// OK 
void LM629_RSTI(unsigned int mask)//ReSeT Interrupts 
{ 
DDRA=0xFF; 
PORTA=0X1d; 
WR_COMMAND(); 
WR_HIGH(); 
LM629_BUSY(); 
PORTA=(unsigned char)((mask&0xff00)>>; 
WR_DATA(); 
WR_HIGH(); 
PORTA=(unsigned char)(mask&0x00ff); 
WR_DATA(); 
WR_HIGH(); 
LM629_BUSY(); 
} 
///////////////////////////////////////////////////////////// 
// 3. PID 控制器指令(2条)===================================================== 
///////////////////////////////////////////////////////////// 
//OK 
void LM629_LFIL(unsigned int command_word,unsigned int kp_data,unsigned int ki_data,unsigned int kd_data,unsigned int il_data)//Load FILter Parameters 
{ 
//写LFIL命令 
DDRA=0xFF; 
PORTA=0X1e; 
WR_COMMAND(); 
WR_HIGH(); 
LM629_BUSY(); 
//写控制字 
PORTA=(unsigned char)((command_word & 0xFF00)>>;//MSB 
WR_DATA(); 
WR_HIGH(); 
PORTA=(unsigned char)(command_word & 0x00FF);//LSB 
WR_DATA(); 
WR_HIGH(); 
LM629_BUSY(); 
//写kp 
PORTA=(unsigned char)((kp_data & 0xFF00)>>;//MSB 
WR_DATA(); 
WR_HIGH(); 
PORTA=(unsigned char)(kp_data & 0x00FF);//LSB 
WR_DATA(); 
WR_HIGH(); 
LM629_BUSY(); 
//写ki 
PORTA=(unsigned char)((ki_data & 0xFF00)>>;//MSB 
WR_DATA(); 
WR_HIGH(); 
PORTA=(unsigned char)(ki_data & 0x00FF);//LSB 
WR_DATA(); 
WR_HIGH(); 
LM629_BUSY(); 
//写kd 
PORTA=(unsigned char)((kd_data & 0xFF00)>>;//MSB 
WR_DATA(); 
WR_HIGH(); 
PORTA=(unsigned char)(kd_data & 0x00FF);//LSB 
WR_DATA(); 
WR_HIGH(); 
LM629_BUSY(); 
//写il 
PORTA=(unsigned char)((il_data & 0xFF00)>>;//MSB 
WR_DATA(); 
WR_HIGH(); 
PORTA=(unsigned char)(il_data & 0x00FF);//LSB 
WR_DATA(); 
WR_HIGH(); 
LM629_BUSY(); 

} 
/////////////////////////////////////////////////////////////OK 
void LM629_UDF(void)//UpDate Filter 
{ 
DDRA=0xFF; 
PORTA=0X04; 
WR_COMMAND(); 
WR_HIGH(); 
LM629_BUSY(); 
} 

// 4.运动指令 (2条)=========================================================== 
/////////////////////////////////////////////////////////////OK 
void LM629_LTRJ(unsigned int command_word,unsigned long acceleration_data,unsigned long velocity_data,signed long position_data) 
////Load TRaJectory Parameters 
{ 
//写LTRJ命令 
DDRA=0xFF; 
PORTA=0X1F; 
WR_COMMAND(); 
WR_HIGH();//WR上升沿写入 
LM629_BUSY(); 

//写控制字 
PORTA=(unsigned char)((command_word & 0xFF00)>>;//MSB 
WR_DATA(); 
WR_HIGH();//WR上升沿写入 
PORTA=(unsigned char)(command_word & 0x00FF);//LSB 
WR_DATA(); 
WR_HIGH();//WR上升沿写入 
LM629_BUSY(); 
if(command_word&0x0020)//指令读入加速度,并且目前电机已经停转 
{ //写加速度 
PORTA=(unsigned char)((acceleration_data & 0xFF000000)>>24);//1 MSB 
WR_DATA(); 
WR_HIGH();//WR上升沿写入 
PORTA=(unsigned char)((acceleration_data & 0x00FF0000)>>16);//2 
WR_DATA(); 
WR_HIGH();//WR上升沿写入 
LM629_BUSY(); 

PORTA=(unsigned char)((acceleration_data & 0x0000FF00)>>;//3 
WR_DATA(); 
WR_HIGH();//WR上升沿写入 
PORTA=(unsigned char)(acceleration_data & 0x000000FF);//4 LSB 
WR_DATA(); 
WR_HIGH();//WR上升沿写入 
} 
if(command_word&0x0008) 
{//写速度 
PORTA=(unsigned char)((velocity_data & 0xFF000000)>>24);//1 MSB 
WR_DATA(); 
WR_HIGH();//WR上升沿写入 
PORTA=(unsigned char)((velocity_data & 0x00FF0000)>>16);//2 
WR_DATA(); 
WR_HIGH();//WR上升沿写入 
LM629_BUSY(); 

PORTA=(unsigned char)((velocity_data & 0x0000FF00)>>;//3 
WR_DATA(); 
WR_HIGH();//WR上升沿写入 
PORTA=(unsigned char)(velocity_data & 0x000000FF);//4 LSB 
WR_DATA(); 
WR_HIGH();//WR上升沿写入 
LM629_BUSY(); 
} 
if(command_word&0x0002) 
{//写位置 
PORTA=(unsigned char)((position_data & 0xFF000000)>>24);//1 MSB 
WR_DATA(); 
WR_HIGH();//WR上升沿写入 
PORTA=(unsigned char)((position_data & 0x00FF0000)>>16);//2 
WR_DATA(); 
WR_HIGH();//WR上升沿写入 
LM629_BUSY(); 

PORTA=(unsigned char)((position_data & 0x0000FF00)>>;//3 
WR_DATA(); 
WR_HIGH();//WR上升沿写入 
PORTA=(unsigned char)(position_data & 0x000000FF);//4 LSB 
WR_DATA(); 
WR_HIGH();//WR上升沿写入 
LM629_BUSY(); 
} 
} 
/////////////////////////////////////////////////////////////OK 
void LM629_STT(void)//STarT Motion Control 
{ 
DDRA=0xFF; 
PORTA=0X01; 
WR_COMMAND(); 
WR_HIGH();//写入 
LM629_BUSY(); 
} 
///////////////////////////////////////////////////////////// 
// 5.状态和信息指令(8条)======================================================= 
/////////////////////////////////////////////////////////////OK 
unsigned int LM629_RDSIGS(void)//ReaD SIGnalS Register 
{ 
unsigned int rt=0x0000; 
LM629_BUSY(); 
DDRA=0XFF; 
PORTA=0X0c; 
WR_COMMAND(); 
WR_HIGH();//写入指令 
LM629_BUSY(); 

DDRA=0X00; 
RD_DATA(); 
rt+=(((unsigned int)PINA)<<; 
RD_HIGH(); 

RD_DATA(); 
rt+=((unsigned int)PINA); 
RD_HIGH(); 
LM629_BUSY(); 

// DDRA=0XFF; 
return rt; 
} 
///////////////////////////////////////////////////////////// 
unsigned long LM629_RDIP(void)//ReaD Index Position 
{ 
unsigned long rt=0x00000000; 
DDRA=0XFF; 
PORTA=0X09; 
WR_COMMAND(); 
WR_HIGH();//写入指令 
LM629_BUSY(); 

DDRA=0X00; 
RD_DATA(); 
rt=(((unsigned long)PINA)<<24); 
RD_HIGH(); 

RD_DATA(); 
rt+=(((unsigned long)PINA)<<16); 
RD_HIGH(); 
LM629_BUSY(); 

DDRA=0X00; 
RD_DATA(); 
rt+=(((unsigned long)PINA)<<; 
RD_HIGH(); 

RD_DATA(); 
rt+=((unsigned long)PINA); 
RD_HIGH(); 
LM629_BUSY(); 

DDRA=0XFF; 
return rt; 
} 
///////////////////////////////////////////////////////////// 
unsigned long LM629_RDDP(void)//ReaD Desired Position 
{ 
unsigned long rt=0x00000000; 
DDRA=0XFF; 
PORTA=0X08; 
WR_COMMAND(); 
WR_HIGH();//写入指令 
LM629_BUSY(); 

DDRA=0X00; 
RD_DATA(); 
rt=(((unsigned long)PINA)<<24); 
RD_HIGH(); 

RD_DATA(); 
rt+=(((unsigned long)PINA)<<16); 
RD_HIGH(); 
LM629_BUSY(); 

DDRA=0X00; 
RD_DATA(); 
rt+=(((unsigned long)PINA)<<; 
RD_HIGH(); 

RD_DATA(); 
rt+=((unsigned long)PINA); 
RD_HIGH(); 
LM629_BUSY(); 

DDRA=0XFF; 
return rt; 
} 
///////////////////////////////////////////////////////////// 
unsigned long LM629_RDRP(void)//ReaD Real Position 
{ 
unsigned long rt=0x00000000; 
LM629_BUSY(); 
DDRA=0XFF; 
PORTA=0X0A; 
WR_COMMAND(); 
WR_HIGH();//写入指令 

LM629_BUSY(); 
DDRA=0X00; 

RD_DATA(); 
rt=(((unsigned long)PINA)<<24); 
RD_HIGH(); 

RD_DATA(); 
rt+=(((unsigned long)PINA)<<16); 
RD_HIGH(); 

LM629_BUSY(); 
DDRA=0X00; 

RD_DATA(); 
rt+=(((unsigned long)PINA)<<; 
RD_HIGH(); 

RD_DATA(); 
rt+=((unsigned long)PINA); 
RD_HIGH(); 

DDRA=0XFF; 
return rt; 
} 
///////////////////////////////////////////////////////////// 
unsigned long LM629_RDDV(void)//ReaD Desired Velocity 
{ 
unsigned long rt=0x00000000; 
DDRA=0xFF; 
PORTA=0X07; 
WR_COMMAND(); 
WR_HIGH(); 

LM629_BUSY(); 
DDRA=0X00; 

RD_DATA(); 
rt|=(unsigned long)PINA<<24; 
RD_HIGH(); 

RD_DATA(); 
rt|=(unsigned long)PINA<<16; 
RD_HIGH(); 

LM629_BUSY(); 
DDRA=0X00; 

RD_DATA(); 
rt|=(unsigned long)PINA<<8; 
RD_HIGH(); 

RD_DATA(); 
rt|=(unsigned long)PINA; 
RD_HIGH(); 

LM629_BUSY(); 
return rt; 

} 
///////////////////////////////////////////////////////////// 
unsigned long LM629_RDRV(void)//ReaD Real Velocity 
{ 
unsigned long rt=0x00000000; 
DDRA=0xFF; 
PORTA=0X0B; 
WR_COMMAND(); 
WR_HIGH(); 

LM629_BUSY(); 
DDRA=0X00; 

RD_DATA(); 
rt|=(unsigned long)PINA<<24; 
RD_HIGH(); 

RD_DATA(); 
rt|=(unsigned long)PINA<<16; 
RD_HIGH(); 

LM629_BUSY(); 
DDRA=0X00; 

RD_DATA(); 
rt|=(unsigned long)PINA<<8; 
RD_HIGH(); 

RD_DATA(); 
rt|=(unsigned long)PINA; 
RD_HIGH(); 

LM629_BUSY(); 
return rt; 

} 
///////////////////////////////////////////////////////////// 
unsigned int LM629_RDSUM(void)//ReaD Integration-Term SUMmation value 
{ 
unsigned int rt=0x0000; 
LM629_BUSY(); 
DDRA=0XFF; 
PORTA=0X0D; 
WR_COMMAND(); 
WR_HIGH();//写入指令 
LM629_BUSY(); 

DDRA=0X00; 
RD_DATA(); 
rt+=(((unsigned int)PINA)<<; 
RD_HIGH(); 

RD_DATA(); 
rt+=((unsigned int)PINA); 
RD_HIGH(); 
LM629_BUSY(); 

// DDRA=0XFF; 
return rt; 

} 

////////////////////////////////////////////////////////////////////// 
////////////////////////////////////////////////////////////////////// 
void Motion_value_CLS(void) 
{ 
; 
} 
/////////////////////////////////////////////////////////////END

⌨️ 快捷键说明

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