PC和单片机通信(二)---使用SerialPort控件

PC和单片机通信(二)---使用SerialPort控件


单个单片机与PC串口通信:
1)测试通信状态
先在文本框中输入字符串“Hello”,单击“测试”按钮,将字符串“Hello”发送到单片机,若PC与单片机通信正常,在PC程序的文本框中显示字符串“OK!”,否则显示字符串“ERROR!”。
2)循环计数
单击“开始”按钮,文本框中数字从0开始累加,0、1、2、3…,并将此数发送到单片机的显示器上显示;当累加到10时,回到0重新开始累加,依次循环;任何时候,单击“停止”按钮,PC程序中和单片机显示器都停止累加,再单击“开始”按钮,接着停下的数继续累加。
3)控制指示灯
在单片机继电器接线端子的2个通道上分别接上2个指示灯,在PC程序画面上选择指示灯号,如1号灯,单击画面“打开”按钮,单片机上1号灯亮,同时蜂鸣器响;单击画面“关闭”按钮,1号灯灭,蜂鸣器停止响;同样控制2号灯的亮灭(蜂鸣器同时动作)。

1、C#界面和程序设计

(1)界面


(2)代码

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

namespace PC控制单片机
{
    public partial class Form1 : Form
    {
        //定义变量
        string f;
        string data;
        int x;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e) //窗体加载时进行串口初始化
        {
            serialPort1.PortName = "COM7";  //端口名称
            serialPort1.BaudRate = 9600;    //波特率
            serialPort1.Open();             //打开串口
            groupBox2.Enabled = false;      //GroupBox2中控件不可用



        }

        private void button2_Click(object sender, EventArgs e)//开始计数
        {
            timer1.Enabled = true;
            timer1.Interval = 400;
            serialPort1.Write("R");
        }

        private void button3_Click(object sender, EventArgs e)//停止计数
        {
            timer1.Enabled = false;
            serialPort1.Write("S");
        }

        private void radioButton1_CheckedChanged(object sender, EventArgs e)    //选择1号灯
        {
            f = "1";

        }

        private void radioButton2_CheckedChanged(object sender, EventArgs e)    //选择2号灯
        {
            f = "2";
        }

        private void button4_Click(object sender, EventArgs e)  //打开指示灯
        {
            if (f=="1")
            {
                serialPort1.Write("A");
            }
            else
            {
                serialPort1.Write("C");
            }
        }

        private void button5_Click(object sender, EventArgs e)  //关闭指示灯
        {
            if (f == "1")
            {
                serialPort1.Write("B");
            }
            else
            {
                serialPort1.Write("D");
            }
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            data = serialPort1.ReadExisting();
            this.Invoke(new EventHandler(DisplayText));
        }
        private void DisplayText(object sender, EventArgs e)
        {

        }
        private void button6_Click(object sender, EventArgs e)  //关闭串口,退出程序
        {
            serialPort1.Close();
            Close();

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (serialPort1.IsOpen)
                serialPort1.Close();
        }

        private void timer1_Tick(object sender, EventArgs e)    //循环计数 
        {
            x++;
            if (x>20)
                x = 1;
            textBox2.Text = x.ToString();
            

        }

        private void button1_Click(object sender, EventArgs e)//测试按钮
        {
            //把字符"H"通过串口发送出去,如果正常,单片机返回字符串"OK"
            serialPort1.Write(textBox1.Text);
            System.Threading.Thread.Sleep(1000);//延时
            if (data == "OK")
            {
                textBox1.Text = "OK";
                groupBox2.Enabled = true;
                groupBox3.Enabled = true;
                button1.Enabled = false;
            }
            else
            {
                textBox1.Text = "ERROR!";
                button1.Enabled = false;
            }
        }
        
    }
}

2、单片机程序

/******************************************************************
** 单个单片机与PC串口通信
** 晶 振 频 率:11.0592M
** 线       路:单片机实验开发板B
******************************************************************/
/*
		      PC   MCU
			  H    OK
			  R    开始记数
			  S    停止记数
			  A    1号灯亮,同时蜂鸣器响
			  B    1号灯灭,蜂鸣器停止响
			  C    2号灯亮,同时蜂鸣器响
			  D    2号灯灭,蜂鸣器停止响
*/

#include <reg51.h>	

/****************************数码显示 键盘接口定义****************************************/   
sbit PS0=P2^4;	//数码管个位    
sbit PS1=P2^5;	//数码管十位    
sbit PS2=P2^6;	//数码管百位	   
sbit PS3=P2^7;	//数码管千位
sfr  P_data=0x80;	//P0口为显示数据输出口
sbit P_K_L=P2^2;	//键盘列 

unsigned char tab[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0xee,0x3e,0x9c,0x7a,0x9e,0x8e};//字段转换表
sbit P_1=P1^1;
sbit P_3=P1^3;
sbit P_7=P1^7;
sbit LIGHT1=P2^1;
sbit LIGHT2=P2^0;
sbit BUZZER=P3^7;
unsigned char COUNTER;//循环计数器
bit count;//循环计数器 启停标志位 1启动记数 0停止记数

/*******************************延时函数*********************************/
/*函数原型:delay(unsigned int delay_time)
/*函数功能:延时函数
/*输入参数:delay_time (输入要延时的时间)
/*输出参数:无
/*调用模块:无
/**********************************************************************/
void delay(unsigned int delay_time)   //短延时子程序
{for(;delay_time>0;delay_time--)
{}
  }

unsigned char htd(unsigned char a)
{
	 unsigned char b,c;
	 b=a%10;
	 c=b;
	 a=a/10;
	 b=a%10;
	 c=c|b<<4;
	 return c;
}

void uart(void) interrupt 4  //把接收到的数据写入ucReceiveData()
{
   TI=0;
   RI=0;
   if(SBUF=='H')	//接收到'H'字符 发送'OK'
   {
	   SBUF='O';
        while(TI==0)
		   ;
        TI=0; 
		SBUF='K';
        while(TI==0)
		   ;
        TI=0;
   }
   else if(SBUF=='R')	//接收到0
   {
	   count=1;
   }
   else if(SBUF=='S')
   {
	   count=0;
   }
   else if(SBUF=='A')
   {
	   LIGHT1=1;
	   BUZZER=1;
   } 
   else if(SBUF=='B')
   {
	   LIGHT1=0;
	   BUZZER=0;
   } 
   else if(SBUF=='C')
   {
	   LIGHT2=1;
	   BUZZER=1;
   } 
   else if(SBUF=='D')
   {
	   LIGHT2=0;
	   BUZZER=0;
   }
}

/**************************数码管显示函数**************************/
/*函数原型:void display(void)
/*函数功能:数码管显示
/*输入参数:无
/*输出参数:无
/*调用模块:delay()
/******************************************************************/ 
void display(unsigned int temp)
{	
	bit b=P_K_L;
	P_K_L=1;	//防止按键干扰显示
   
	P_data=tab[temp&0x0f];	//显示个位
	PS0=0;		 
	PS1=1;						   
	PS2=1;		 
	PS3=1;
	delay(200);
   
 	P_data=tab[(temp>>4)&0x0f]; //显示十位
	PS0=1;		 
	PS1=0;						   
	PS2=1;		 
	PS3=1;
	delay(200);	
   
	P_data=tab[(temp>>8)&0x0f];	//显示百位
	PS0=1;		 
	PS1=1;						   
	PS2=0;		 
	PS3=1;
	delay(200);
   
 	P_data=tab[(temp>>12)&0x0f]; //显示千位
	PS0=1;		 
	PS1=1;						   
	PS2=1;		 
	PS3=0;
	delay(200);
	PS3=1;	

	P_K_L=b;		//恢复按键
	P_data=0xff;	//恢复数据口
}



void main(void)
{    
    TMOD=0x20;           //定时器1--方式2 
/*  GATE C/T M1 M0 GATE C/T M1 M0
      0   0   1  0   0   0   0  0
      |   |   |  |   |   |   |  +----方式选择
  	  |   |   |  |   |   |   +-------方式选择
	  |   |   |  |   |   +-----------定时器0或计数器0选择位 清零时用作定时器功能 置位时用作计数器功能
	  |   |   |  |   +---------------置位时为门控位
	  |   |   |  +-------------------方式选择
	  |   |   +----------------------方式选择
	  |   +--------------------------定时器1或计数器1选择位	清零时用作定时器功能 置位时用作计数器功能
	  +------------------------------置位时为门控位*/
    IE=0x12;             //中断控制设置,串口、T2开中断
/*  EA - ET2 ES ET1 EX1 ET0 EX0  
     0 0  0   1  0   0   1   0
     | |  |   |  |   |   |   +-------外部中断0 使能。 
     | |  |   |  |   |   +-----------定时器0 溢出中断使能。
	 | |  |   |  |   +---------------外部中断1 使能。
	 | |  |   |  +-------------------定时器1 溢出中断使能。
	 | |  |   +----------------------串口中断使能。
	 | |  +--------------------------定时器2 中断使能。
	 | +-----------------------------
	 +-------------------------------中断使能位:EA=1,允许中断服务;EA=0,禁能中断服务。*/
    PCON=0x80;           //电源控制
/*  SMOD SMODO - POF GF1 GF0 PD IDL 
      1    0   0  0   0   0   0  0
	  |    |   |  |   |   |   |  +---
	  |    |   |  |   |   |   +------
	  |    |   |  |   |   +----------
	  |    |   |  |   +--------------
	  |    |   |  +------------------
	  |    |   +---------------------
	  |    +-------------------------
	  +------------------------------*/
    SCON=0x50;           //方式1
/*  SM0/FE SM1 SM2 REN TB8 RB8 TI RI
       0    1   0   1   0   0   0  0
	   |    |   |   |   |   |   |  +-接收中断标志
	   |    |   |   |   |   |   +----发送中断标志
	   |    |   |   |   |   +--------模式2 和3 中接收的第9 位数据,在模式1 中(SM2 必须为0),RB8 是接收到的停止位。在模式0 中,RB8 未定义。
	   |    |   |   |   +------------模式2 和3 中将要发送的第9 位数据,可以根据需要由软件置位或清零。
	   |    |   |   +----------------使能串行接收
	   |    |   +--------------------使能模式2 和3 中的多机通信功能。
	   |    +------------------------和SM0 定义串行口操作模式
	   +-----------------------------该位的用途由PCON 寄存器中的SMOD0 决定。*/
    TL1=0xFa;//0xF4;            //12MHZ晶振,波特率为4800 0xf3   4800  
    TH1=0xFa;//0xF4;            //11.0592MHZ晶振,波特率为4800 0xf4   9600	0xfa   19200 0xfd 
    TR1=1;               //启动定时		   
      ES=1;
    EA=1;
      LIGHT1=1;
      LIGHT2=1;
      COUNTER=0;
    while(1)
    {  
	    unsigned char i;
	    for(i=0;i<50;i++)
	        display(htd(COUNTER));
	    if(count)
	        COUNTER++;
	    if(COUNTER>10)
	        COUNTER=0;
    }
}

3、运行结果


猜你喜欢

转载自blog.csdn.net/liyuqian199695/article/details/65944603