|
{*******************************************************}
{ }
{ PWM 舵机控制 }
{ }
{ 版权所有 (C) 2009 笑熬浆糊 }
{ }
{*******************************************************}
unit uSteeringCtrl;
interface
uses
Windows, Messages, SysUtils, Variants, Classes,mmsystem;
function ReadPort(Port:WORD):BYTE;
procedure WritePort(Port:WORD;ConByte:BYTE);
procedure SetSignal(_pos:Integer;const Signal:BOOL=False);
procedure ChannelCtrl(index:Integer);
function InitializeWinIo:Boolean;stdcall;external 'WinIo.dll' name'InitializeWinIo';
function InstallWinIoDriver(pszWinIoDriverPathString;IsDemandLoaded:boolean=false):Boolean;stdcall;external 'WinIo.dll' name 'InstallWinIoDriver';
function RemoveWinIoDriver:Boolean;stdcall;external 'WinIo.dll' name 'RemoveWinIoDriver';
function GetPortVal(PortAddr:WordortValDWord;bSize:Byte):Boolean;stdcall;external 'WinIo.dll' name 'GetPortVal';
function SetPortVal(PortAddr:WordortValWord;bSize:Byte):Boolean;stdcall;external 'WinIo.dll' name 'SetPortVal';
function GetPhysLong(PhysAddrBytehysValDWord):Boolean;stdcall;external 'WinIo.dll' name 'GetPhysLong';
function SetPhysLong(PhysAddrBytehysValWord):Boolean;stdcall;external 'WinIo.dll' name 'SetPhysLong';
function MapPhysToLin(PhysAddrBytehysSizeWordhysMemHandleHandle)Byte;stdcall;external 'WinIo.dll' name 'MapPhysToLin';
function UnMapPhysicalMemory(PhysMemHandle:THandle;LinAddrByte):Boolean;stdcall;external 'WinIo.dll' name 'UnmapPhysicalMemory';
procedure ShutdownWinIo;stdcall;external 'WinIo.dll' name'ShutdownWinIo';
type
TSteeCtrl = class(TThread)
private
m_LastHighTime: Double ;
protected
procedure Execute; override;
public
m_HighTime ouble;
constructor Create;
end;
implementation
constructor TSteeCtrl.Create;
begin
m_HighTime:=2;
inherited Create(False);
end;
procedure TSteeCtrl.Execute;
var
r1,L_Base,L_ALLouble;
c1:int64;
t1,t2:int64;
begin
{ Place thread code here }
QueryPerformanceFrequency(c1);//WINDOWS API 返回计数频率(Intel86:1193180)(获得系统的高性能频率计数器在一毫秒内的震动次数)
L_Base:=0;
while not Terminated do
begin
QueryPerformanceCounter(t1);//WINDOWS API 获取开始计数值
if (L_Base > 20*1000) then
begin
L_Base:=0;
end;
if m_LastHighTime = m_HighTime then
begin
if L_ALL> 500*1000 then //每次动作由 500MS 时间完成,防止抖舵
begin
Sleep(1);
Continue;
end;
end
else
begin
L_ALL:=0;
m_LastHighTime := m_HighTime
end;
if L_Base < m_HighTime then //高电平时间
begin
SetSignal(1,True);
end
else
begin
SetSignal(1,False); //低电平
sleep(1);
end;
QueryPerformanceCounter(t2);//获取结束计数值
r1:=(t2-t1) / c1*1000000;//取得计时时间,单位微秒
L_Base:=L_Base+r1;
L_ALL:=L_ALL+r1;
end;
end;
function ReadPort(Port:WORD):BYTE;
var
B:BYTE;
begin
ASM
MOV DX, Port;
IN AL, DX;
MOV B, AL;
END;
Result:=B;
end;
procedure WritePort(Port:WORD;ConByte:BYTE);
begin
ASM
MOV DX, Port;
MOV AL, ConByte;
OUT DX, AL;
END;
end;
procedure SetSignal(_pos:Integer;const Signal:BOOL=False);
var
b:Byte;
begin
b:=0;
if Signal then
begin
case _pos of //每位表示一个通道
1:
b:=b or $01;
2:
b:=b or $02;
3:
b:=b or $04;
4:
b:=b or $08;
5:
b:=b or $10;
6:
b:=b or $20;
7:
b:=b or $40;
8:
b:=b or $80;
end;
end;
WritePort($378,b); //写数据端口
end;
procedure ys(n:integer);//延时子程序头部说明
var
i,j:integer;
begin
j:=1;
while j<N do
begin
i:=1;
while i<100 do i:=i+1;
j:=j+1;
end;
end;
procedure ChannelCtrl(index:Integer);
var
x,n:Integer;
begin
for x:=1 to 80 do {某一舵机位置初始化定位}
n:=0;
begin
//WritePort($378,b):=32; {并行口数据线的第6位置“1”,}
SetSignal(index,True);
ys(300); {调用延时子程序,参数300,观察舵机转动的位置}
//port[$378]:=0;
SetSignal(index,False);
Sleep(20);
end;
for x:=300 to 500 do
begin
// port[$378]:=32;
SetSignal(index,True);
ys(x); {参数x从300随着循环变量而增加到500,观察舵机转动的位置和方式}
//port[$378]:=0;
SetSignal(index,False);
Sleep(20);
//delay(20);
end;
end;
initialization
end.
{*******************************************************}
{ }
{ PWM 舵机控制 }
{ }
{ 版权所有 (C) 2009 笑熬浆糊 }
{ }
{*******************************************************}
program SteeringCtrl;
uses
Forms,
clMain in 'clMain.pas' {Form1},
uSteeringCtrl in 'uSteeringCtrl.pas';
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
[ 本帖最后由 zhude111 于 2009-4-14 11:04 编辑 ] |
|