0 卖盘信息
BOM询价
您现在的位置: 首页 > 电子资讯 >基础知识 > 串口通信原理

串口通信原理

2017-11-10
类别:基础知识
eye 334
文章创建人 拍明
  串口是学习单片机重要的一项,用来显示数据和一些简单的控制命令非常方便,经过笔者这几天的测试,总结出了一些需要注意的地方:(以下代码全部基于单片机STM32F407实现)

  1、关于发送

  除非你勾选了串口调试工具里面的HXE(16进制),否则串口发送的是对应字符的ASCII码,也就是说接收的是每一位都是一个字节的ASCII码。比如说通过串口发送内容:adc123,其实发送的它们对应的ASCII码:61H 62H 63H 31H 32H 33H(H表示16进制)。如果发送勾选了“发送新行”,就会在发送的内容后面添加0DH 0AH(换行符),添加了两个字节。

  在单片机编程中,如果用指针定义了一个无变量名的字符串:char *str=”abc123”;系统会自动在该变量后面添加一个‘’表示字符串的结束,这样改字符串共占了7个字节。基于这个原因,发送字符串时可以采用下函数实现:

  void usartSendString(u8 *str)

  {

  while(*str != 0)

  {

  while((USART3->SR&0x40)==0); //等待发送缓冲器空

  USART_SendData(USART3,*str); //发送字符

  str++;

  }

  而不是采用大多数采用的函数:

  void uart3SendChars(u8 *str, u16 strlen)

  {

  u16 k= 0 ;

  do {uart3SendChar(*(str + k)); k++; }

  while (k < strlen);

  }

  比较以上两个函数,可以发现第一个函数入口参数少了要发送字符串的字长,第一个函数可以实现自动计算字长。当然,第一个函数仅能实现对字符串的发送,并不能实现对数组的发送。

串口通信原理.png

  2、关于接收

  相信大多数人都曾想实现将串口接收的内容在LCD上显示,一个非常简便的办法就是在串口接收中断中直接将接收到的字符显示在LCD上,但是由于刷新LCD需要较长的时间,在发送了一长串字符串后,很容易由于刷新LCD需要较长的时间而导致接收到的内容不全。笔者想出了一个比较巧妙的函数,可以解决这样的烦恼:

  #define USART3_REC_NUM 100 //定义最大接收字节数

  u8 receive_str[USART3_REC_NUM] = {0}; //接收缓存数组

  u16 uart_byte_count=0; //接收的字节数

  //串口中断函数

  void USART3_IRQHandler(void)

  {

  u8 rec_data;

  if(USART_GetITStatus(USART3,USART_IT_RXNE) != RESET)

  {

  rec_data=(u8)USART_ReceiveData(USART3); //接收内容

  receive_str[uart_byte_count]=rec_data;//将接收到的内容存放在数组中

  uart_byte_count++; //接收的字节数+1

  }

  }

  //将串口接收到的数据拷贝出来,拷贝出来的字符串末尾保留了换行符'x0d' 'x0a'

  u8 USART_Receive2Str(u8 *str)

  {

  u16 i;

  if(receive_str[uart_byte_count-1]== 0x0a) //接收到换行符

  {

  for(i=0;i

  {

  *(str+i) =receive_str; //将数据拷贝出来

  receive_str=0; //将接收缓冲数组清零

  }

  uart_byte_count=0;

  return 1; //成功拷贝到数据

  }

  else return 0; //拷贝数据失败

  }

  这样就将数组中的内容拷贝到其他数组中,进行相应的处理。但是要特别注意的是,要想使用以上函数,必须在串口调试工具中勾选“发送新行”才能实现,并且拷贝出来的字符串末尾保留了换行符'x0d' 'x0a'。要想实现控制,可以使用下列方式:

  u8 str[20]; //最多能拷贝出来20个字符

  if(USART_Receive2Str(str) == 1)

  {

  if(strcmp("Light_led1x0dx0a",(char*)str)==0) LED1=0;//点亮LED1

  elseif(strcmp("Close_led1x0dx0a",(char *)str)==0) LED1=1;//关闭LED1

  elseif(strcmp("Open_beepx0dx0a ",(char *)str)==0)BEEP=1; //打开蜂鸣器

  elseif(strcmp("Close_beepx0dx0a ",(char *)str)==0)BEEP=0;//关闭蜂鸣器

  //使用完后一定要将数组清零,方便下一次使用

  u8 i=0;

  while(*(str+i) !=0) /

  {

  *(str+i) = 0;

  i++;

  }

  i=0;

  }

  以下代码实现通过开发板STM32F407实现对WIFI模块8266的控制,每按一次按键就发送一条指令,并将模块返回的信息显示到LCD上:

  //控制指令,末尾的x0dx0a一定要加上,否则8266不能识别指令,相当于勾选了“发送新行”

  char *Ins1 = "AT+RSTx0dx0a";

  char *Ins2 = "AT+CWMODE=1x0dx0a";

  char *Ins3 = "AT+CWLAPx0dx0a";

  char *Ins4 ="AT+CWJAP="DLUTv0","bugaosuniaaa"x0dx0a";

  char *Ins5 ="AT+CIPSTART="TCP","192.168.5.98",8080x0dx0a";

  if(get_key_msg(&keymsg) == 1) //获得按键消息

  {

  static u8 i=0;

  if((keymsg.key == KEY0)&& (keymsg.status == KEY_DOWN))

  {

  switch(i)

  {

  case 0:uart3SendString((u8*)Ins1);i=1;LCD_DisplayString(10,10,16,"SendIns1");break;

  case 1:uart3SendString((u8*)Ins2);i=2;LCD_DisplayString(10,10,16,"SendIns2");break;

  case 2:uart3SendString((u8*)Ins3);i=3;LCD_DisplayString(10,10,16,"SendIns3");break;

  case 3:uart3SendString((u8*)Ins4);i=4;LCD_DisplayString(10,10,16,"SendIns4");break;

  case 4:uart3SendString((u8*)Ins5);i=0;LCD_DisplayString(10,10,16,"SendFinished");break;

  default: break;

  }

  }

  }

  if(USART_Receive2Str(string) ==1)//将模块返回的内容显示在LCD上

  {

  u8 i=0;

  LCD_DisplayString(1,yc,12,string);

  yc+=12;

  if(yc>=320){LCD_Clear(WHITE);yc=50;}

  while(*(str+i) !=0)

  {

  *(str+i) = 0;

  i++;

  }

  i=0;

  }

  1.串口通信原理--简介

  串口通信的概念非常简单,串口通信是指外设和计算机间,通过数据信号线 、地线、控制线等,按位进行传输数据的一种通讯方式。这种通信方式使用的数据线少,在远距离通信中可以节约通信成本,但其传输速度比并行传输低。它很简单并且能够实现远距离通信。比如IEEE488定义并行通行状态时,规定设备线总长不得超过20米,并且任意两个设备间的长度不得超过2米;而对于串口而言,长度可达1200米。

  2.串口通信原理--通信前的准备工作

  在具体操作串口之前需要对单片机的一些与串口有关的特殊功能寄存器进行初始化设置,主要是设置产生波特率的定时器1、串行口控制和中断控制。具体步骤如下:

  1.确定T1的工作方式(编程TMOD寄存器)

  2.计算T1的初值,载入TH1、TL1

  3.启动T1(编程TCON中的TR1位)

  4.确定串行口工作方式(编程SCON寄存器)

  5.串行口工作在中断方式时,要进行中断设置(编程IE,IP)

串口通信原理.png

  3.串口通信原理

  通信使用3根线完成:(1)地线,(2)发送,(3)接收。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其他线用于握手,但是不是必须的。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通信的端口,这些参数必须匹配:

  a,波特率:这是一个衡量通信速度的参数。它表示每秒钟传送的bit的个数。高波特率常常用于放置的很近的仪器间的通信,典型的例子就是GPIB设备的通信。

  b,数据位:这是衡量通信中实际数据位的参数。当计算机发送一个信息包,实际的数据不会是8位的,标准的值是5、7和8位。由于实际数据位取决于通信协议的选取,术语“包”指任何通信的情况。

  c,停止位:用于表示单个包的最后一位。典型的值为1,1.5和2位。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。

  d,奇偶校验位:在串口通信中一种简单的检错方式。有四种检错方式:偶、奇、高和低。对于偶和奇校验的情况,串口会设置校验位,用一个值确保传输的数据有偶个或者奇个逻辑高位。


责任编辑:Davia

【免责声明】

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

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

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

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

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

标签: 串口通信

相关资讯