0 卖盘信息
BOM询价
您现在的位置: 首页 > 技术方案 >通信与网络 > 基于PIC单片机PIC16F877与PC机实现串行通信的设计方案

基于PIC单片机PIC16F877与PC机实现串行通信的设计方案

来源: elecfans
2022-07-28
类别:通信与网络
eye 32
文章创建人 拍明芯城

原标题:PIC单片机与PC机实现串行通信的设计方案

  1. 实例目的:

  本实例完全建立在计算机软件的基础上,利用PROTEUS软件构建一个单片机系统,利用VB编写一个计算机控制软件和单片机系统串行通信,计算机上的控制软件可以发送一个值在0——999之间的数,在单片机系统上显示出来,单片机系统上也可输入一个相同值域的数并在计算机控制软件上显示出来。本实例主要是为了展示虚拟串行通信的仿真。

  2. 系统配置

  本实例虽然简单,但是要想看到想要的仿真结果,建立虚拟的串口连接是必不可少的。要想仿真串行通信,必须要把单片机系统上的串行口与计算机上的串行口连接,这样他们之间才能传输数据,但由于是仿真,实际没有相连接,所以需要创建一对虚拟串行口并使他们相连,这里我使用的是这个软件Virtual Serial Ports Driver XP 5.1(VSPD XP),打开后的界面如图1所示。在右面“ADD PAIR”按钮的旁边的下拉选项中一个选择“COM3”,一个选择

  

<a target=PIC单片机与PC机实现串行通信的设计" src="https://supp.iczoom.com/images/public/202207/1658994812335044310.png" width="489" height="301"/>


  “COM4”,然后点击“ADD PAIR”按钮,这样就完成了虚拟串口“COM3”和“COM4”的连接,完成后如图1所示。简单吧?!

  另外,你还要选择一个串口调试软件作为你的调试软件,因为当你单片机系统弄完以后而计算机上的控制软件还没有编时,没有串口调试软件的话,你就没法知道你单片机系统正确与否。这种软件网上多如牛毛,随便找一个。我的软件为SSCOM32,界面如图2所示。

  

image.png


  功能与用法这里就不一一介绍了,反正既能接收又能发送,实例需要的功能他都可以调试。

  3.单片机系统

  单片机硬件:

  电路如图3所示。

  本实例采用的单片机依然是PIC16F877,他含有UASRT模块,有了它才能进行串行通信。显示部分采用3位数码管共阳输出。键盘采用矩阵键盘。这里需要特别说明的是,由于是仿真,没有采用电平转换芯片MAX232将TTL电平转换成RS232的电平,实际这一步是必需的。串行口的设置需要特别注意,由于本实例单片机程序中设置的波特率是9600,8位数据,无奇偶校验,所以串行口也要一样设置,这里由于建立的是“COM3”“COM4”之间的虚拟连接,端口号一定要设置成“COM3”或“COM4”,这是关键!如图4所示。

  

image.png


  单片机软件:

  单片机软件主要由以下几个部分组成:初始化程序,显示程序,键盘输入程序,串行接收程序,串行发送程序。

  程序采用C语言,简单明了,经过PICC编译通过。

  全部程序如下:

  #include

  //预定义

  #define uch unsigned char

  //显示用码表

  const uch shu[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x98,0xff};

  //变量

  int data,temp1,temp2,temp3,temp;

  uch flag,keylock;

  uch point,buffer[3];

  //初始化

  void init()

  {

  TRISB=0;

  PORTB=0;

  TRISC=0;

  PORTC=0;

  keylock=1;//初始化键盘按键标志位,用于锁定按键

  //USART部件初始化

  SPBRG=0x19;//设置波特率为9600bps

  TXSTA=0x04;//选择异步高速8位数据传输模式

  RCSTA=0x80;//允许串行端口工作

  TRISC=0x80;//设置为高阻态,防止干扰

  TXEN=1;//发送允许

  CREN=1;//接收允许

  PEIE=1; //开放外设中断

  RCIE=1; //开放串行口中断

  ei(); //开放总中断

  }

  //显示需要的延时

  void delay()

  {

  int i;

  for(i=0;i《1000;i++);

  }

  //发送子程序

  void send_usart()

  {

  uch i;

  for(i=0;i《3;i++)//每次发3个数据

  {

  if(i==0)TXREG=data/100+0x30;//求得百位

  if(i==1)TXREG=data%100/10+0x30; //求得十位

  if(i==2)TXREG=data%10+0x30; //求得个位

  while(1)

  {

  if(TXIF==1)break;//等待发送完成

  }

  }

  }

  //中断接收子程序

  void interrupt receive(void)

  {

  if(point《3)//是否已经接收到3个数据

  buffer[point++]=RCREG-48;//没有,继续接收

  else point=0;//是,指针复位

  data=buffer[0]*100+buffer[1]*10+buffer[2];//组合成三位数

  }

  //数码管显示

  void display(int dis_data)

  {

  int dis_data_ge,dis_data_shi,dis_data_bai;

  dis_data_ge =dis_data%10;//个位

  dis_data_shi=dis_data%100/10;//十位

  dis_data_bai=dis_data/100; //百位

  if(dis_data==0)//若数据为0,只显示1位

  {

  dis_data_ge=0;

  dis_data_shi=10;

  dis_data_bai=10;

  }

  if(dis_data《10)//若数据小于10,则十位与百位关闭显示

  {

  dis_data_shi=10;

  dis_data_bai=10;

  }

  if(dis_data《100)//若数据小于100,则只显示两位

  {

  dis_data_bai=10;

  }

  RC0=0;

  RC1=0;

  RC2=1;

  PORTB=shu[dis_data_ge];//个位送显

  delay();

  RC0=0;

  RC2=0;

  RC1=1;

  PORTB=shu[dis_data_shi];//十位送显

  delay();

  RC1=0;

  RC2=0;

  RC0=1;

  PORTB=shu[dis_data_bai];//百位送显

  delay();

  }

  //键盘(线反转法)

  void presskey()

  {

  uch line,column,key;

  TRISD=0x07;

  PORTD=0xf0;

  column=PORTD & 0x07;//取列码

  TRISD=0xf0;

  PORTD=0x0f;

  line=PORTD&0xf0;//取行码

  key=line|column;//合成键值

  if(key==0)keylock=0;//保证每次只按一次键

  if(keylock==0)

  {

  if(key!=0)keylock=1;

  switch(key)//查找键值

  {

  case 0x11:temp=3;flag++;break;

  case 0x12:temp=2;flag++;break;

  case 0x14:temp=1;flag++;break;

  case 0x21:temp=4;flag++;break;

  case 0x22:temp=5;flag++;break;

  case 0x24:temp=6;flag++;break;

  case 0x41:temp=9;flag++;break;

  case 0x42:temp=8;flag++;break;

  case 0x44:temp=7;flag++;break;

  case 0x82:temp=0;flag++;break;

  case 0x81:flag=4;send_usart();break;//发送

  case 0x84:flag=0;data=0;break;//清零键

  }

  }

  if(flag==1)//第一次按键

  {

  if(temp==0)flag=0;//若按0,则忽略

  temp1=temp;

  data=temp1;

  }

  if(flag==2)//第二次按键

  {

  temp2=temp;

  data=temp1*10+temp2;//原来的个位变成十位

  }

  if(flag==3)//第三次按键

  {

  temp3=temp;

  data=temp1*100+temp2*10+temp3;//原来的十位变成百位

  flag=4;//屏蔽按键

  }

  }

  //主程序

  main()

  {

  init();

  while(1)

  {

  presskey();

  display(data);

  }

  }

  4. 计算机控制软件

  上位机软件是用VB编写的,功能很简单,主要有发送和接收两个功能。软件的界面如图5所示。

  

image.png


  软件主要有2个“TextBox”,3个按钮,和一些文本控件组成。

  现把所有程序都贴出来:

  Private Sub Cmdquit_Click()

  i = MsgBox(“您要离开吗?”, vbQuesTIon Or vbYesNo, “温馨提示”)

  If i = 6 Then

  Shell “explorer.exe http://blog.163.com/wujieflash”

  End

  End If

  End Sub

  Private Sub Cmdsend_Click()

  If Len(Text1.Text) = 1 Then MSComm1.Output = “0” + “0” + Text1.Text ‘不满3位补足3位再发送

  If Len(Text1.Text) = 2 Then MSComm1.Output = “0” + Text1.Text

  If Len(Text1.Text) = 3 Then MSComm1.Output = Text1.Text

  End Sub

  Private Sub cmdzero_Click()

  Text2.Text = “”

  Text1.Text = “”

  End Sub

  Private Sub Form_Load()

  MSComm1.SetTIngs = “9600,n,8,1” ’设置数据传输率和发送字符格式

  MSComm1.CommPort = 4 ‘设置通讯串口为4

  MSComm1.InputLen = 0 ’设置或返回一次从接受缓冲器中读取所有字节数

  MSComm1.InBufferSize = 512 ‘设置接收缓冲区512BYTE

  MSComm1.InBufferCount = 0

  MSComm1.OutBufferSize = 512 ’设置发送缓冲区512BYTE

  MSComm1.OutBufferCount = 0

  MSComm1.RThreshold = 3 ‘每3个字符到接收缓冲区都触发接收事件

  MSComm1.SThreshold = 1

  MSComm1.PortOpen = True

  End Sub

  Private Sub Label6_Click()

  Shell “explorer.exe http://blog.163.com/wujieflash” ’我博客的超连接,多多捧场

  End Sub

  Private Sub MSComm1_OnComm()

  Text2.Text = MSComm1.Input

  End Sub

  Private Sub Text1_KeyPress(KeyAscii As Integer)

  If KeyAscii 《 Asc(“0”) Or KeyAscii 》 Asc(“9”) Then

  KeyAscii = 0

  MsgBox (“请输入数字字符!”)

  End If

  End Sub

  软件是简单了点,但功能却齐全的。

  5. 总结

  这次搞得这个实例仿真的确有点麻烦,不过的确能了解很多关于这串行通信方面的知识,经过自己亲自动手实现,感觉也是蛮不错的。


责任编辑:David

【免责声明】

1、本文内容、数据、图表等来源于网络引用或其他公开资料,版权归属原作者、原发表出处。若版权所有方对本文的引用持有异议,请联系拍明芯城(marketing@iczoom.com),本方将及时处理。

2、本文的引用仅供读者交流学习使用,不涉及商业目的。

3、本文内容仅代表作者观点,拍明芯城不对内容的准确性、可靠性或完整性提供明示或暗示的保证。读者阅读本文后做出的决定或行为,是基于自主意愿和独立判断做出的,请读者明确相关结果。

4、如需转载本方拥有版权的文章,请联系拍明芯城(marketing@iczoom.com)注明“转载原因”。未经允许私自转载拍明芯城将保留追究其法律责任的权利。

拍明芯城拥有对此声明的最终解释权。

相关资讯

方案推荐
基于MC33771主控芯片的新能源锂电池管理系统解决方案

基于MC33771主控芯片的新能源锂电池管理系统解决方案

AMIC110 32位Sitara ARM MCU开发方案

AMIC110 32位Sitara ARM MCU开发方案

基于AMIC110多协议可编程工业通信处理器的32位Sitara ARM MCU开发方案

基于AMIC110多协议可编程工业通信处理器的32位Sitara ARM MCU开发方案

基于展讯SC9820超低成本LTE芯片平台的儿童智能手表解决方案

基于展讯SC9820超低成本LTE芯片平台的儿童智能手表解决方案

基于TI公司的AM437x双照相机参考设计

基于TI公司的AM437x双照相机参考设计

基于MTK6580芯片的W2智能手表解决方案

基于MTK6580芯片的W2智能手表解决方案