首页 新闻 工控搜 论坛 厂商论坛 产品 方案 厂商 人才 文摘 下载 展览
中华工控网首页
  P L C | 变频器与传动 | 传感器 | 现场检测仪表 | 工控软件 | 人机界面 | 运动控制
  D C S | 工业以太网 | 现场总线 | 显示调节仪表 | 数据采集 | 数传测控 | 工业安全
  电 源 | 嵌入式系统 | PC based | 机柜箱体壳体 | 低压电器 | 机器视觉
四个编程问题,请稍加留意
深圳市雷赛智能控制股份有限公司
收藏本文     查看收藏
No.1 一个由VB编译引起的错误
VB编译环境下,常有这样种事情发生,第一次初始化控制卡时,往往正常通过,若中途中断或意外退出,则再次启动程序,则初始化时却找不到控制卡了,有时弄得人很郁闷,一点成熟感都没有,在没有别的招的情况下,搞得程序员一怒之下重启PC才得以好转。然事情却很让人不开心。
这个问题是由VB编译引起的,由于VB是一种解释语言,其程序运行时被加载的速度不够快,故会把程序调用的动态库等资源暂放置内存,直到VB整个软件结束才会释放。而在调试控制卡软件时,由于中途中断或调试意外退出,没有执行到控制卡关闭函数,则控制卡资源还未被释放,故程序再次运行初始化控制卡资源时,则找不到有效的资源了,因而也找不到控制卡了。
解决问题很简单,关闭整个VB编译器软件,以释放所有资源,再次进入即可。此过程稍为麻烦,但比上重启PC来讲,还是稍有效率一些。


No.2
取位运算
在使用控制卡编程时,常常碰到取位运算的案例,如下面函数:
d3000_get_axis_status
在其《软件手册》上有对其返回值的每一位进行了详细说明,即使这样,有些新手面对具体编程时,一时还转不过弯过来。如:要从返回值内判断原点信号的高低电平状态到底该怎样编程呢,以下列出在C/C++Basic取位运算的代码片段,其它状态位类同:
(注:DMC3000控制卡的原点信号在d3000_get_axis_status的返回值第9位,从0位开始数)

1
C/C++
DWORD nStatus = d3000_get_axis_status( XCH );//
读取X轴的专用输入信号
//XCH
的值为0

if( (nStatus&(1<<9)) != 0 )
//
高电平或低电平
else
//
低电平或高电平

(用移位方法在《控制卡编程几招》中有介绍)

2
Basic

Dim nStatus as long
nStatus = d3000_get_axis_status ( XCH ) ‘
读取X轴的专用输入信号

if (nStatus and &H200) <> 0 then
//
高电平或低电平
else
//
低电平或高电平
end if

注意:第9位为1时的十六进制数值为0x200



No.3
关于大数平方和平方根溢出的解决方法
平方和平方根的计算常常遇到,一般都会用浮点数来表示,当计算大数时,由于电脑内部定义的数据类型字节宽有限,总会有溢的可能,如:

double kx = 1000000.0; //
一个doubleVC++中为64位,在DOS环境下为32
double ky = 1000000.0;
double len = sqrt( kx * kx + ky * ky );//
求两者的平方和之根

想必上面的表达算式大家都见怪不怪了吧,但很容易溢出哦,要是多次系数,就更容易了,那么到底该如何解决这个问题呢?我们改一下表达算法,也可达到同样效果,可将溢出的机率大大降低,请看:

double kx = 1000000.0;
double ky = 1000000.0;

ky = (ky/kx); //
注意变化,实际应用时,要避免kx=0.0

double len = kx * sqrt( 1 + ky * ky );
//
想一想,若kx,ky的数值有效,那么len的值也不会溢出了

No.4
精确定时器的实现(仅用在VC++
MFC
提供的定时器OnTimer,虽然可以通过SetTimer设定响应时间间隔,但无论怎样都不能超过每少20次的调用频率,在一些需要精确计时的场合当然就不适合了。API提供一个性能较好的函数GetTickCount,这个函数理论上可以跑到毫秒级,但是它的时间积累误差很大,而且不可以得到更精确的计时。
在《Windows图形编程》一书当中有封装好的一个精确计时类,可以根据CPU的时钟周期来计时,够酷吧,然此书有很多人暂未购得,故由本人做一做义务,公布其主要的核心片段,也足够大家用了,具体大家再根据需要去完善吧。

typedef __int64 I64; //
一个64位整数类型的定义

I64 GetQueryCount()
{//
返回当前时钟周期,若不明白以下语法,就不明白,反正能用就行,在NT下也正常
_asm _emit 0x0F
_asm _emit 0x31
}


//
取得1秒中的周期计数值
I64 start = GetQueryCount ();
Sleep(1000);
I64 stop = GetQueryCount ();
//
转化成1微秒的计数值,可根据需要进行,我在一个软件当中使用1微秒就够了
//
单位关系:1=1000毫秒=1000000微秒
long double fUnit = (long double)(stop-start)*0.000001;//
取得1微秒的时种周期值

若你想要达到100微秒中断一次,则可以写出下面程序:

I64 nTimers = I64( fUnit * 100 );//
100再转化周期值
I64 nStart = GetQueryCount();
I64 nEnd = nStart;

While(
你的有效循环条件 )
{
nEnd = GetQueryCount();
if( labs(nEnd – nStart) >= nTimers )
{
做你想做的事情,记得你要作的事情不要太复杂,以致于运行的周期超过自己定义的中断间隔周期。

nEnd = nStart;
}
else
::DoEvents();//
此函数在我的相关文章有详解,故不赘述
 

状 态: 离线

公司简介
产品目录

公司名称: 深圳市雷赛智能控制股份有限公司
联 系 人: 梁邦敏
电  话: 755-26401178
传  真:
地  址: 深圳市南山区登良路天安南油工业区2栋3楼
邮  编: 518000
主  页:
 
该厂商相关技术文摘:
CNC解释库调用接口详述
DMC1000控制卡不能响应系统消息
DMC2000脉冲速度初始化故障
DMC2000运动控制卡常见软件问题的解决方案
DMC2200驱动程序特殊安装方法
DMC3000控制卡,与CNC之G代码的邦定关系
DMC3000控制卡的多任务编程
多类型运动控制卡编程方法探讨
多线程与控制卡编程
发现步进电机定位不准怎么办
过程控制编程之简要探讨
控制卡应用编程技巧几招(2)
更多文摘...
立即发送询问信息在线联系该技术文摘厂商:
用户名: 密码: 免费注册为中华工控网会员
请留下您的有效联系方式,以方便我们及时与您联络

关于我们 | 联系我们 | 广告服务 | 本站动态 | 友情链接 | 法律声明 | 不良信息举报
工控网客服热线:0755-86369299
版权所有 中华工控网 Copyright©2022 Gkong.com, All Rights Reserved