A tecnologia de aquisição de dados desempenha um papel importante no controle e automação industrial e em outros campos. O processo geral de coleta de dados é o seguinte:
①Envie o comando de seleção de canal para a placa de captura. ②Selecione o número do canal a ser coletado. ③Inicie a conversão A/D. ④Aguarde até que a conversão seja concluída. ⑤Leia os dados do cartão de aquisição. Para aquisição multicanal, dois métodos são geralmente usados no projeto do programa. Método de consulta ou método de interrupção. O chamado método de consulta consiste em usar um loop para coletar cada canal de dados em sequência. A vantagem do método de consulta é que o programa é simples e fácil de implementar, a desvantagem é que durante o processo de coleta a CPU passa a maior parte do tempo esperando, resultando em desperdício de recursos; O método de interrupção adota a forma de interrupção de hardware - primeiro inicia a conversão A/D e envia um sinal de interrupção no final da conversão - a CPU lê os dados coletados ao responder à interrupção do cartão de aquisição. Desta forma, enquanto aguarda a conversão, a CPU pode realizar outros cálculos sem ficar em estado de espera. A vantagem do método de interrupção é que os recursos podem ser totalmente utilizados; porém, o design do programa é complexo, principalmente quando os recursos de interrupção de hardware do sistema são escassos, além disso, é fácil causar conflitos de interrupção, em sistemas operacionais como Windows ou; Win95, os usuários não têm permissão para instalar manipuladores de interrupção de tempo, isso não pode ser alcançado.
---- Os dois métodos discutidos acima são ambos métodos no DOS no Win95, agora existe um método melhor - tecnologia multi-threading; Agora, podemos aproveitar as vantagens da tecnologia multithreading para coleta de dados.
---- 1. Vantagens de usar multi-threading para coleta de dados
---- O que há de mais popular no Win95/98, além da bela interface, é o multithreading e a multitarefa. No ambiente DOS, o programa em execução pode monopolizar todos os recursos; no ambiente Windows, embora seja um ambiente multitarefa um pouco rudimentar, seu programa ainda pode controlar todo o tempo da CPU pelo tempo que desejar. Entretanto, no Windows95 e no Windows NT, um programa não pode monopolizar todo o tempo de execução da CPU. Além disso, um programa não é uma linha do começo ao fim. Pelo contrário, um programa pode ser dividido em vários fragmentos de programa durante a execução e executado simultaneamente. Esses fragmentos de programa que podem ser executados simultaneamente são chamados de threads. No Windows 95 e no Windows NT, o sistema operacional pode se revezar na execução de vários programas ao mesmo tempo, o que é multitarefa.
---- O uso de multithreading para coleta de dados pode efetivamente acelerar a velocidade de resposta do programa e aumentar a eficiência da execução. Os programas gerais devem processar a entrada do usuário, mas comparada à velocidade de execução da CPU, a velocidade de entrada do usuário é como caminhar ou voar. Dessa forma, a CPU perderá muito tempo aguardando a entrada do usuário (como em um ambiente DOS). Se multithreading for usado, um thread pode ser usado para aguardar a entrada do usuário, o outro thread pode realizar processamento de dados ou outro trabalho; Para programas de coleta de dados, um thread separado pode ser usado para coleta de dados. Dessa forma, a natureza da coleta em tempo real pode ser garantida ao máximo, enquanto outros threads podem responder às operações do usuário ou realizar o processamento de dados em tempo hábil. Caso contrário, o programa não poderá responder às operações do usuário ao coletar dados; ele não poderá coletar dados ao responder às operações do usuário. Especialmente quando a quantidade de dados coletados é grande e a tarefa de processamento de dados é pesada, a longa espera durante a coleta é muito aceitável se o multithreading não for usado.
---- No entanto, o multithreading é muito mais complexo do que a programação comum. Como vários threads podem estar em execução ao mesmo tempo a qualquer momento, muitas variáveis e dados podem ser modificados por outros threads. Este é o problema mais crítico de controle de sincronização entre threads em programas multithread.
---- 2. Problemas que devem ser resolvidos por multi-threading para coleta de dados
---- Na verdade, a complexidade da programação multithread é temporária. Se você usar C tradicional para design multithread, você mesmo deverá controlar a sincronização entre os threads. Isso seria complicado. No entanto, se você usar métodos de design orientados a objetos e Delphi para programação multithread, o problema será muito mais simples. Isso ocorre porque o Delphi lidou com a complexidade do multithreading para nós e tudo o que precisamos fazer é herdar.
---- Especificamente, a coleta de dados multithread precisa concluir o seguinte trabalho:
---- ① Derive sua própria classe SampleThread da classe TThread. Esta é a classe que usamos para coleta de dados. Ao coletar, basta criar uma instância de SampleThread.
---- ② Sobrecarregue o método Execute da superclasse TThread. Neste método, a tarefa de coleta de dados será executada especificamente.
---- ③ Se você deseja coletar e exibir ao mesmo tempo, escreva vários processos para exibir o progresso da coleta para o método Execute chamar.
----Os atributos/métodos mais comumente usados na classe TThread são os seguintes:
Método de criação: construtor Criar
(CreateSuspended: Booleano);
----O parâmetro CreateSuspended determina se o thread será executado imediatamente quando for criado. Se for True, o novo thread será suspenso após a criação; se for False, o thread será executado imediatamente após a criação.
Propriedade FreeOnTerminate:
Propriedade FreeOnTerminate: Booleano;
---- Este atributo determina se o programador é responsável por cancelar este thread. Se esta propriedade for True, a VCL destruirá automaticamente o objeto thread quando o thread terminar. Seu valor padrão é Falso.
Propriedades OnTerminate:
propriedade OnTerminate: TNotifyEvent;
---- Este atributo especifica um evento que ocorre quando o thread termina.
---- Vejamos um exemplo específico:
---- 3. Implementação de coleta de dados multithread
---- Este é um programa desenvolvido pelo autor para medir o diagrama de desempenho de uma unidade de bombeamento. Sua função é coletar os dados de carga e deslocamento do ponto de suspensão da unidade de bombeamento e, em seguida, fazer um diagrama de trabalho da unidade de bombeamento após o processamento. A Figura 1 (omitida) mostra a interface durante a coleta de dados. Após clicar no botão “Coletar Dados”, o programa criará um novo thread e definirá suas propriedades. Este novo thread concluirá a tarefa de coleta de dados. O procedimento é o seguinte:
ProcedimentoTsampleForm.
DoSampleBtnClick(Remetente: TObject);
Começar
ReDrawBtn.Enabled := Verdadeiro;
DoSampleBtn.Enabled := Falso;
FFTBtn.Enabled := Verdadeiro;
TheSampler := SampleThread.Create(False);
Criar tópico de coleção
TheSampler.OnTerminate := FFTBtnClick;
Tarefas a serem executadas após a conclusão da coleta
TheSampler.FreeOnTerminate := Verdadeiro;
Desfazer após a conclusão da coleta
Fim;
----A definição de classe do thread de coleção é a seguinte:
Tipo
SampleThread = classe(TThread)
Público
função AdRead(ach: byte): número inteiro;
Função para ler cartão A/D
procedimento UpdateCaption;
Exibir o horário de coleta
privado
{Declarações privadas}
protegido
estes, thep: real;
dt: real;
id: inteiro;
st, ed: LongInt;
substituição de procedimento;
Esta é a chave.
Fim;
---- Nesta classe, uma função AdRead é definida para operar o cartão A/D, e os dois processos são usados para exibir o progresso e o tempo de coleta. Deve-se observar que a função AdRead é escrita em assembly e o formato de chamada do parâmetro deve ser safecall.
---- O código do método sobrecarregado de chave Execute é o seguinte:
Procedimento SampleThread.Execute;
Começar
StartTicker := GetTickCount;
identificação:= 0;
Repita
estes := Adread(15) * ad2mv * mv2l;
Adquirir canal 15
thep := Adread(3) * ad2mv * mv2n;
Adquirir canal 3
dt := GetTickCount - StartTicker;
sarray[id] := estes;
parray[id] := thep;
tarray[id] := dt;
inc(id);
Sincronizar(UpdateCaption);
Nota: Exibir o progresso da coleta
Até id >=4096;
ed := GetTickCount;
Sincronizar(ShowCostTime);
Nota: Mostre o tempo gasto
fim;
---- Como pode ser visto no código acima, não há diferença essencial entre Executar e código comum. A única diferença é que ao exibir o andamento da coleta e exibir o tempo decorrido, os respectivos procedimentos não podem ser chamados diretamente, mas indiretamente através da chamada de Synchronize. Isso é feito para manter a sincronização entre os processos.
---- 4. Conclusão
----O programa acima é programado usando Delphi 4.0 e implementado em AMD-K6-2/300. Os resultados do teste são os seguintes: usando multithreading, geralmente leva de 10 a 14 segundos para coletar 4.096 pontos; se o multithreading não for usado, leva de 1 minuto a 1 minuto e meio; Pode-se observar que o multithreading pode melhorar significativamente a eficiência de execução do programa.