wolfccb 的个人资料老狼的窝照片日志列表 工具 帮助

日志


2006/6/24

VB串口通信数据采集

前两天受人之托写的一个程序,发上来共享,从中可以看到串口通信的常用处理方式,希望对大家有所帮助。

一、系统需求:使用三线制串口,利用vb与dsp通信,采集数据并存储为文本文件。

二、通信协议

1. RS232串行通信的波特率设为9600,8位数据位,一位停止位,无校验位。

2. 每组数据包含T1(16位)和T2(16位),将每个数据分成2个8位的数据,先是低8位,然后是高8位。数据为无符号整型。

   先发T1,然后发T2,然后是下一组T1、T2。
   T1以头数据0x0A(16进制,10进制位10)为头字节,然后是T1的低8位,T1的高8位。
   T2以头数据0xA0(16进制,10进制位160)为头字节,然后是T2的低8位,T2的高8位。
   发送时序举例:0x0A, t1低8位,t1高8位,0xA0, t2低8位,t2高8位……
   将收到的数据T1、T2的高低8位合并,转换成10进制数,以每行T1 T2的形式存储到txt文本文件中。

三、要点说明
0. 如果通信协议没有考虑周全就着手开始做,可能会经受无比的痛苦

1. 文本框textbox的大小限制为32k,不符合大量数据的需要,因此使用richtextbox

2. 换行符为Chr(&HD) + Chr(&HA)

3. 需要用状态栏给出必要的信息

4. 保存文件的默认名字为当前日期

5. 收到comm事件后,需要关闭com事件接收,避免再次触发事件

四、程序源代码:

Dim av As Variant
Dim datacount As Long

Private Sub cmdClear_Click()
    txtData.Text = ""
End Sub

Private Sub cmdStop_Click()
   
    '关闭端口
    If MSComm.PortOpen = True Then
        MSComm.InBufferCount = 0    '清空缓冲区
        MSComm.PortOpen = False
    End If
   
    cmdReceive.Enabled = True
    lblStatus.Caption = "停止接收,空闲"
   
End Sub

Private Sub cmdReceive_Click()
   
    '串口设置
    With MSComm
        .CommPort = 1
        .Settings = "9600,N,8,1"
        .RThreshold = 1         '接收1字节触发oncomm事件
        .InputMode = comInputModeBinary
        .InputLen = 1           '输入长度为1
        .InBufferCount = 0      '清除接收缓冲区
    End With

    '打开端口
    If MSComm.PortOpen = False Then
        MSComm.PortOpen = True
        If Err Then
            MsgBox (Err.Description)
            Exit Sub
        End If
    End If
        
    lblStatus.Caption = "打开端口,等待接收"
    datacount = 0
    cmdReceive.Enabled = False
End Sub

Private Sub cmdSave_Click()

    Dim outfn As String

    MsgBox ("接收了" + CStr(datacount) + "组数据")
    lblStatus.Caption = "接收完成,请选择输出文件"
   
    cmdReceive.Enabled = True
   
    '选择输出文件
    CommonDialog1.FileName = CStr(Date) + ".txt"
    CommonDialog1.Filter = "Text Files|*.txt"
    CommonDialog1.Flags = CommonDialog1.Flags Or cdlOFNOverwritePrompt
    CommonDialog1.CancelError = True
    On Error GoTo errhandler
        CommonDialog1.ShowSave
        outfn = CommonDialog1.FileName
        
        Open outfn For Output As #1
            Print #1, txtData.Text
        Close #1
   
    'txtData.SaveFile outfn
    lblStatus.Caption = "输出完成,空闲"
   
errhandler:
    Exit Sub
End Sub

Private Sub Form_Load()
    lblStatus.Caption = "空闲"
End Sub

Private Sub Form_Unload(Cancel As Integer)

    '关闭端口
    If MSComm.PortOpen = True Then
        MSComm.InBufferCount = 0    '清空缓冲区
        MSComm.PortOpen = False
    End If
   
End Sub

Private Sub MSComm_OnComm()
    Dim T1, T2 As Long
    Select Case MSComm.CommEvent
   
        Case comEvReceive       '收到Rthreshold个字节产生的接收事件
           
            MSComm.RThreshold = 0    '关闭OnComm事件接收

            lblStatus.Caption = "接收"
            av = MSComm.Input       '读取一个接收字节
            dataframe(1) = av(0)    '转换为字节
           
            If dataframe(1) = &HA Then   '接收到T1
               
                Do
                    DoEvents
                Loop Until MSComm.InBufferCount >= 2  '循环等待接收缓冲区>=2个字节
               
                av = MSComm.Input
                dataframe(2) = av(0)
                av = MSComm.Input
                dataframe(3) = av(0)       '接收T1
                T1 = dataframe(2) + CLng(dataframe(3)) * 256    '计算T1
            End If
           
            Do
                DoEvents
            Loop Until MSComm.InBufferCount >= 1  '循环等待接收缓冲区>=1个字节

            av = MSComm.Input       '读取一个接收字节
            dataframe(4) = av(0)    '转换为字节
           
            '接收到T2
            If dataframe(4) = &HA0 Then
                'MSComm.RThreshold = 0     '关闭OnComm事件接收
               
                '循环等待接收缓冲区>=2个字节
                Do
                    DoEvents
                Loop Until MSComm.InBufferCount >= 2
               
                av = MSComm.Input
                dataframe(5) = av(0)
                av = MSComm.Input
                dataframe(6) = av(0)       '接收T2
                T2 = dataframe(5) + CLng(dataframe(6)) * 256    '计算T2
               
                '显示T1 T2 enter
                txtData.Text = txtData.Text + CStr(T1) + " " + CStr(T2) + Chr(&HD) + Chr(&HA)
               
                datacount = datacount + 1   '数据组数+1
            End If
           
            MSComm.RThreshold = 1       '打开OnComm事件接收
           
        Case Else
        
    End Select
   
End Sub
 
以上。
吹空调的老狼
2006/6/1

写在儿童节

今天早晨收到短信,说要问我一个很残酷的问题——你小时候最大的梦想是什么?
 
问题确实残酷,我小时候对星空痴迷不已,每天晚上都看得脖子生疼,当时的梦想就是能成为一个天文学家。记得那时候还不知道“清华”等等名校,只知道北大非常牛,于是就跟爸妈夸海口说要考入北大天文系——谁知道北大天文系现在成立了没有?
 
曾经想拥有一个天文望远镜,一直未能如愿。
 
忽然想到,居然我到现在还没透过那几片精密的透镜看过星空,遗憾啊,看来有必要去一下天文馆一类的地方了。
 
路过的朋友,说说你们小时候的梦想吧,呵呵。
 
以上。
残酷的老狼

matlab生成m序列的函数

原来那个效率太低,主要是因为实际应用并不需要生成太长的m序列,加入了需求长度,能有效减少运行时间。25级的移位寄存器,运行了一个小时都没有出来一周期,我仅仅需要三千bit而已。改进版:
 
function [seq]=mseq(connections,registers,len);
%***************************************************
% 此函数用来生成最大长度线性移位寄存器序列
% connections为特征多项式向量,registers为初始值向量
% len为所需序列长度,若为0则输出一个周期
%***************************************************
m=length(connections);
L=2^m-1;     %周期长度
if len==0
    len=L;
end
fan=0;
for i=1:len
    seq(i)=registers(m);
    for j=1:m
        fan=fan +connections(j)*registers(j);
        fan=(mod(fan,2));
    end
    for t=m:-1:2  %寄存器移位
        registers(t)=registers(t-1);
    end
    registers(1)=fan;
    fan=0;
end
 
以上。
很久没来的老狼