2010年9月23日星期四

【例程】PC与单片机的串口通讯的简单实例

PC与单片机的串口通讯的简单实例
这几天看了些串口方面的资料,决定设计一个简单的实验,以强化所学的东西。实验实现的功能主要是:用PC上的一个软件通过串口通讯控制单片机I/O口的输出。本次实验主要涉及PC端上位机的程序编写(用VC)与单片机程序的编写(用Keil)。为了简化实验,PC端软件设计成具有8个按钮的对话框,每个按钮分别控制单片机P2口的一个引脚的高低电平。为了体现直观的结果,P2口上接上8个发光二极管。实验的原理图如下:




PC与单片机的通讯协议如下:采用4800波特率,无校验位,8个数据位,1个停止位,一次传输一个控制字节。

一、上位机软件的编写

       本来控制单片机只需单向传输数据即可,为了熟悉PC端接受数据的功能,在应用软件将控制数据传输到单片机端后,单片机端回传数据给应用软件,并用16进制格式显示在编辑控件中。

       VC实现对串口的控制主要有两种方式:mscomm控件与api函数。由于mscomm控件实现简单,本实验采用该方式。

1.       在VC中创建一个基于对话框的应用程序,在该程序中插入Mscomm控件。修改对话框资源,增加Mscomm及8个按钮控件与一个编辑框。并为Mscomm控件增加一个控件变量m-com。

2.       在对话框的OnInitDialog()函数中初始化串口,代码如下:

  if(m_com.GetPortOpen())

         m_com.SetPortOpen(FALSE);

  m_com.SetCommPort(1);//选择com1

  if(!m_com.GetPortOpen())

         m_com.SetPortOpen(TRUE);//打开串口

  else

         MessageBox("无法打开串口!");

  m_com.SetSettings("4800,n,8,1");//波特率4800,无校验,8个数据位,1个停止位

  m_com.SetInputMode(1); //1:表示以二进制方式检取数据

  m_com.SetRThreshold(1);//参数1表示每当串口接收缓冲区中有多于

                        //或等于1个字符时将引发一个接收数据的OnComm事件

  m_com.SetInputLen(0); //设置当前接收区数据长度为0

  m_com.GetInput();//先预读缓冲区以清除残留数据

3.为每个按钮添加命令函数。下面为其中一个函数的代码,其他与此类似。

void CComDlg::OnP20()

{

  // TODO: Add your control notification handler code here

  Output.Format("%c",0x01);

  m_com.SetOutput(COleVariant(Output));

}

4.接受数据时采用Mscomm控件的响应函数进行对事件的捕捉。处理代码如下:

void CComDlg::OnComm()

{

  // TODO: Add your control notification handler code here

  VARIANT Input;

  CString temp;

  long k,len;

  COleSafeArray OleArray;

  BYTE rxdata[10];

  if (2==m_com.GetCommEvent())

  {

         Input=m_com.GetInput();

         OleArray=Input;

         len=OleArray.GetOneDimSize();

         for (k=0;k

         {

                OleArray.GetElement(&k,rxdata+k);

                BYTE bt=*(char *)(rxdata+k);

                temp.Format("%02X ",bt);

                m_recv+=temp;

         }                         

  }

  UpdateData(FALSE);

}

二、单片机程序的编写。

单片机程序编写相对容易,只需进行初始话串口,接受数据,发送数据等工作即可。代码如下:

#include

unsigned char inbuf;

unsigned char flag;

//初始化函数

void init_serialcomm(void)

{

    SCON  = 0x50;       //SCON: serail mode 1, 8-bit UART, enable ucvr,0101000b

    TMOD |= 0x20;       //TMOD: timer 1, mode 2, 8-bit reload,0010000b

    PCON |= 0x80;       //SMOD=1;10000000b

    TH1   = 0xF4;       //Baud:4800  fosc=11.0592MHz

    IE   |= 0x90;       //Enable Serial Interrupt

    TR1   = 1;                 // timer 1 run

    inbuf=0;

       P2=0;       

   // TI=1;

}

//向串口发送一个字符

void send_char_com(unsigned char ch) 

{

    SBUF=ch;

    while(TI==0);

    TI=0;

}