📄 demo01dlg.cpp
字号:
// Demo01Dlg.cpp : implementation file
//
#include "stdafx.h"
#include "Demo01.h"
#include "Demo01Dlg.h"
# include "dmc3000.h" //必须增加的库头文件
/********************************************
雷赛DMC3000控制卡编程示例之一
?-主要演示功能:
No.1 控制卡的基本操作
No.2 了解匀速/S形/T形运行速度曲线
No.3 停止控制方式(指令停止,外部输入信号停止)
No.4 多轴联动的实现
No.5 持续运动实现
No.6 对称/非对称的简单调配
No.7 了解逻辑方向对设备的物理位置与显示位置关系的影响
No.8 邦定该轴的状态显示及位置查询实现
!-关键函数:
控制卡
d3000_board_init
d3000_board_close
d3000_get_base_addr
d3000_get_irq_channel
速度-匀速
当T形驱动函数邦定的起始速度与运行速度相等时,为匀速,不相等为T形速度
S形函数函数实现匀速效果同T形原理一致
d3000_start_t_move
d3000_start_s_move
停止控制
d3000_decel_stop
外部信号输入可参见硬件折册
多轴联动
实质是同时启动多个单轴的表现,不管是在点动定位或持续运行的需求下
for( int i(0); i<anyAxis; i++)
d3000_start_t_move(i, ... )//点动定位
d3000_start_tv_move(i,... )//持续运行
持续运行
d3000_start_tv_move T形持续
d3000_start_rv_move S形持续
当使用持续驱动时,可使用外部输入信号停止
对称或非对称
当T形驱动函数邦定的加速时间或减速时间不一致时,为非对称速度曲线,相等则为
对称速度曲线
逻辑方向
此方向的变化,会导致显示的位置变化正常,但物理设备的运动方向发生反向,此种发明
即成本低,功效会很大
d3000_set_pls_outmode
指定轴的状态查询及位置显示
d3000_motion_done //输入信号读取
d3000_get_command_pos //指令位置获取
#-注意事项:
No.1 为了体验控制卡编程之乐趣,最好按手册连接好物理设备(驱动器,电机),这样学起来
会比较有成就感.
No.2 程序结束时,必须调用d3000_board_close释放占有的系统资源,初始化失败除外,此
事项,在所有DMC系列的控制卡编程当中都适用,且必须使用。
No.3 S形函数驱动需要注意,其加加速度值不能不比总加速时间大,道理不言自明。
Writen by LEISAI-SUPPORT
FAX: 0755 - 26402718
TEL: 0755 - 26434329
EMAIL: support@leisai.com
HTTP: www.leisai.com
********************************************/
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDemo01Dlg dialog
CDemo01Dlg::CDemo01Dlg(CWnd* pParent /*=NULL*/)
: CDialog(CDemo01Dlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CDemo01Dlg)
m_nSpeedST = 0;
m_nActionST = 0;
m_nAxis = 0;
m_bSymmetry = FALSE;
m_bLogic = TRUE;
m_nPulse = 6400;
m_nStart = 1600;
m_nSpeed = 3200;
m_fAccel = 0.1;
m_fDecel = 0.1;
m_fEff = 0.01;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CDemo01Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDemo01Dlg)
DDX_Radio(pDX, IDC_RADIO_SPEEDST, m_nSpeedST);
DDX_Radio(pDX, IDC_RADIO_ACTIONST, m_nActionST);
DDX_Radio(pDX, IDC_RADIO_AXIS, m_nAxis);
DDX_Check(pDX, IDC_CHECK_SYMMETRY, m_bSymmetry);
DDX_Check(pDX, IDC_CHECK_LOGIC, m_bLogic);
DDX_Text(pDX, IDC_EDIT_PULSE, m_nPulse);
DDX_Text(pDX, IDC_EDIT_START, m_nStart);
DDX_Text(pDX, IDC_EDIT_SPEED, m_nSpeed);
DDX_Text(pDX, IDC_EDIT_ACCEL, m_fAccel);
DDX_Text(pDX, IDC_EDIT_DECEL, m_fDecel);
DDX_Text(pDX, IDC_EDIT_SEFF, m_fEff);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDemo01Dlg, CDialog)
//{{AFX_MSG_MAP(CDemo01Dlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_CLOSE()
ON_WM_DESTROY()
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BUTTON_EMGSTOP, OnButtonEmgstop)
ON_BN_CLICKED(IDC_CHECK_LOGIC, OnCheckLogic)
ON_BN_CLICKED(IDC_CHECK_SYMMETRY, OnCheckSymmetry)
ON_BN_CLICKED(IDC_RADIO_TS, OnRadioTs)
ON_BN_CLICKED(IDC_RADIO_SS, OnRadioSs)
ON_BN_CLICKED(IDC_RADIO_SPEEDST, OnRadioSpeedst)
ON_BN_CLICKED(IDC_BUTTON_DECSTOP, OnButtonDecstop)
ON_BN_CLICKED(IDC_RADIO_ACTIONST, OnRadioActionst)
ON_BN_CLICKED(IDC_RADIO_CMOVE, OnRadioCmove)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDemo01Dlg message handlers
BOOL CDemo01Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
if( d3000_board_init() <= 0 ){//控制卡的初始化操作
MessageBox("初始化DMC3000卡失败!","出错");
// return TRUE;
}
CString string;
//以下显示地址及中断申请号
DWORD nAddress,nChannel;
nAddress = d3000_get_base_addr();
nChannel = d3000_get_irq_channel();
string.Format("0x%04x", nAddress );
GetDlgItem( IDC_EDIT_ADDR )->SetWindowText( string );
string.Format("0x%04x", nChannel );
GetDlgItem( IDC_EDIT_CHANNEL )->SetWindowText( string );
//////////////////////////////
UpdateControl();
SetTimer( IDC_TIMER, 100, NULL );
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CDemo01Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CDemo01Dlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CDemo01Dlg::OnClose()
{
CDialog::OnClose();
}
void CDemo01Dlg::OnDestroy()
{
d3000_board_close(); //非常之重要,释放其占用的系统资源
KillTimer( IDC_TIMER );
CDialog::OnDestroy();
}
void CDemo01Dlg::OnTimer(UINT nIDEvent)
{
CString string;
long position = d3000_get_command( m_nAxis );
string.Format("当前位置:%ld", position );
GetDlgItem( IDC_STATIC_POSITION )->SetWindowText( string );
DWORD status = d3000_check_done( m_nAxis );
string.Format("状态值:0x%04x", status );
GetDlgItem( IDC_STATIC_STATUS )->SetWindowText( string );
CDialog::OnTimer(nIDEvent);
}
void CDemo01Dlg::OnCancel()
{
CDialog::OnCancel();
}
void CDemo01Dlg::OnButtonEmgstop()
{
for( int i(0); i<4; i++){//全部急停
d3000_emg_stop( i );
}
}
void CDemo01Dlg::OnOK()
{
try{
if( !UpdateData(true) )
throw "";
}
catch( char * ){
return;
}
//////////////////////////
if( (d3000_check_done( m_nAxis )&0x02) == 0x02) //已经在运动中
return;
//设定脉冲模式及逻辑方向(此处脉冲模式固定为P+D方向:脉冲+方向)
d3000_set_pls_outmode( m_nAxis, m_bLogic?1:3);
if( m_nActionST == 0 ){//点动
//暂使用相对运动函数,若需要绝对,替换相对函数为绝对函数即可,其它可不变
m_nSpeedST == 2 ?//S形驱动
d3000_start_s_move( m_nAxis, m_nPulse, m_nStart, m_nSpeed, m_fAccel, m_fEff ):
d3000_start_t_move( m_nAxis, m_nPulse, m_nStart, m_nSpeed, m_fAccel, m_fDecel);
//T形加速,当起始速度与运动速度相等时,即为匀速
}
else{//持续驱动
int dir = (m_nPulse > 0 ) ? 1 : -1;//以点动长度,即得运动方向
m_nSpeedST == 2 ?//S形驱动
d3000_start_sv_move( m_nAxis, m_nStart, m_nSpeed*dir, m_fAccel, m_fEff ):
d3000_start_tv_move( m_nAxis, m_nStart, m_nSpeed*dir, m_fAccel);
}
// CDialog::OnOK();
}
void CDemo01Dlg::UpdateControl()
{
GetDlgItem( IDC_CHECK_LOGIC )->SetWindowText( m_bLogic?"逻辑方向:正":"逻辑方向:反");
GetDlgItem( IDC_CHECK_SYMMETRY )->EnableWindow( m_nSpeedST == 1 );//仅支持T形
GetDlgItem( IDC_CHECK_SYMMETRY )->SetWindowText( m_bSymmetry ?"非对称曲线":"对称曲线");
GetDlgItem( IDC_EDIT_SEFF )->EnableWindow( m_nSpeedST == 2 );
// GetDlgItem( IDC_EDIT_PULSE )->EnableWindow( m_nActionST == 0 );
}
void CDemo01Dlg::OnCheckLogic()
{//逻辑正反
UpdateData( TRUE );
UpdateControl();
}
void CDemo01Dlg::OnCheckSymmetry()
{//对称或对称
UpdateData( true );
m_fDecel = m_fAccel;//对称,则加速时间及减速时间相等
if( m_bSymmetry )
m_fDecel += m_fAccel;//非对称,自动设定减速时间为加速时间两倍
UpdateData( FALSE );
UpdateControl();
}
void CDemo01Dlg::OnRadioTs()
{//T形速度
UpdateData( true );
if( m_nSpeed == m_nStart ){//自动产生不同速度
m_nSpeed = m_nStart+m_nStart;
UpdateData( FALSE );
}
UpdateControl();
}
void CDemo01Dlg::OnRadioSs()
{//S形速度
UpdateData( true );
if( m_nSpeed == m_nStart ){//自动产生不同速度
m_nSpeed = m_nStart+m_nStart;
UpdateData( FALSE );
}
UpdateControl();
}
void CDemo01Dlg::OnRadioSpeedst()
{//匀速
UpdateData( true );
m_nSpeed = m_nStart;//速度相等
UpdateData( FALSE );
UpdateControl();
}
void CDemo01Dlg::OnButtonDecstop()
{//减速停
d3000_decel_stop( m_nAxis, m_fDecel );
}
void CDemo01Dlg::OnRadioActionst()
{
UpdateData( true );
UpdateControl();
}
void CDemo01Dlg::OnRadioCmove()
{
UpdateData( true );
UpdateControl();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -