📄 lm629driver.txt
字号:
//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上升沿写入
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -