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

2019-04-15 18:15发布

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 /****************************数码显示 键盘接口定义****************************************/    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、运行结果