多通道数据采集

淡定如旧 2013-01-05 09:42:52
各位高手,最近做了一个多通道的数据采集,遇到了一个麻烦,希望您能帮我一下,我要做的就是用单片机采集数据,然后通过串口送到上位机里,上位机用的是vb,从下位机猜到的是1000个字节的数据,这1000个乬是四个通道的数据,也就是每个通道有250个字节,现在我已经能够顺利采集到了数据了,在vb工程文件中国的textbox显示的是1000个十六进制的数据,现在我想把这十六进制的数据转换成具体的唯一值,我采用的是8位的AD转换器,怎么才能吧这些十六进制转换成正常的十进制的浮点数的位移,传感器输入的是0-5V的电压,所对应的位移是0-1250mm,下面是我的代码,希望高手给我指点一下如何才能将这1000个字节的十六进制的数据转换成十进制的0-1250mm的位移啊?

上位机程序代码

Public Class 多通道数据采集
Public Delegate Sub myDelegate()
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
For i As Integer = 0 To My.Computer.Ports.SerialPortNames.Count - 1

cmbSerialPort.Items.Add(My.Computer.Ports.SerialPortNames(i))
Next
btnCloseSerialPort.Enabled = False
SerialPort.Close()
Timer.Enabled = False
picState.BackColor = Color.Red
cmbBoadrate.Items.Add("4800")
cmbBoadrate.Items.Add("9600")
cmbBoadrate.Items.Add("57600")
cmbChanel.Items.Add("通道一")
cmbChanel.Items.Add("通道二")
cmbChanel.Items.Add("通道三")
cmbChanel.Items.Add("通道四")
End Sub
Private Sub btnOpenSerialPort_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOpenSerialPort.Click
If SerialPort.IsOpen = True Then
SerialPort.Close()
End If
If cmbSerialPort.Text = "" Then
MessageBox.Show("请选择一个串口", "串口选择警告", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
SerialPort.PortName = cmbSerialPort.Text
SerialPort.ReadBufferSize = 4096
SerialPort.BaudRate = cmbBoadrate.Text
SerialPort.Parity = IO.Ports.Parity.None
SerialPort.DataBits = 8
SerialPort.StopBits = IO.Ports.StopBits.One
SerialPort.DiscardNull = True
SerialPort.DtrEnable = False
SerialPort.Encoding = System.Text.Encoding.ASCII
SerialPort.RtsEnable = False
SerialPort.Open()
picState.BackColor = Color.Green
btnCloseSerialPort.Enabled = True
End If
End Sub
Private Sub btnClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClear.Click
If MessageBox.Show("清空文本框显示请选择Yes,清零计数器请选择No", "选择一个删除对象", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information) = Windows.Forms.DialogResult.Yes Then
txtDataReceive.Text = String.Empty

Else
txtNumOfReceive.Text = "0"
txtNumOfSendChar.Text = "0"

End If


End Sub
Public Sub SendtoSbuf()
Dim TestArray() As String = Split("fe")
'Dim str(0)="fe" as string
Dim hexBytes() As Byte
ReDim hexBytes(TestArray.Length - 1)
Dim i As Integer
For i = 0 To TestArray.Length - 1
hexBytes(i) = Val("&h" & TestArray(0))
Next
SerialPort.Write(hexBytes, 0, 1)
txtNumOfSendChar.Text = (Val(txtNumOfSendChar.Text) + 1).ToString
End Sub
Public Function DecToHex(ByVal DecNumber As Byte) As String '转换成十六进制字符串
If DecNumber <= 15 Then
DecToHex = " 0" & Hex(DecNumber)
Else : DecToHex = " " & Hex(DecNumber)
End If
End Function
Public Sub GetCharFromAndSendToTextBox()
Dim str_indata As String
Dim byteToRead As Int16


byteToRead = SerialPort.BytesToRead '(读取缓冲区的字节长度)
txtNumOfReceive.Text = (Val(txtNumOfReceive.Text) + byteToRead).ToString

Dim ch(byteToRead) As Byte

Dim bytesRead As Int16 = 0
' str_indata = SerialPort1.ReadExisting()

bytesRead = SerialPort.Read(ch, 0, byteToRead)


If bytesRead > 0 Then
For i As Int16 = 0 To bytesRead - 1
'System.Threading.Thread.Sleep(50) ' 这个很重要!
str_indata = str_indata & DecToHex(ch(i))
Next
End If
With txtDataReceive
.Font = New Font("Garamond", 12.0!, FontStyle.Bold)
.AppendText(str_indata)
.ScrollToCaret()
End With

End Sub
Private Sub btnStartCollectData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStartCollectData.Click

If SerialPort.IsOpen = True Then
SendtoSbuf()
Else : MessageBox.Show("请打开串口", "警告", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
End If


End Sub

Private Sub btnCloseSerialPort_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCloseSerialPort.Click
SerialPort.Close()
picState.BackColor = Color.Red
End Sub

Private Sub SerialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort.DataReceived
txtDataReceive.Invoke(New myDelegate(AddressOf GetCharFromAndSendToTextBox), New Object() {})

End Sub

Private Sub btnCycleCollect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCycleCollect.Click

If SerialPort.IsOpen = True Then
SendtoSbuf()

Timer.Enabled = True
Else : MessageBox.Show("请打开串口", "警告", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
End If

End Sub

Private Sub Timer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer.Tick


SendtoSbuf()
End Sub

Private Sub btnStopCollect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStopCollect.Click
Timer.Enabled = False
End Sub
End Class


...全文
79 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
贝隆 2013-01-06
  • 打赏
  • 举报
回复
淡定如旧 2013-01-05
  • 打赏
  • 举报
回复
我最后的目的就是把数据写到数据库里,然后把位移画到picturebox里面,怎么才能完成啊?着急中,网高手相助,感激不尽
淡定如旧 2013-01-05
  • 打赏
  • 举报
回复
下位机单片机程序 //-----------------------函数声明,变量定义------------------------ #include <reg51.h> #include <intrins.h> sbit SCL=P1^2; // 将p1.2口模拟时钟口 sbit SDA=P1^3; // 将p1.3口模拟数据口 sbit key=P1^4; bit askflag; #define uchar unsigned char #define uint unsigned int #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();}; bit bdata SystemError; //从机错误标志位 /*********************** PCF8591专用变量定义 ***********************/ #define PCF8591_WRITE 0x90 #define PCF8591_READ 0x91 #define NUM 4 //接收和发送缓存区的深度 uchar idata receivebuf[NUM]; //数据接收缓冲区 /****************************************************************** * 串行通信波特率设置 * * * *******************************************************************/ cxtx_btl() { TMOD = 0x20; // 定时器1工作于8位自动重载模式, 用于产生波特率 TH1=TL1=0xFF; // 波特率9600 SCON = 0x50; // 设定串行口工作方式1 允许接收,相当于下面三句 //SM0=0; //SM1=1; //REN=1; PCON =0x80; // 波特率不倍增 TR1 = 1; } /******************************************************************* * 向串行口发送一个数据 * * * ********************************************************************/ void send_char(unsigned char txd) // 传送一个字符 { SBUF = txd; while(!TI); // 等特数据传送 TI = 0; // 清除数据传送标志 } /*******************************************************************/ /* */ /* 延时函数 */ /* */ /*******************************************************************/ void delay(int ms) { while(ms--) { uchar i; for(i=0;i<250;i++) { _nop_(); _nop_(); _nop_(); _nop_(); } } } //------------------------------------------------------------------- // 函数名称: iic_start() // 函数功能: 启动I2C总线子程序 //------------------------------------------------------------------- void iic_start(void) { //时钟保持高,数据线从高到低一次跳变,I2C通信开始 SDA = 1; SCL = 1; delayNOP(); // 延时5us SDA = 0; delayNOP(); SCL = 0; } //------------------------------------------------------------------- // 函数名称: iic_stop() // 函数功能: 停止I2C总线数据传送子程序 //------------------------------------------------------------------- void iic_stop(void) { SDA = 0; //时钟保持高,数据线从低到高一次跳变,I2C通信停止 SCL = 1; delayNOP(); SDA = 1; delayNOP(); SCL = 0; } //------------------------------------------------------------------ // 函数名称: iicInit_() // 函数功能: 初始化I2C总线子程序 //------------------------------------------------------------------ void iicInit(void) { SCL = 0; iic_stop(); } //------------------------------------------------------------------- // 函数名称: slave_ACK // 函数功能: 从机发送应答位子程序 //------------------------------------------------------------------- void slave_ACK(void) { SDA = 0; SCL = 1; delayNOP(); SCL = 0; } //------------------------------------------------------------------- // 函数名称: slave_NOACK // 函数功能: 从机发送非应答位子程序,迫使数据传输过程结束 //------------------------------------------------------------------- void slave_NOACK(void) { SDA = 1; SCL = 1; delayNOP(); SDA = 0; SCL = 0; } //------------------------------------------------------------------- // 函数名称: check_ACK // 函数功能: 主机应答位检查子程序,迫使数据传输过程结束 //------------------------------------------------------------------- void check_ACK(void) { SDA = 1; // 将p1.1设置成输入,必须先向端口写1 SCL = 1; askflag = 0; delayNOP(); if(SDA == 1) // 若SDA=1表明非应答,置位非应答标志askflag askflag = 1; SCL = 0; } //------------------------------------------------------------------- // 函数名称: IICSendByte // 入口参数: ch // 函数功能: 发送一个字节 //------------------------------------------------------------------- void IICSendByte(uchar ch) { unsigned char idata n=8; // 向SDA上发送一位数据字节,共八位 while(n--) { if((ch&0x80) == 0x80) // 若要发送的数据最高位为1则发送位1 { SDA = 1; // 传送位1 SCL = 1; delayNOP(); // SDA = 0; SCL = 0; } else { SDA = 0; // 否则传送位0 SCL = 1; delayNOP(); SCL = 0; } ch = ch<<1; // 数据左移一位 } } //------------------------------------------------------------------- // 函数名称: IICreceiveByte // 返回接收的数据 // 函数功能: 接收一字节子程序 //------------------------------------------------------------------- uchar IICreceiveByte(void) { uchar idata n=8; // 从SDA线上读取一上数据字节,共八位 uchar tdata=0; while(n--) { SDA = 1; SCL = 1; tdata =tdata<<1; //左移一位 if(SDA == 1) tdata = tdata|0x01; // 若接收到的位为1,则数据的最后一位置1 else tdata = tdata&0xfe; // 否则数据的最后一位置0 SCL = 0; } return(tdata); } //------------------------------------------------------------------- // 函数名称: DAC_PCF8591 // 入口参数: slave_add从机地址,n要发送的数据个数 // 函数功能: 发送n位数据子程序 //------------------------------------------------------------------- void DAC_PCF8591(uchar controlbyte,uchar w_data) { iic_start(); // 启动I2C delayNOP(); IICSendByte(PCF8591_WRITE); // 发送地址位 check_ACK(); // 检查应答位 if(askflag == 1) { SystemError = 1; return; // 若非应答,置错误标志位 } IICSendByte(controlbyte&0x77); //Control byte check_ACK(); //检查应答位 if(askflag == 1) { SystemError = 1; return; // 若非应答,置错误标志位 } IICSendByte(w_data); //data byte check_ACK(); // 检查应答位 if(askflag == 1) { SystemError = 1; return; // 若非应答表明器件错误或已坏,置错误标志位SystemError } iic_stop(); // 全部发完则停止 delayNOP(); delayNOP(); delayNOP(); delayNOP(); } //------------------------------------------------------------------- // 函数名称: ADC_PCF8591 // 入口参数: controlbyte控制字 // 函数功能: 连续读入4路通道的A/D转换结果到receivebuf //------------------------------------------------------------------- void ADC_PCF8591(uchar controlbyte) { uchar idata receive_da,i=0; iic_start(); IICSendByte(PCF8591_WRITE); //控制字 check_ACK(); if(askflag == 1) { SystemError = 1; return; } IICSendByte(controlbyte); //控制字 check_ACK(); if(askflag == 1) { SystemError = 1; return; } iic_start(); //重新发送开始命令 IICSendByte(PCF8591_READ); //控制字 check_ACK(); if(askflag == 1) { SystemError = 1; return; } IICreceiveByte(); //空读一次,调整读顺序 slave_ACK(); //收到一个字节后发送一个应答位 while(i<4) { receive_da=IICreceiveByte(); receivebuf[i++]=receive_da; slave_ACK(); //收到一个字节后发送一个应答位 } slave_NOACK(); //收到最后一个字节后发送一个非应答位 iic_stop(); } //------------------------------------------------------------------- // 函数名称: main // 函数功能: 主程序 //------------------------------------------------------------------- main() { cxtx_btl(); delay(10); //延时 while(1) { uchar i,sbuf; if(RI==1) { RI=0; sbuf=SBUF; if(sbuf==0xFE) { iicInit(); //I2C总线初始化 ADC_PCF8591(0x04); if(SystemError == 1) //有错误,重新来 { iicInit(); //I2C总线初始化 ADC_PCF8591(0x04); } for(i=1;i<=250;i++) { iicInit(); //I2C总线初始化 ADC_PCF8591(0x04); send_char(receivebuf[0]); send_char(receivebuf[1]); send_char(receivebuf[2]); send_char(receivebuf[3]); } iicInit(); //I2C总线初始化 DAC_PCF8591(0x40,receivebuf[0]); //D/A输出 if(SystemError == 1) //有错误,重新来 { iicInit(); //I2C总线初始化 DAC_PCF8591(0x40,receivebuf[0]); //D/A输出 } //delay(50); //延时 } } } }

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧