我制作了一个应用程序,它使用 USB HID 自定义从 PIC 读取 ADC 值,第一个测试是使用按钮读取值并将读取的值传递到进度条和文本框,效果很好:
private void btnRead_Click(object sender, EventArgs e)
{
txbCmd.Text = board.ADCVal().ToString();
progressBar1.Value = Convert.ToInt32(txbCmd.Text);
}
如果我开始尽可能快地单击按钮,我将从 ADC 获得多个读取值,例如连续读取。
然后我尝试每 1.5 秒设置一个带有事件的计时器来读取 ADC(这比我连续多次按下按钮要慢):
private void timer1_Tick(object sender, EventArgs e)
{
txbCmd.Text = board.ADCVal().ToString();
progressBar1.Value = Convert.ToInt32(txbCmd.Text);
}
当我启动计时器时,第一次读取没有问题,但下一次读取给出错误 5,即访问被拒绝,如果我让程序运行一次读取并且下一个给定错误,则下一次读取,然后再次下一次读取给我错误...我不知道为什么它从单击按钮事件而不是从使用相同代码的计时器事件中起作用。
编辑
ADCVal 方法调用了同一个类中名为 WriteUSB 的另一个私有方法,将读取 ADC 命令发送到 PIC 板,然后使用私有方法 ReadUSB 从板上读取命令接收确认,最后等待读取 ADC 值从 PIC 板上,错误来自 WriteUSB 调用:
public UInt16 ADCVal()
{
byte[] SndData = new byte[65];
byte[] RcvData = new byte[65];
SndData[0] = 0; //EP0 USB
SndData[1] = _ADC_Val; //Cmd
if (WriteUSB(ref SndData) == false)
{
MessageBox.Show("Write USB Error: " + Marshal.GetLastWin32Error().ToString());
return 0;
}
if (ReadUSB(ref RcvData, false) == true)
{
if ((RcvData[1] == SndData[1]) && (RcvData[2] == 255))
{
if (ReadUSB(ref RcvData, false) == true)
{
return BitConverter.ToUInt16(RcvData, 2);
}
else
{
MessageBox.Show("Read USB Error: " + Marshal.GetLastWin32Error().ToString());
return 0;
}
}
else
{
MessageBox.Show("Read USB Error: " + Marshal.GetLastWin32Error().ToString());
return 0;
}
}
return 0;
}
私有方法 WriteUSB 有 WriteFile 调用(ReadUSB 有 ReadFile 调用代码):
public bool WriteUSB(ref byte[] OutBuffer)
{
int Bsize = OutBuffer.Length;
string error;
Int32 NumbersOfBytesWritten = 0;
IntPtr UnManagedBuffer = Marshal.AllocHGlobal(Bsize);
Marshal.Copy(OutBuffer, 0, UnManagedBuffer, Bsize);
if(WriteFile(USBDeviceInfo.WriteHandle, OutBuffer, Bsize, ref NumbersOfBytesWritten, IntPtr.Zero) == false)
{
error = Marshal.GetLastWin32Error().ToString();
return false;
}
if (Marshal.GetLastWin32Error().ToString() == "0")
{
Marshal.FreeHGlobal(UnManagedBuffer);
return true;
}
error = Marshal.GetLastWin32Error().ToString();
return false;
}