注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

一车,一房,一个温暖家

10万左右的车,80平方的房子,这是我奋斗的暖暖的家

 
 
 

日志

 
 

引用 上位机与单片机的互动(二)   

2015-03-22 14:53:15|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

今天是3月12号,时间过的可真快, 之前修改的都没来得及写上来,现在直接将成型的代码贴上来吧。 之前我定义了协议这个程序基本实现了,可能有些代码写的不够好。

以下是单片机的代码:

/*
*工程名称:单片机与上位机通信
*工程总监:OYPL
*工程时间:2011/02/28
*进度记录:
1、完成单片机与上位机通信。

2、完成通信协议的定义与实现。

3、完成数据的CRC校验。

*/
#include<reg52.h>
#include<intrins.h>
#include<CRC16.h>
#define uchar unsigned char
#define uint  unsigned int
//数据接收
uchar ga_ucRcvBuf[4];  //数据接收寄存器
uchar gc_uCount;   //数据接收计数器
bit gc_bRcvCount;   //数据接收计数器,接收完毕置1。
uchar g_uCrcLow;   //存储计算后的低位CRC
uchar g_uCrcHigh;   //存储计算后的高位CRC
uchar g_ucRcvCrcLow;  //暂储接收到的低位CRC
uchar g_ucRcvCrcHigh;  //暂储接收到的高位CRC
//数据发送
uchar ga_ucSendBuf[5];  //数据发送寄存器
uchar g_uSendCrcLow;  //发送数据CRC低位寄存器
uchar g_uSendCrcHigh;  //发送数据CRC高位寄存器
//数据处理
bit g_bCheckRcvData; //用于判断接收数据是否正确
/********************************************************************
* 名称 : Delay_1ms()
* 功能 : 延时子程序,延时时间为 1ms * x
* 输入 : x (延时一毫秒的个数)
* 输出 : 无
***********************************************************************/
void Delay_1ms(uint i)//1ms延时
{
  uchar x,j;
  for(j=0;j<i;j++)
  for(x=0;x<=148;x++);
}

/********************************************************************
* 名称 : Com_Int()
* 功能 : 串口中断子函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Com_Int(void) interrupt 4 using 3
{
  EA = 0;
  if(RI == 1)   //当硬件接收到一个数据时,RI会置位
  {
    RI = 0;
  /***************************成功
    ga_ucRcvBuf[0] = SBUF;
    Delay_1ms(1);
  ************************/
    ga_ucRcvBuf[gc_uCount] = SBUF;
    gc_uCount ++;
    if(gc_uCount > 4)
    {
     gc_uCount = 0;
   gc_bRcvCount = 1;
    }
   }
   EA = 1;
}

/********************************************************************
* 名称 : Com_Init()
* 功能 : 串口初始化,晶振11.0592,波特率9600,使能了串口中断
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Com_Init(void)
{
     TMOD = 0x20;
     PCON = 0x00;
     SCON = 0x50;  
     TH1 = 0xFd;    //设置波特率 9600
     TL1 = 0xFd;
     TR1 = 1;  //启动定时器1
   ES = 1;  //开串口中断
   EA = 1;  //开总中断 
}


/********************************************************************
* 名称 : checkData()
* 功能 : 检测接收到的数据是否正确?
* 输入 : 无
* 输出 : g_bCheckRcvData(返回1则为数据正确)
*********************************************************************/
bit checkData(void)
{
 if(ga_ucRcvBuf[2] == 0x01)
 {
  g_ucRcvCrcLow = ga_ucRcvBuf[0];
  g_ucRcvCrcHigh = ga_ucRcvBuf[1];
  ga_ucRcvBuf[0] = 0;
  ga_ucRcvBuf[1] = 0;
  g_uCrcLow = cal_crc(ga_ucRcvBuf,5);
  g_uCrcHigh = cal_crc(ga_ucRcvBuf,5) / 256;
  if((g_ucRcvCrcLow == g_uCrcLow) && (g_ucRcvCrcHigh == g_uCrcHigh))
  {
  //这里可以处理校验成功后的功能
  //这里为单片机接收到正确指令后给上位机回应
   g_bCheckRcvData = 1; //表明接收数据正确
  }else
  {g_bCheckRcvData = 0;}
 }
 return g_bCheckRcvData;
}

/********************************************************************
* 名称 : sendData()
* 功能 : 检测接收到的数据是否正确?
* 输入 : *gp_ucSendPtr(要发送的数据)
* 输出 : 无
*********************************************************************/
void sendData(uchar idata *gp_ucSendPtr)
{
 uchar i;
 for(i=0;i<5;i++)
 {
  SBUF = *gp_ucSendPtr;
  while(!TI);
  TI = 0;
  gp_ucSendPtr++;
  Delay_1ms(1);
 }
}

/********************************************************************
* 名称 : do_Command()
* 功能 : 根据接收到的命令做相应处理
* 输入 : 无
* 输出 : 无
*********************************************************************/
void do_Command(void)
{
 switch(ga_ucRcvBuf[3])  //取出数据帧中的命令
 {
  case 0x38:
  {
   P0 = ga_ucRcvBuf[4];
   break;
  }
  default: break;
 }
}
/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main()
{
  Com_Init();
  gc_uCount = 0;
  P0 = 0;
  g_uCrcLow = 0;   //存储计算后的低位CRC
  g_uCrcHigh = 0;   //存储计算后的高位CRC
  gc_bRcvCount = 0;   //接收数据计数器
  g_ucRcvCrcLow = 0;  //暂储接收到的低位CRC
  g_ucRcvCrcHigh = 0;  //暂储接收到的高位CRC
  while(1)
  {
   if(gc_bRcvCount == 1)
  {
   gc_bRcvCount = 0;
   EA = 0;
   if(checkData())    //数据正确性检测
   {
    g_bCheckRcvData = 0;  //将数据判断器复位
    do_Command();    //根据数据帧数据做相应处理
    //以下为反馈信息至单片机
    ga_ucSendBuf[0] = 0x00;
    ga_ucSendBuf[1] = 0x00;
    ga_ucSendBuf[2] = 0x02;
    ga_ucSendBuf[3] = ga_ucRcvBuf[3];
    ga_ucSendBuf[4] = ga_ucRcvBuf[4];
    g_uSendCrcHigh = cal_crc(ga_ucSendBuf,5)/256;  
    g_uSendCrcLow = cal_crc(ga_ucSendBuf,5);    //这里如果不用变量的话算出来的CRC会出错
    ga_ucSendBuf[0] = g_uSendCrcLow;
    ga_ucSendBuf[1] = g_uSendCrcHigh;
    sendData(ga_ucSendBuf);
   }
  }
  EA = 1;
  Delay_1ms(1);
 }
}

 

 

以下是VB的核心代码:

Dim ga_byRcvBuf(4) As Byte   '接收数据存储器
Dim gi_byRcvCount As Byte    '接收计数器,也是下标
Dim g_ucRcvCrcLow As Byte
Dim g_ucRcvCrcHigh As Byte
Dim g_uCrcLow As Byte
Dim g_uCrcHigh As Byte

'进度:
'完成基本页面, 完成与89C52单片机基本通讯。 2011/02/27
'已完成VB与单片机双方互动,CRC校验成功! 2011/03/04

'今日待完成进度:
'已完成基本通讯,双方进行通讯时CRC虽然计算正确,但单片机方未能正确解析数据帧。 2011/02/27


Private Sub Command1_Click()
    Dim crc As Long
    Dim crcData(4) As Byte
    crcData(0) = &H0
    crcData(1) = &H0
    'crcData(2) = &H0
    'crcData(3) = &H0
    crcData(2) = &H2
    crcData(3) = &H34
    crcData(4) = &H20
    crc = bCRC(crcData, 5)
    crc = crc And &HFF
    Print "CRC = "; crc
End Sub

'可用CRC校验码
Function bCRC(data() As Byte, le As Byte) As Long
'数组指针计数器
    Dim mc_bPtr As Byte
'unsigned char i;
    Dim i As Byte
'unsigned int crc=0;
    Dim crc As Long
    crc = 0
    mc_bPtr = 0
                            '<--------CRC计算入口
    Do While (le <> 0)
    le = le - 1
'for(i=0x80; i!=0; i/=2)
        Dim c As Byte       '模拟i=0x80
        c = &H80
        For i = 0 To 7
            If ((crc And &H8000) <> 0) Then
                crc = crc And &H7FFF
                crc = CLng(crc) * 2
                crc = CLng(crc) Xor &H1021
            Else
                crc = CLng(crc) * 2
            End If
            If ((data(mc_bPtr) And c) <> 0) Then
                crc = CLng(crc) Xor &H1021
            Else
            End If
            c = c / 2
         Next
             mc_bPtr = mc_bPtr + 1
    Loop
'return(crc);
    bCRC = CLng(crc)
End Function


Private Sub Command3_Click()    '断开COM连接
    If MSComm1.PortOpen = False Then
        MsgBox ("串口未打开!")
    Else
        MSComm1.PortOpen = False
        MsgBox ("串口关闭成功!")
    End If
    Dim a As Byte
    a = Combo1.ItemData(0)
    Print "A=" & a
End Sub

 

 

Private Sub contCom_Click()        '连接COM
    If MSComm1.PortOpen = False Then
      '  On Error GoTo cntOpenCom
        If Combo1.Text = "COM1" Then
            MSComm1.CommPort = 1
        ElseIf Combo1.Text = "COM2" Then
            MSComm1.CommPort = 2
        ElseIf Combo1.Text = "COM3" Then
            MSComm1.CommPort = 3
        ElseIf Combo1.Text = "COM4" Then
            MSComm1.CommPort = 4
        ElseIf Combo1.Text = "COM5" Then
            MSComm1.CommPort = 5
        ElseIf Combo1.Text = "COM6" Then
            MSComm1.CommPort = 6
        ElseIf Combo1.Text = "COM7" Then
            MSComm1.CommPort = 7
        End If
        MSComm1.PortOpen = True
         MsgBox ("串口打开完毕!")
    Else
        MsgBox ("串口已打开!")
'cntOpenCom:
'        MsgBox ("错误描述:" & Err.Description)
    End If
End Sub

Private Sub Form_Load()
    Combo1.ListIndex = 4    '设置COM口选项默认值
    Timer1.Enabled = False
    MSComm1.InBufferSize = 40 '初始化串口
    MSComm1.InBufferCount = 0
    MSComm1.InputMode = comInputModeBinary '二进制方式
    MSComm1.CommPort = 1
    MSComm1.Settings = "9600,N,8,1"
    MSComm1.RThreshold = 1
    MSComm1.InputLen = Val(Combo1.Text)
End Sub

Private Sub Command5_Click()        'LED全灭
    Dim sende(0 To 4) As Byte
    Dim g_lcrcLow As Byte
    Dim g_lcrcHigh As Byte
    Dim ccrc As Long
    sende(0) = &H0
    sende(1) = &H0
    sende(2) = &H1
    sende(3) = &H38
    sende(4) = &HFF
    g_lcrcLow = bCRC(sende, 5) And &HFF
    g_lcrcHigh = bCRC(sende, 5) \ 256
    sende(1) = g_lcrcHigh
    sende(0) = g_lcrcLow
    'Print "LOW=" & g_lcrcLow
     'Print "HIGH=" & g_lcrcHigh
     MSComm1.Output = sende
End Sub

Private Sub Command4_Click()        'LED半亮灭
    Dim sende(0 To 4) As Byte
    Dim g_lcrcLow As Byte
    Dim g_lcrcHigh As Byte
    Dim ccrc As Long
    sende(0) = &H0
    sende(1) = &H0
    sende(2) = &H1
    sende(3) = &H38
    sende(4) = &HAA
    g_lcrcLow = bCRC(sende, 5) And &HFF
    g_lcrcHigh = bCRC(sende, 5) \ 256
    sende(1) = g_lcrcHigh
    sende(0) = g_lcrcLow
    'Print "LOW=" & g_lcrcLow
     'Print "HIGH=" & g_lcrcHigh
     MSComm1.Output = sende
End Sub
':串口通信模块

Private Sub Command2_Click()    '测试LED全亮
    Dim sende(0 To 4) As Byte
    Dim g_lcrcLow As Byte
    Dim g_lcrcHigh As Byte
    Dim ccrc As Long
    sende(0) = &H0
    sende(1) = &H0
    sende(2) = &H1
    sende(3) = &H38
    sende(4) = &H0
    g_lcrcLow = bCRC(sende, 5) And &HFF
    g_lcrcHigh = bCRC(sende, 5) \ 256
    sende(1) = g_lcrcHigh
    sende(0) = g_lcrcLow
   ' Print "LOW=" & g_lcrcLow
     'Print "HIGH=" & g_lcrcHigh
     MSComm1.Output = sende
End Sub

Private Sub MSComm1_OnComm()        '接收程序
    If MSComm1.CommEvent = comEvReceive Then
       'Receive(0) = AscB(MSComm1.Input)
       ga_byRcvBuf(gi_byRcvCount) = AscB(MSComm1.Input)
        'Text1.Text = AscB(MSComm1.Input)
         End If
       gi_byRcvCount = gi_byRcvCount + 1
       If (gi_byRcvCount > 4) Then
            MSComm1.DTREnable = False
        gi_byRcvCount = 0
        If ga_byRcvBuf(2) = &H2 Then
                g_ucRcvCrcLow = ga_byRcvBuf(0)
                g_ucRcvCrcHigh = ga_byRcvBuf(1)
               'Text1.Text = "成功了====" & g_ucRcvCrcHigh
                ga_byRcvBuf(0) = 0
                ga_byRcvBuf(1) = 0
                g_uCrcLow = 0
                g_uCrcHigh = 0
                g_uCrcLow = bCRC(ga_byRcvBuf, 5) And &HFF
                g_uCrcHigh = bCRC(ga_byRcvBuf, 5) \ 256
               ' Text1.Text = "成功了!!!" & ga_byRcvBuf(4)
            If (g_ucRcvCrcLow = g_uCrcLow And g_ucRcvCrcHigh = g_uCrcHigh) Then
                Text1.Text = "成功了!!!" & ga_byRcvBuf(4)
            End If
        End If
        End If
          MSComm1.DTREnable = True
        MSComm1.InBufferCount = 0
End Sub

 

也是写的不精,只考虑到功能的实现,以后有时间再慢慢改善了!

  评论这张
 
阅读(7)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018