4 / 286 / 2
Регистрация: 02.04.2009
Сообщений: 610
1

Управление с помощью потоков шаговыми двигателями через параллельный порт

30.06.2023, 20:13. Показов 457. Ответов 3

Author24 — интернет-сервис помощи студентам
Я создал 4 потока для каждого из 4-х шаговых двигателей отдельно, где будет крутиться бесконечный цикл с заданными Dir и Step и с задержками, зависящими от текущей скорости для каждого двигателя. Каждый вызов Out32 будет находиться в критической секции. В процедуре TLPTEngine.ApplyHardware для каждого двигателя будут задаваться RotDir[i], RotateStep[i] и скорость (задержка) TimeOut[i].
Приведенный ниже код должен начать вращение двигателей при запуске программы, но не делает этого. При вызове процедуры OutToLptThread[i].Execute в процедуре TLPTEngine.InitializeHardware выдается ошибка:
"Exception EAccessViolation in module MyProgram.exe at 001CE279. Access violation at address 005CE279 in module MyProgram.exe'. Read of address 00000000."
и выполнение программы прекращается.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
uses
    SysUtils, Math, TraceLog, MDriveEngines, SyncObjs;
 
const
    numOfEngines = 4;
 
type
    // Class of threads that control motors
    TOutToLptThread = class(TThread)
    private
    { Private declarations }
    protected
        procedure Execute; override;
    public
        LPTEngineNum: integer; // Number of engine and thread
    end;
 
    // Class of stepper motors
    TLPTEngine = class(TEngine)
    public
        procedure InitializeHardware; override;
        procedure FinalizeHardware; override;
        procedure ApplyHardware; override;
    end;
 
var
    RotateStep: array [1 .. numOfEngines] of Integer; // Stepper motor rotation pulse via LPT-port
    RotDir: array [1 .. numOfEngines] of Integer; // Direction of rotation of stepper motor via LPT-port
    Time_out: array [1 .. numOfEngines] of Integer; // Delays in the supply of pulses to the stepper motor through the LPT-port - for different motor speeds
 
    FSynchronizer: TCriticalSection;
    OutToLptThread: array[1..numOfEngines] of TOutToLptThread; // Array of threads that control numOfEngines engines
    OutToLPTData: Byte; // Common byte with all Dir and Step for tumOfEngines engines, issued to the LPT port
 
procedure TOutToLptThread.Execute;
 
    procedure Delay_mcs(time_out: double); // Delay in microseconds
    var
        iCounterPerSec: TLargeInteger;
        T1, T2: TLargeInteger; // Values of counter before and after operation
    begin
        QueryPerformanceFrequency(iCounterPerSec);
        // We defines a frequency of counter
        QueryPerformanceCounter(T1); // Recorded the start time of the operation
        T2 := T1;
 
        while (T2 - T1) * 1000000 / iCounterPerSec < time_out do
            QueryPerformanceCounter(T2); // Recorded the end time of the operation
    end;
 
var
    PortAdr: word;
begin
    PortAdr := $EEFC; // Address of LPT-port
 
    while true do
    begin
        OutToLPTData := RotDir[1] * 2 + RotDir[2] * 8 + RotDir[3] * 32 + RotDir[4] *
          128; // Data that output to LPT-port
        FSynchronizer.Enter; // = Acquire;
        try
            Out32(PortAdr, OutToLPTData);
        finally
            FSynchronizer.Leave; // = Release
        end;
        Delay_mcs(Time_out[LPTEngineNum]);
        OutToLPTData := RotateStep[1] + RotateStep[2] * 4 + RotateStep[3] * 16 +
          RotateStep[4] * 64 +
          RotDir[1] * 2 + RotDir[2] * 8 + RotDir[3] * 32 +
          RotDir[4] * 128; // Data that output to LPT-port
        FSynchronizer.Enter; // = Acquire;
        try
            Out32(PortAdr, OutToLPTData);
        finally
            FSynchronizer.Leave; // = Release
        end;
        Delay_mcs(Time_out[LPTEngineNum]);
    end;
end;
 
procedure TLPTEngine.InitializeHardware; // Called at the start of program execution
var
    i: integer;
begin
    IsSoftwareControlEngine := true;
 
    for i := 1 to numOfEngines do
    begin
        RotateStep[i] := 1; // Initial pulses of rotation of the stepper motor
        RotDir[i] := 0; // Initial direction of rotation of motors
        Time_out[i] := 500; // Delay in microseconds for each stepper motor
        OutToLptThread[i] := TOutToLptThread.Create(False);
        OutToLptThread[i].LPTEngineNum := i; // The thread number corresponds to the engine number, used in the assignment Time_out[LPTEngineNum]
        OutToLptThread[i].Priority := tpNormal;
//        OutToLptThread[i].Execute; // This command causes a message "Exception EAccessViolation in module MyProgram.exe at 001CE279. Access violation at address 005CE279 in module MyProgram.exe'. Read of address 00000000."
    end;
 
    inherited;
end;
 
procedure TLPTEngine.ApplyHardware; // Called when the value of Velocity changes.
var
    i: Integer;
begin
    i := AxisNum; // Number of engine
    if Velocity > 0 then // Direction of Rotation
    begin
        RotDir[i] := 0;
        RotateStep[i] := 1
    end
    else if Velocity < 0 then // Another direction of Rotation
    begin
        RotDir[i] := 1;
        RotateStep[i] := 1
    end
    else
    begin
        RotDir[i] := 0;
        RotateStep[i] := 0
    end;
end;
Вот описание платы CNC TB6560HQT 4V3, с помощью которой осуществляется управление: https://www.duxe.ru/load/red%20TB6560HQT%204V3.pdf
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.06.2023, 20:13
Ответы с готовыми решениями:

Управление шаговыми двигателями
Двигатель вращается на шаг при подаче на его кратковременного импульса на одну из обмоток. Как...

STM32 С++ c шаговыми двигателями кто работал?
STM32 С++ c шаговыми двигателями кто работал? Нужна помощь (разумеется оплачу) (есть...

Драйвер+контроллер шаговыми двигателями, управляемый по usb
Собственно по диплому нужно сделать такую штуку. Проблема в том, что программу для пк из статьи...

Управление ИБП через порт с помощью модуля serial
Здравствуйте! У меня есть бесперебойник я нашёл команды через которые можно с ним общаться,...

3
523 / 226 / 23
Регистрация: 05.05.2022
Сообщений: 1,483
30.06.2023, 20:35 2
Ну в несозданный объект или что-то подобное влетает. В какой строке-то?

Delphi
1
OutToLptThread[i] := TOutToLptThread.Create(False);
Понеслась!
И уже после начала движения потоку присваивается номер. Попробуйте создать поток остановленным, задать параметры, а потом Resume вызвать. Не факт, что это решит проблему, но жать точно надо после вспашки и посева.
1
411 / 140 / 27
Регистрация: 04.08.2018
Сообщений: 598
30.06.2023, 22:55 3
Цитата Сообщение от Rasool Посмотреть сообщение
При вызове процедуры OutToLptThread[i].Execute
А зачем вы её вызываете? Её не надо вызывать, она сама. Запускать поток надо OutToLptThread[i].Start
1
Модератор
3748 / 2248 / 782
Регистрация: 15.11.2015
Сообщений: 8,956
01.07.2023, 11:04 4
Цитата Сообщение от Rasool Посмотреть сообщение
Delphi
1
// OutToLptThread[i].Execute; // This command causes a message "Exception EAccessViolation in module MyProgram.exe at 001CE279. Access violation at address 005CE279 in module MyProgram.exe'. Read of address 00000000."
А смысл? Если здесь вызвать Execute, то он выполнится тут же, в основном потоке.
1
01.07.2023, 11:04
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.07.2023, 11:04
Помогаю со студенческими работами здесь

Обмен данными через параллельный порт
Нужен код программы, которая будет обмениваться данными с устройством, подключенное через...

Обмен данными через параллельный порт
Нужен код программы, которая будет обмениваться данными с устройством, подключенное через...

Вывести через параллельный порт сигнал задания скорости в виде экспоненты
Здравствуйте.необходимо написать программу на Assembler для микроконтроллера msp430. задание:...

управление двигателями постоянного тока
Чинил электроколяску, не ехал в другую сторону. Выяснил, что обмотки возбуждения не переключаются...

Управление через ИК порт
Уважаемые, интересуюсь таким вопросом. На современных девайсах имеется инфракрасный порт, вопрос...

управление через СОМ порт
Как сдельть сигнал на RTS,DTR по нажатию BUTTON1и2 соответственно. Причём при их отпускании сигналы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru