找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 68547|回复: 33
收起左侧

手把手教你单片机串口通信-基础篇

  [复制链接]
ID:285356 发表于 2018-2-25 11:46 | 显示全部楼层 |阅读模式
通信方式
并行
适合短距离通信,并行通信控制简单、相对传输速度快(8位一起传输)。
串行
只能一位一位的传送。
同步(了解)
建立发送方时钟对接收方时钟的直接控制,使双方达到完全同步。此时,传输数据的位之间的距离均为“位间隔”的整数倍,同时传送的字符间不留间隙。
发送方对接收方的同步可以通过外同步和自同步
异步
以字符(构成的帧)为单位进行传输。数据位从低到高传送。
格式:
这里的空闲时间是任意的。
串行通信的制式(传输方向)
单工(仅能沿一个方向)
半双工(可进行双向,但需分时)
全双工
串行通信的错误校验
奇偶校验
在发送数据时,数据位尾随的1位为奇偶校验位(1/0)。奇校验时,数据中1的个数与检验位1的个数之和应为奇数;偶校验时,数据中1的个数与校验位1的个数之和应为偶数。接收字符时,对1的个数进行校验,若字符不一致,则说明传输数据过程中出现错误。
代码和校验
发送方将所发数据块求和(或各字节异或),产生一个字节的校验字符(校验和)附加到数据块末尾。接收方接收数据时,同时对数据块(除校验字节外)求和(或各字节异或),将所得的结果与发送方的“校验和”进行比较,一致则无差。
循环冗余校验
通过某种数学预算实现有效信息与校验位之间的循环校验,常用语对磁盘信息的传输、存储区的完整性校验。
串口的基本结构
SBUF:51单片机中的特殊寄存器,串行数据缓冲器(一个接收一个发送),两个其实是共用的一个地址99H,但是两个在物理上面是分开的。
当发送使用时,就采用SBUF=XXX;  (XXX为需要传送的数据)
当接收使用时,采用XXX=SBUF;
记得因为是串行的所以传输都是一位一位进行的。
T1溢出率:T1计时器的溢出频率(就是计时器每次低位计满向高位进位时间的倒数)
用处:用于计算波特率(每秒传输二进制代码的位数)
实现单片机与电脑之间的互相传送字符串通信代码:
  1.      #include <reg52.h>  
  2.      #include <stdio.h>              //printf头文件  
  3.      #define uc unsigned char   
  4.      #define uint unsigned int  
  5.       
  6.      uc flag,i,flag_t,s[50]="",j=0,flag_n=0;  
  7.      uc code table[]="I get ";         
  8.       
  9.      void init()  
  10. {  
  11.      TMOD=0x20;    //定时器工作方式,选择了定时器1,工作方式2 八位初值自动重装的8位定时器。         
  12.      TH1=0xfd;     //定时器1初值  ,设置波特率为9600 晶振11.0529MHZ?  
  13.      TL1=0xfd;  
  14.      TR1=1;        //开启定时器1  
  15.    
  16.      SM0=0;  
  17.      SM1=1;        //10位异步接收,(8位数据)波特率可变  
  18.      REN=1;        //允许串行口接收位  
  19.      EA=1;         //允许中断(总闸)  
  20.      ES=1;         //允许串口中断  
  21. }  
  22. void main()  
  23. {  
  24.      init();  
  25.      while(1)  
  26. {  
  27.        if(flag==1)  
  28.      {     if(flag_n!=0)        //使第二个及以后I get xx 换行,不与You transfer在一行(单纯为了格式好看)  
  29.              {TI=1;  
  30.              printf("\n");  
  31.              while(!TI);  
  32.              TI=0;  
  33.              }  
  34.          for(i=0;i<6;i++)  
  35.          {  
  36.              SBUF=table[i];  
  37.              while(!TI);  
  38.              TI=0;  
  39.          }  
  40.              for(i=0;s[i]!='#'&&i<50;i++)  
  41.          {  
  42.              SBUF=s[i];  
  43.              while(!TI);  
  44.              TI=0;  
  45.          }  
  46.          flag=0;  
  47.      }  
  48.      if(flag_t==1)                          //发送完毕之后,在电脑端输出。  
  49.      {  
  50.          TI=1;                              //printf之前必须将T1置为1才行。  
  51.          printf ("\nYou transfer %s",s);  
  52.          while(!TI);  
  53.          TI=0;  
  54.          flag_t=0;  
  55.      }     
  56. }  
  57. }  
  58.    
  59. void ser() interrupt 4  
  60. {  
  61.          if(RI)       //接收数据,手动将RI清0  
  62.      {         
  63.          RI=0;  
  64.            
  65.          if(flag==0&&j!=0)//1.循环赋值为'\0'(字符串结尾标志符),j=0,为了第二次传递字符串是又是从头输出  
  66.          {            //2.flag为0和j不为0时,保证是第二次及以后,传输字符串(控制输出格式)  
  67.              flag_n++;              
  68.              for(j=0;s[j]!='#'&&j<50;j++)  
  69.                    s[j]='\0';  
  70.                    j=0;  
  71.          }  
  72.          s[j]=SBUF;  
  73.          flag=1;  
  74.          if(s[j]=='#'||j==49)     //以'#'作为传送字符串的结尾符,我定义的字符数组最长为50所以49也应该结束。  
  75.              flag_t=1;  
  76.          else  
  77.              j++;  
  78.      }  
  79.    
  80.      if(TI)     //发送数据  
  81.      {  
  82.      }      
  83. }  
复制代码

运行截图:
代码解读:基本上就是几个模块:计时器、中断以及串口通信中断寄存器介绍IE(interrupt enable):(可位寻址)设定各个中断源的打开和关闭IP(interrupt prior)中断优先级寄存器:(可位寻址)用来设定各个中断源属于两级中断中的哪一级
中断源:
中断响应条件:
1.中断源有中断请求
2.此中断源的中断允许位为1
3.CPU开中断(EA=1)
代码书写:
1.先开总中断EA
2
.然后再开特定的中断去控制
3.如果有特殊需要优先级问题再设置IP
4.中断函数书写
格式
void 函数名() interrupt 中断号(上面图示的序号)
//中断函数返回值一定是void  
//函数名随便写
//中断号用来判断是哪个中断源
计时器寄存器介绍TCON 支持位寻址 :控制寄存器,控制T1、T0的启动和停止及设置溢出标志
TMOD,不支持位寻址:定时/计数器的工作方式寄存器,确定工作方式和功能
计时器代码书写步骤:1.EA=1;
2.ETX=1;                            //开启计时器X中断
3.配置工作方式  TMOD=0x..; //根据自己需求按照上表来配     
3.配置计时器初值
//THX=(65535-N)/256;
//TLX=(65535-N)%256;   
//N由你要计时的时长决定。计时器计一个数花费一个时钟周期来计算。
4.TRX=1;                           //开启计时器X
串口通信寄存器介绍PCON电源管理寄存器 :(不可位寻址)
用来管理单片机的电源部分,包括上电复位检测、掉电模式
、空闲模式等
SCON:(可位寻址)用以设定串行口的工作方式、接收/发送控制以及设置状态标志
波特率计算
SMOD就是PCON中的第一位,默认为0
fosc为晶振频率,所以自己设定不同波特率时,也要考虑晶振不同的问题。
代码书写
1.上面都书写完毕之后
2.还需要ES=1
3.传输数据时,SBUF=XX
   接收数据时,XX=SBUF
4.中断函数书写
一定要将RI清0,但是TI的清0在主函数中进行
//因为TI在中断中进行,(1)没有if(TI)的判断,那么就会和RI的处理混淆(2)如果有TI判断
//那么有可能永远进行不了传输数据,因为最开始TI是为0的,无法进入TI条件,就无传
//输数据(SBUF=XX)。而且在传输数据的时候会又一次进入中断,就是还没处理中
//断就又进入了另外一个中断,导致通信出现异常。

完整的Word格式文档51黑下载地址:
单片机串口详解.doc (958 KB, 下载次数: 504)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:382700 发表于 2018-8-3 21:04 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:191393 发表于 2018-10-9 16:38 | 显示全部楼层
谢          谢
回复

使用道具 举报

ID:65880 发表于 2018-10-10 08:29 | 显示全部楼层
不错,谢谢了
回复

使用道具 举报

ID:396581 发表于 2018-10-26 09:09 | 显示全部楼层
很全,很仔细的内容,谢谢分享
回复

使用道具 举报

ID:450403 发表于 2018-12-20 00:03 | 显示全部楼层
写的很好,我们刚刚期末需要
回复

使用道具 举报

ID:130345 发表于 2018-12-21 08:26 | 显示全部楼层
串口通信,太感谢了
回复

使用道具 举报

ID:387908 发表于 2019-2-15 21:44 | 显示全部楼层
为啥我的返回的是乱码?
捕获.PNG
回复

使用道具 举报

ID:48127 发表于 2019-3-27 06:59 来自手机 | 显示全部楼层
写的好
回复

使用道具 举报

ID:290290 发表于 2019-3-28 00:12 | 显示全部楼层
写的很好,不错。
回复

使用道具 举报

ID:501991 发表于 2019-3-31 21:01 | 显示全部楼层
对于小白很有帮助,支持楼主。
回复

使用道具 举报

ID:500383 发表于 2019-4-1 09:43 | 显示全部楼层
吃瓜子不吐壳 发表于 2019-2-15 21:44
为啥我的返回的是乱码?

把波特率设为9600试试看。
回复

使用道具 举报

ID:535994 发表于 2019-5-12 11:16 | 显示全部楼层
写的很好
回复

使用道具 举报

ID:520638 发表于 2019-5-12 18:28 | 显示全部楼层
楼主能不能讲解下 单片机和模块的接线问题,
我 想把单片机和UBLOX GPS模块和SIM800c模块连接一起
回复

使用道具 举报

ID:547657 发表于 2019-5-26 16:52 | 显示全部楼层
写的很好
回复

使用道具 举报

ID:511328 发表于 2019-6-10 12:56 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:511588 发表于 2019-7-22 19:29 | 显示全部楼层
吃瓜子不吐壳 发表于 2019-2-15 21:44
为啥我的返回的是乱码?

可能波特率不一致
回复

使用道具 举报

ID:542954 发表于 2019-8-4 18:09 | 显示全部楼层
万分感谢
回复

使用道具 举报

ID:684539 发表于 2020-2-8 10:43 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:208733 发表于 2020-2-8 17:43 | 显示全部楼层
感觉自己还是搞不太清
回复

使用道具 举报

ID:769583 发表于 2020-6-5 21:27 | 显示全部楼层
你这种人活该活到一百岁
回复

使用道具 举报

ID:808940 发表于 2020-8-7 10:23 来自手机 | 显示全部楼层
为什么我的发送1,就一直在发送
回复

使用道具 举报

ID:168971 发表于 2020-11-5 19:00 | 显示全部楼层
感谢大神指路,,,!!!
回复

使用道具 举报

ID:168971 发表于 2020-11-5 21:29 | 显示全部楼层
大神的写法好高级,有没有大神帮忙注释一下啊
回复

使用道具 举报

ID:865268 发表于 2020-12-22 10:09 | 显示全部楼层
为啥我的接受显示是乱码
回复

使用道具 举报

ID:832201 发表于 2020-12-23 22:37 | 显示全部楼层
写的非常清晰,感谢
回复

使用道具 举报

ID:882811 发表于 2021-2-18 10:23 | 显示全部楼层
和教材一样,就是记不住中断啥的的寄存器名字
回复

使用道具 举报

ID:160932 发表于 2021-2-18 14:53 | 显示全部楼层
正在学习串口通信,就看到这个帖子了,非常好,学习了!
回复

使用道具 举报

ID:66328 发表于 2021-2-20 11:35 | 显示全部楼层
教程写的非常好,学习了,谢谢分享!
回复

使用道具 举报

ID:937091 发表于 2021-6-20 19:31 | 显示全部楼层
谢谢您,非常有用
回复

使用道具 举报

ID:88606 发表于 2021-6-21 09:15 | 显示全部楼层
收下了,慢慢看!多看才会有收获!
回复

使用道具 举报

ID:937201 发表于 2021-6-22 19:45 | 显示全部楼层
感谢分享,正在学习串口
回复

使用道具 举报

ID:577554 发表于 2022-1-22 17:35 | 显示全部楼层
示例程序及笔记简单易懂,感谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表