51单片机上位机编写与串口通信-深入了解串口

Posted CHENxiaomingming

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51单片机上位机编写与串口通信-深入了解串口相关的知识,希望对你有一定的参考价值。

采用环境

VS,keil:

简单介绍

简单的利用VS写上位机 ,和51单片机进行一个通信

单片机通信原理这里不多说直接放链接CSDN有很多很详细的博客

51单片机串口通信原理讲解

C#网上很多教程这里推荐一篇更加详细的博客

C#串口编程

对于串口不理解的可以看这一篇

C#中串口通信SerialPort类

此项目下载地址

https://download.csdn.net/download/chen_taifu/19827747


代码

C51

/*
	开发者邮箱
	@m.t-chen@foxmail.com
	串口发送数据和接收
*/
#include <reg52.h>
#include <stdio.h>
#include "ccom.h"      

//串口寄存器配置
void init()
{
	TMOD=0x20;	  		//定时器工作方式,选择了定时器1,工作方式2 八位初值自动重装的8位定时器。		 
	TH1=0xfd;	  			//定时器1初值	,设置波特率为9600 晶振11.0529MHZ?
	TL1=0xfd;
	TR1=1;		 				//打开计数器	 TCON
	SCON=0X50;				//设置为工作方式1 (10位/8位数据)允许串口接收位
	EA=1;	      			//允许中断(总闸)
	ES=1;		 		 			//允许串口中断
}

void main()
{
	init();								//初始化
	while(1)
{
	  if(bzf_cz==1)				//接收到数据运行
	{
		if(bzf_hh!=0)		    //是否需要换行检测
		{
			bzf_hh=0;					//重置
			TI=1;						
			printf("\\n");			//换行
			while(!TI);
			TI=0;
		}
			for(i=0;i<50;i++)
		{
			SBUF=s[i];
			while(!TI);
			TI=0;
		}
		bzf_cz=0;
	}
}
}
 
void ser() interrupt 4
{
		if(RI)		 								//接收数据,手动将RI清0
	{	    
		RI=0;
		
		if(bzf_cz==0&&j!=0)  			//第二次输入后将数组a还原
		{
			for(j=0;j<50;j++)				//最大50个字符
			s[j]='\\0';
			j=0;
			bzf_hh=1;								//换行标识符
		}
		s[j]=SBUF;								//读取数据到s
		bzf_cz=1;						      //接收标识符
		j++;	
	} 
}

上位机项目建立流程

新建项目/Visual C# 选择窗体应用

控件有label1 ,comboBox,textBox,button,

容器panel

组件serialPort

代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace _51串口机
{
    public partial class Form1 : Form
    {
        private StringBuilder sb = new StringBuilder();     //为了避免在接收处理函数中反复调用,依然声明为一个全局变量
        public Form1()
        {
            InitializeComponent();

        }

        private void Form1_Load(object sender, EventArgs e)
        {

            int i;
            for (i = 300; i <= 38400; i = i * 2)
            {
                comboBox2.Items.Add(i.ToString());  //添加波特率列表
            }
            //获取电脑当前可用串口并添加到选项列表中
            comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
            //批量添加波特率列表
            string[] comboxD = { "43000", "56000", "57600", "115200", "128000", "230400", "256000", "460800" };
            comboBox2.Items.AddRange(comboxD);

            //添加数据位列表
            string[] comboxA = { "6", "7", "8" };
            comboBox3.Items.AddRange(comboxA);

            //添加校验位列表
            string[] comboxC = { "0", "1" };
            comboBox4.Items.AddRange(comboxC);

            //添加停止位位列表
            string[] comboxB = { "1.5", "2" };
            comboBox5.Items.AddRange(comboxB);

            //设置默认值
            comboBox1.Text = "COM1";
            comboBox2.Text = "9600";
            comboBox3.Text = "8";
            comboBox4.Text = "None";
            comboBox5.Text = "1";
        }
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                //将可能产生异常的代码放置在try块中
                //根据当前串口属性来判断是否打开
                if (serialPort1.IsOpen)
                {
                    //串口已经处于打开状态
                    serialPort1.Close();    //关闭串口
                    button1.Text = "打开串口";
                    button1.BackColor = Color.ForestGreen;
                    comboBox1.Enabled = true;
                    comboBox2.Enabled = true;
                    comboBox3.Enabled = true;
                    comboBox4.Enabled = true;
                    comboBox5.Enabled = true;
                    textBox1.Text = "";     //清空接收区
                    textBox2.Text = "";     //清空发送区
                }
                else
                {
                    //串口已经处于关闭状态,则设置好串口属性后打开
                    comboBox1.Enabled = false;
                    comboBox2.Enabled = false;
                    comboBox3.Enabled = false;
                    comboBox4.Enabled = false;
                    comboBox5.Enabled = false;
                    serialPort1.PortName = comboBox1.Text;
                    serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);
                    serialPort1.DataBits = Convert.ToInt16(comboBox3.Text);

                    if (comboBox4.Text.Equals("None"))
                        serialPort1.Parity = System.IO.Ports.Parity.None;
                    else if (comboBox4.Text.Equals("Odd"))
                        serialPort1.Parity = System.IO.Ports.Parity.Odd;
                    else if (comboBox4.Text.Equals("Even"))
                        serialPort1.Parity = System.IO.Ports.Parity.Even;
                    else if (comboBox4.Text.Equals("Mark"))
                        serialPort1.Parity = System.IO.Ports.Parity.Mark;
                    else if (comboBox4.Text.Equals("Space"))
                        serialPort1.Parity = System.IO.Ports.Parity.Space;

                    if (comboBox5.Text.Equals("1"))
                        serialPort1.StopBits = System.IO.Ports.StopBits.One;
                    else if (comboBox5.Text.Equals("1.5"))
                        serialPort1.StopBits = System.IO.Ports.StopBits.OnePointFive;
                    else if (comboBox5.Text.Equals("2"))
                        serialPort1.StopBits = System.IO.Ports.StopBits.Two;

                    serialPort1.Open();     //打开串口
                    button1.Text = "关闭串口";
                    button1.BackColor = Color.Firebrick;
                }
            }
            catch (Exception ex)
            {
                //捕获可能发生的异常并进行处理

                //捕获到异常,创建一个新的对象,之前的不可以再用
                serialPort1 = new System.IO.Ports.SerialPort();
                //刷新COM口选项
                comboBox1.Items.Clear();
                comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
                //响铃并显示异常给用户
                System.Media.SystemSounds.Beep.Play();
                button1.Text = "打开串口";
                button1.BackColor = Color.ForestGreen;
                MessageBox.Show(ex.Message);
                comboBox1.Enabled = true;
                comboBox2.Enabled = true;
                comboBox3.Enabled = true;
                comboBox4.Enabled = true;
                comboBox5.Enabled = true;
            }
        }

        private void SerialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            sb.Clear();                              //防止出错,首先清空字符串构造器
            int num = serialPort1.BytesToRead;      //获取接收缓冲区中的字节数
            byte[] received_buf = new byte[num];    //声明一个大小为num的字节数据用于存放读出的byte型数据

            serialPort1.Read(received_buf, 0, num);   //读取接收缓冲区中num个字节到byte8位类型 received数组中

            sb.Append(Encoding.ASCII.GetString(received_buf));  //将整个数组解码为ASCII数组
            foreach (byte b in received_buf) //遍历数组进行字符串转化及拼接
            {
                sb.Append(b.ToString());
            }

            try
            {
                //因为要访问UI资源,所以需要使用invoke方式同步ui
                Invoke((EventHandler)(delegate
                {
                    textBox1.AppendText(sb.ToString());
                }
                ));

            }
            catch (Exception ex)
            {
                //响铃并显示异常给用户
                System.Media.SystemSounds.Beep.Play();
                MessageBox.Show(ex.Message);

            }

        }

        private void label6_Click(object sender, EventArgs e)
        {

        }

        private void button2_Click(object sender, EventArgs e)
        { 
            try
            {

                //首先判断串口是否开启
                if (serialPort1.IsOpen)
                {
                    serialPort1.Write(textBox2.Text);

                }
            }
            catch (Exception ex)
            {
                serialPort1.Close();
                //捕获到异常,创建一个新的对象,之前的不可以再用
                serialPort1 = new System.IO.Ports.SerialPort();
                //刷新COM口选项
                comboBox1.Items.Clear();
                comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
                //响铃并显示异常给用户
                System.Media.SystemSounds.Beep.Play();
                button1.Text = "打开串口";
                button1.BackColor = Color.ForestGreen;
                MessageBox.Show(ex.Message);
                comboBox1.Enabled = true;
                comboBox2.Enabled = true;
                comboBox3.Enabled = true;
                comboBox4.Enabled = true;
                comboBox5.Enabled = true;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            textBox2.Text = "";  //清空接收文本框
            textBox1.Text = "";     //清空发送文本框
        }
    }
}

以上是关于51单片机上位机编写与串口通信-深入了解串口的主要内容,如果未能解决你的问题,请参考以下文章

51单片机上位机编写与串口通信-深入了解串口

51单片机串口通讯,数据在发送后,上位机没有接收到数据。

c语言 让计算机像单片机一样接收串口发来的数据

隔壁老王看了都会的文章:STM32串口实验——单片机与上位机交互信息

LabVIEW上位机与串口通信

两片单片机通过串口一发一收的C语言例程