Pergunta

Eu escrevi um aplicativo simples em C # 2.0 usando a classe 2.0 serialport .Net Framework para se comunicar com uma placa controladora via COM1.

Um problema ocorreu recentemente foram os bytes retornado pelo método de leitura estão incorretas. Ele voltou a quantidade certa de bytes, apenas os valores estão incorretos. Um aplicativo semelhante escrito em Delphi ainda devolveu os valores corretos embora.

Portmon para registar a actividade sobre a porta serial de ambos os apps, comparou os dois troncos e lá onde algumas configurações (aparentemente) menores diferente e eu tentei a imitar o aplicativo Delphi, tanto quanto possível, mas sem sucesso.

Então, o que poderia afetar os valores de bytes retornados pelo método de leitura?

A maioria das configurações entre os dois aplicativos são idênticos.

Aqui está uma lista das linhas que diferiam no log de Portmon:

Delphi App:

IOCTL_SERIAL_SET_CHAR Serial0 SUCESSO EOF: dc ERR: 0 BRK: 0 EVT: 0 XON: 11 XOFF: 13
IOCTL_SERIAL_SET_HANDFLOW Serial0 SUCESSO Agite: 0 Substituir: 0 XonLimit: 256 XoffLimit: 256 IOCTL_SERIAL_SET_TIMEOUTS Serial0 SUCESSO RI: -1 RM: 100 RC: 1000 WM: 100 WC: Máscara 1000 IOCTL_SERIAL_SET_WAIT_MASK Serial0 SUCESSO: RXCHAR RXFLAG TXEMPTY CTS DSR RLSD BRK ERR ANEL RX80FULL

C # App:

IOCTL_SERIAL_SET_CHAR Serial0 SUCESSO EOF: 1a ERR: 0 BRK: 0 EVT: 1a XON: 11 XOFF: 13 IOCTL_SERIAL_SET_HANDFLOW Serial0 SUCESSO Agite: 0 Substituir: 0 XonLimit: 1024 XoffLimit: 1024 IOCTL_SERIAL_SET_TIMEOUTS Serial0 SUCESSO RI: -1 RM: -1 RC: 1000 WM: 0 WC: Máscara 1000 IOCTL_SERIAL_SET_WAIT_MASK Serial0 SUCESSO: RXCHAR RXFLAG CTS DSR RLSD BRK ERR ANEL

UPDATE:

Os bytes retornados corretas foram: 91, 1, 1, 3, 48, 48, 50, 69, 66, 51, 70, 55, 52, 93 (14 bytes). O último valor de ser um simples checksum.

Os valores incorrectos devolvidos foram:. 91, 241, 254, 252, 242, 146, 42, 201, 51, 70, 55, 52, 93 (13 bytes)

Como você pode ver o primeiro eo último cinco bytes retornado correspondem.

O evento ErrorReceived indica que ocorreu um erro de enquadramento, o que poderia explicar os valores incorretos. Mas a questão é por que SerialPort encontrar um erro de enquadramento quando o aplicativo Delphi, aparentemente, não faz?

Foi útil?

Solução

Bem, parece como se o problema foi resolvido (pelo menos por enquanto).

Aparentemente, um erro de enquadramento causado o retorno de valores incorretos. Eu escrevi um aplicativo VB6, usando o controle MSComm, que funcionou bem, e comparou os arquivos de log gerados pelo Portmon.

Eu peguei as seguintes diferenças

VB6 App:

IOCTL_SERIAL_SET_HANDFLOW Serial0 SUCESSO Agite: 1 Substituir: 0 XonLimit: 256 XoffLimit: 256

C # App:

IOCTL_SERIAL_SET_HANDFLOW Serial0 SUCESSO Agite: 0 Substituir: 0 XonLimit: 1024 XoffLimit: 1024

Brincando com as configurações que eu descobri que se eu set _serialPort.DtrEnable = true o C # App gera a seguinte entrada de log:

IOCTL_SERIAL_SET_HANDFLOW Serial0 SUCESSO Agite: 1 Substituir: 0 XonLimit: 1024 XoffLimit: 1024

Isso pareceu impedir que o erro de enquadramento eo aplicativo parece estar funcionando bem.

Outras dicas

Você verificou as definições para o número de bits de dados, bits de parada e paridade?

O bit de paridade é uma espécie de mecanismo de detecção de erros. Por exemplo: Se você enviar usando 7 bits de dados e um bit de paridade, o oitavo bit será usado para a detecção de erros de bit de inversão. Se o receptor espera 8 bits de dados e sem bits de paridade, o resultado será truncado.

Infelizmente você não mencionou exatamente que tipo de diferenças que você começa. É um caráter ocasional que é diferente ou se todos os seus dados de entrada truncado? Note que caracteres lidos através da função SerialPort.Read poderia ser alterado pelo sistema devido à configuração do SerialPort.Encoding propriedade . Esta definição afecta a interpretação do texto de entrada como era de texto em ASCII, Unicode, UTF-8 ou qualquer outro esquema de codificação do Windows usa para 'byte-prima (s)' à conversão 'texto legível'.

Se você está lendo em uma matriz de bytes (ex: SerialPort.Read). Você deve obter exatamente os bytes que você está vendo na Portmon

Se você estiver convertendo para caracteres (SerialPort.ReadLine ou SerialPort.ReadChar), em seguida, os dados serão codificados usando a codificação atual (propriedade SerialPort.Encoding), o que explica as diferenças que você está vendo.

Se você quiser ver personagens com os mesmos valores binários como os bytes sobre o fio, uma boa codificação para uso é Latin-1 como descrito em este post .

Exemplo:

SerialPort.Encoding = Encoding.GetEncoding("Latin1")
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top