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、运行结果
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮