一、串口

1.1串口基本认知

串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信式的扩展接口。串行接口(Serial Interface)是指数据一位一位地顺序传送。其特点是通信线路单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了本,特别适用于远距离通信,但传送速度较慢
小结:
1).是设备间接线通讯的一种方式
2).数据是一位一位的传输
3).双向全双工通讯
4).传输速度相对较慢

1.2串口标准与协议

串行接口常用接口有RS-232、RS-422、RS-485接口

**RS-232**
由于RS-232其发送电平与接收电平的差仅为2V至3V左右,所以其共模抑制能力差,再加上双绞线上的分布电容,其传送距离最大为约15米,最高速率为20kb/s。RS-232是为点对点(即只用一对收、发设备)通讯而设计的,其驱动器负载为3~7kΩ。所以RS-232适合本地设备之间的通信。
**RS-422**
典型的RS-422是四线接口。实际上还有一根信号地线,共5根线。其DB9连接器引脚定义。由于接收器采用高输入阻抗和发送驱动器比RS232更强的驱动能力,故允许在相同传输线上连接多个接收节点,最多可接10个节点。即一个主设备(Master),其余为从设备(Salve),从设备之间不能通信,所以RS-422支持点对多的双向通信。
RS-422的最大传输距离为1219米,最大传输速率为10Mb/s。其平衡双绞线的长度与传输速率成反比,在100kb/s速率以下,才可能达到最大传输距离。只有在很短的距离下才能获得最高速率传输。一般100米长的双绞线上所能获得的最大传输速率仅为1Mb/s。
RS-422需要一终接电阻,要求其阻值约等于传输电缆的特性阻抗。在短距离传输时可不需终接电阻,即一般在300米以下不需终接电阻。终接电阻接在传输电缆的最远端。

**RS-485**

由于RS-485是从RS-422基础上发展而来的,所以RS-485许多电气规定与RS-422相仿。如都采用平衡传输方式、都需要在传输线上接终接电阻等。RS-485可以采用二线与四线方式,二线制可实现真正的多点双向通信,而采用四线连接时,与RS-422一样只能实现点对多的通信,即只能有一个主(Master)设备,其余为从设备,但它比RS-422有改进, 无论四线还是二线连接方式总线上可多接到32个设备。
RS-485与RS-422的不同还在于其共模输出电压是不同的,RS-485是-7V至+12V之间,而RS-422在-7V至+7V之间,RS-485接收器最小输入阻抗为12k剑 鳵S-422是4k健; 旧峡梢运礴S-485满足所有RS-422的规范,所以RS-485的驱动器可以用在RS-422网络中应用。
RS-485与RS-422一样,其最大传输距离约为1219米,最大传输速率为10Mb/s。平衡双绞线的长度与传输速率成反比,在100kb/s速率以下,才可能使用规定最长的电缆长度。只有在很短的距离下才能获得最高速率传输。一般100米长双绞线最大传输速率仅为1Mb/s
RS-485需要2个终接电阻,其阻值要求等于传输电缆的特性阻抗。在短距离传输时可不需终接电阻,即一般在300米以下不需终接电阻。终接电阻接在传输总线的两端。

 1.3接口电平

RS-232电平
逻辑1的电平为-3~-15V,逻辑0的电平为+3~+15V,注意电平的定义反相了一次
TTL电平
+5V等价于逻辑“1”,0V等价于逻辑“0”(采用二进制来表示数据时)。
输出高电平>=2.4V,输出低电平<=0.4V;
输入高电平>=2.0V,输入低电平<=0.8V

1.4串口通讯接线

**两个芯片之间的通讯**

 芯片与计算机串口连接


二、串口配置与基础印象

2.1基础印象

对于输入输出的数据需要先传送到SBUF寄存器中

想要接收数据

char datas= = SBUF;

想要发送数据

SBUF = datas

2.2串口配置与工作模式

2.2.1:串行口相关寄存器

2.2.2:串行口控制器SCON与PCON

串行口控制器SCON:可寻址位

SFR name address b7 b6 b5 b4 b3 b2 b1 b0
SCON 98H SM0/FE SM1 SM2 REN TB8 RB8 TI RI

SM0与SM1组合之后的工作方式

REN:允许/禁止串行接口接收控制位,由软件控制,即当REN=1时,则为允许接收,可启动RxD,开始接收消息,反之则禁止接收

TI:发送请求中断标志位。当发送的8位数据结束之后,硬件内部自动置位,TI=1,向主机发送中断请求,相应中断之后必须用软件进行复位,即TI=0。

RI:接收请求中断标志位。当接收的8位数据结束之后,硬件内部自动置位,RI=1,向主机发送中断请求,相应中断之后必须用软件进行复位,即RI=0。

串行口控制器PCON:不可寻址位

SFR name address b7 b6 b5 b4 b3 b2 b1 b0
PCON 87H SMOD SMOD0 - POF GF1 GF0 PD IDL

SMOD:波特率选择。当软件进行置位后,即SMOD = 1,则串行通讯方式1,2,3比特率加倍;当SMOD=0,则各个工作方式的波特率加倍。

 2.2.3:串行口中断控制器

中断允许寄存器IE(可寻址位)

SFR name address b7 b6 b5 b4 b3 b2 b1 b0
IE A8H EA - ET2 ES ET1 EX1 ET0 EX0

EA:CPU总中断控制,EA=1,CPU开放中断,EA=0,CPU停止中断;在各个中断中,首先有EA控制,然后在由自己中断进行控制

ES:串口中断允许标志,ES =1,允许中断;ES=0,禁止中断

三.串口配置方式

配置串口要求:晶振频率11.0592Mhz,波特率为9600,选择串口UART1,工作方式配置为1,允许串行接收控制,允许接收与发送中断标志位

SCON位 :0   1    0    1    0    0    1    1

PCON位: 0   1    0    1    0    0    0    0

由波特率计算出定时器初始值:设定时器的初始值为“X”

解出X = 3,定时器溢出率=10#253=16#FD

代码实现

void UartInit(void)      //9600bps@11.0592MHz
{PCON &= 0x7F;     //波特率不倍速SCON = 0x50;       //8位数据,可变波特率AUXR &= 0xBF;      //定时器1时钟为Fosc/12,即12TAUXR &= 0xFE;     //串口1选择定时器1为波特率发生器TMOD &= 0x0F;        //清除定时器1模式位TMOD |= 0x20;       //设定定时器1为8位自动重装方式TL1 = 0xFD;       //设定定时初值TH1 = 0xFD;        //设定定时器重装值ET1 = 0;     //禁止定时器1中断TR1 = 1;     //启动定时器1
}

四.程序练习

1.通过串口向电脑每次间隔一秒发送一个字符“A”

#include <reg52.h>
#include "intrins.h"
sfr AUXR = 0x8E;
/*配置C51串口的通信方式*/
void UartInit(void)     //9600bps@11.0592MHz
{AUXR = 0x01;SCON = 0x40; //配置串口工作方式1,REN不使能接收TMOD &= 0xF0;TMOD |= 0x20;//定时器1工作方式位8位自动重装TH1 = 0xFD;TL1 = 0xFD;//9600波特率的初值TR1 = 1;//启动定时器
}void Delay1000ms()     //@11.0592MHz
{unsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do{do{while (--k);} while (--j);} while (--i);
}void main()
{char data_msg = 'a';  //data_msg为内部数据参数,并给定数据字符“a“UartInit();while(1){Delay1000ms();//往发送缓冲区写入数据,就完成数据的发送SBUF = data_msg;}
}

2.通过串口向电脑每次间隔一秒发送字符

#include <REGX52.H>
#include "intrins.h"
/*配置C51串口的通信方式*/
void UartInit()     //9600bps@11.0592MHz
{AUXR = 0x01;SCON = 0x40; //配置串口工作方式1,REN不使能接收TMOD &= 0xF0;TMOD |= 0x20;//定时器1工作方式位8位自动重装TH1 = 0xFD;TL1 = 0xFD;//9600波特率的初值TR1 = 1;//启动定时器
}
void Delay1000ms()      //@11.0592MHz
{unsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do{do{while (--k);} while (--j);} while (--i);
}
/*由于SBUF是8位为一组,因此需要建立一个字节发送函数,以发送相应的字节
形式参数:datas,用于承接发送的实际内容*/
void sendbyte(char datas)
{SBUF  = datas;while(TI == 0);  //当发送数据的时候,TI=0,这时while循环满足,不执行下面的程序,当TI=1时,while循环不满足,执行下面的程序:复位TITI = 0;
}
/*发送字符串函数
形式参数:char型字符*/
void sendstring(char* str)
{sendbyte(*str);while(*str !='\0'){sendbyte(*str);str++;}      //当字符串没有结尾的时候,则要调用sendbyte函数,进行函数的发送
}
void main()
{UartInit();while(1){Delay1000ms();sendstring("youare handsome\r\n")  //向sendstring形式参数中传输实际参数}
}

3.通过串口接收到的数据控制指示灯亮灭

#include <REGX52.H>
#include <intrins.h>
sbit LED = P2^0;
void UartInit()
{PCON &= 0x7F; SCON = 0x50;   TMOD &= 0x0F;  TMOD |= 0x20;  TL1 = 0xFD;        TH1 = 0xFD;        ET1 = 0;       TR1 = 1;
}
void Delay1000ms()
{unsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do{do{while (--k);} while (--j);} while (--i);
}
/*void sendbyte(char datas)
{SBUF = datas;while(TI == 0);TI=0;
}
void sendstring(char *str)
{while(*str !='\0'){sendbyte(*str)str++;}
}
*/
void main()
{char cmd;LED = 0;   //LED指示灯初始化为熄灭状态UartInit();while(1){Delay1000ms();RI = 0;        //当接收到数据完成之后,RI=0cmd = SBUF;   //当RI=0之后,将SBUF中的数据读取到cmd中/*当读取到的字符为“O”时,点亮LED;当读取到字符为“C”时,熄灭LED*/if(cmd = 'O'){LED = 0;}if(cmd = 'C'){LED = 1;}}}

经过测试,这段代码没有功能上的问题,但是会存在一定的延迟

4.通过串口中断的方法控制LED指示灯

中断优先级

#include "reg52.h"
#include "intrins.h"
sbit D5 = P3^7;
char cmd;void UartInit(void)
{SCON = 0x50; TMOD &= 0xF0;TMOD |= 0x20;TH1 = 0xFD;TL1 = 0xFD;TR1 = 1;EA = 1;ES = 1;
}void Delay1000ms()     //@11.0592MHz
{unsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do{do{while (--k);} while (--j);} while (--i);
}
/*
void sendByte(char data_msg)
{SBUF = data_msg;while(!TI);TI = 0;
}void sendString(char* str)
{while( *str != '\0'){sendByte(*str);str++;}
}
*/
void main()
{D5 = 1;//配置C51串口的通信方式UartInit();while(1){Delay1000ms();//往发送缓冲区写入数据,就完成数据的发送/*sendString("chenlichen shuai\r\n");*/}
}void Uart_Handler() interrupt 4
{if(RI)//中断处理函数中,对于接收中断的响应{RI = 0;//清除接收中断标志位cmd = SBUF;if(cmd == 1){D5 = 0;//点亮D5}if(cmd == 0){D5 = 1;//熄灭D5}}if(TI);
}

5.通过发送字符方式控制指示灯

#include "reg52.h"
#include "intrins.h"
#include <string.h>#define SIZE 12
sbit D5 = P3^7;
char cmd[SIZE];void UartInit(void)
{SCON = 0x50; TMOD &= 0xF0;TMOD |= 0x20;TH1 = 0xFD;TL1 = 0xFD;TR1 = 1;EA = 1;ES = 1;
}void Delay1000ms()
{unsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do{do{while (--k);} while (--j);} while (--i);
}
/*
void sendByte(char data_msg)
{SBUF = data_msg;while(!TI);TI = 0;
}void sendString(char* str)
{while( *str != '\0'){sendByte(*str);str++;}
}
*/
void main()
{D5 = 1;//配置C51串口的通信方式UartInit();while(1){Delay1000ms();//往发送缓冲区写入数据,就完成数据的发送sendString("chenlichen shuai\r\n");}
}void Uart_Handler() interrupt 4
{static int i = 0;//定义字符串的指针,静态变量,被初始化一次if(RI)//中断处理函数中,对于接收中断的响应{RI = 0;//清除接收中断标志位cmd[i] = SBUF; //将SBUF中的数据读取到cmd中i++;  //将指针进行右移if(i == SIZE){i = 0;}  //当移动到最后一位时,将指针移动到首位if(strstr(cmd,"en")){D5 = 0;//点亮D5i = 0;memset(cmd,'\0',SIZE);}  //当接收到字符中有‘en’(open),启动LED,同时将cmd中数据清空if(strstr(cmd,"cl")){D5 = 1;//熄灭D5i = 0;memset(cmd,'\0',SIZE);}  //当接收到字符中有‘cl’(close),关闭LED,同时将cmd中数据清空}if(TI);
}

单片机的串口通讯编程相关推荐

  1. ABOV单片机UART串口通讯实现讲解及示例代码-[MC96F6332D]

    一.准备工作 1.KEIL C51编译环境 2.CodeGen8 代码生成器 3.MC96F6332D 开发板 4.USB-OCD II仿真器 二.生成串口通讯代码 1.在CodeGen8 代码生成器 ...

  2. c语言stm32串口控制单片机,基于STM32F103C8T6单片机电脑串口通讯控灯设计(原理图+程序+论文)...

    题目:基于STM32F103C8T6单片机电脑串口通讯控灯设计 内容要求: 一. 任务 通信是指不同的独立系统利用线路互相交换数据,它的主要目的是将数据从一端传送到另一端,实现数据的交换.在现代工业控 ...

  3. 串口通讯编程一日通1(整合资料) .

    本文以VC++为平台进行串口通信编程 串口通讯在VC++下实现方式有很多,控件自然是最简单话的方式了,但由于控件只支持对话框程序,有些场合又不需要对话框,所以用Windows API实现是比较好的方式 ...

  4. plc.单片机的串口通讯的调试方法——通过虚拟串口工具和串口助手来调试串口

    加一个,串口助手和虚拟串口工具统合使用的链接,可以一起看哦~https://blog.csdn.net/qq_32278309/article/details/101384003 博主是新入坑的新人, ...

  5. 51单片机之串口通讯应用实例(逻辑分析仪调试)

    硬件:STC89C52RC 开发工具:Keil uVision4 前言:8051是一款很经典的.历史悠久的单片机,作为一款入门级的单片机8051受到很多初学者的欢迎.89c52是8051系列的成员之一 ...

  6. DELPHI串口通讯编程

    spcomm更加简单     转贴     Delphi中串口通信的实现         河南省计算中心   张海航           ------------------------------- ...

  7. 串口通讯编程一日通3(COMMTIMEOUTS DCB整理)

    上一篇看了Overlapped IO模型后,接下来看剩下两个重要结构:  2.COMMTIMEOUTS结构 超时设置 COMMTIMEOUTS:COMMTIMEOUTS主要用于串口超时参数设置.COM ...

  8. 21 树莓派和电脑之间串口通讯编程

    linux特性:一切皆文件(设备虽然是硬件,但在Linux当中它还是以文件形式存在) 在cd/dev目录下ls 初次使用树莓派串口编程,需要配置. 参考:树莓派wiringPi库详解 - lulipr ...

  9. 51单片机——UART串口通讯-波特率可选,增添定时器2产生波特率1.0

    1.51单片机自带硬件串口接口,使用时只需要进行寄存器配置即可. 2.定时器1波特率有4种可选择,默认9600bps.另外还有1个字节的发送函数,字符串发送函数. 3.增添:定时器2波特率有5种可选择 ...

最新文章

  1. C语言的HashTable简单实现
  2. vue仿今日头条_vue2.0仿今日头条开源项目
  3. 尝试优化骨骼动画计算的意外收获——使用嵌入式汇编对float转int进行优化
  4. 神策 FM | 数据驱动时代,你的岗位如何转变?
  5. JAVA Socket 底层是怎样基于TCP/IP 实现的???
  6. suse10 linux安装,SuSE10.2 安装手记
  7. Log4j(1)--hellloworld
  8. BUPT复试专题—C翻转(2010)
  9. nginx 配置文件详解 深入理解nginx配置文件
  10. jsp数据库连接大全和数据库操作封装到Javabean
  11. 找回foxmail下的邮箱密码
  12. 推荐系统 AB 测试
  13. 数据集中趋势度量:众数、平均数、中位数、几何平均数
  14. linux下搜狗输入法wps无法使用,搜狗输入法能在WPS下使用,但其他地方不能输入...
  15. html桌面共享文件夹,win7共享文件夹在哪? win7和win10怎么共享文件夹
  16. 转载 2015A国赛优秀论文
  17. Axure9的使用经验分享:如何高效的实现弹窗交互模型
  18. 计算机usb无法识别网络连接,usb无法识别是什么原因 usb无法识别解决方法【详解】...
  19. 【软件工程实践】Hive研究-Blog7
  20. 高速信号的完整性分析

热门文章

  1. drupal 用的什么php框架,7个使用Drupal的理由
  2. OBJ2GLTF使用,将obj格式模型转换为gltf
  3. latch和DFF的区别和联系
  4. 神器 Markmap
  5. 毕夏钟伟强沧桑战全场泪奔
  6. Android头像上传实战模拟
  7. Docker Swarm Could not attach to network not manually attachable.
  8. 360手机助手 无法android 4.2手机软件移动sd卡,360手机助手怎么设置安装到sd卡 360手机助手设置安装位置...
  9. MAC电脑 安全与隐私 中没有任何来源选项怎么办
  10. SyntaxHighlighter示例源码[代码高亮]