切换到宽版
  • 4817阅读
  • 8回复

[STM]STM8学习之——UART串口 [复制链接]

上一主题 下一主题
离线zeze10000
 

发帖
2858
M币
8559
专家
35
粉丝
112
只看楼主 倒序阅读 我要置顶 楼主  发表于: 2018-07-18
今天我们来学习下串口通讯,串口通讯分好几种,今天就讲TTL电平的,串口。
今天就讲讲单片机与电脑通讯用的串口,也就是串口最简单的应用。
STM8的串口是全双工串口,异步通讯。
全双工就是指能同时双向传输,因为有TX和RX两条线路。
异步指没有同步时钟线。

先看看串口的波形吧,了解一下一条信号线是如何通讯的。

这是用逻辑分析仪抓取的0x55的波形
是不是很神奇,这不就是个方波信号么?
怎么就是0x55了?

先不急,再来看看字符型的55

what?
为啥这也是55?
波形完全不一样,还长了好多!

先不急,再看看下图

咦,这图不是和上图一样么?
怎么这里变成35、35了,不是55了??

真有意思
下面先来看看串口波形的资料

先看8位数据长度的,
一个低电平的起始位,8位数据位,一位高电平停止位
串口波形,一帧的数据构成就是这样
由1位的低电平起始位置,8位、9位或者5位、4位的数据位再加上奇偶校验位(可不用)再加上1位或者1.5或者2位的停止位组成。
貌似说的有点啰嗦了,结构就是:起始位+数据位+校验位+停止位
这就是一帧串口数据的结构,其中数据位可长可短,校验位可有可无,停止位也有长短分别

那么,在没有同步时钟的异步串口中,我们如何能够知道这个波形代表的是1还是11还是111呢?
这个就关系到一个重要的概念:波特率
波特率就是每秒能发送多少个码元,码元简单来说在数字信号里就是代表0和1的最小单位。
以最常见的9600的串口波特率来说,一秒能传输9600个二进制位,那么每个位所占的时间长度就能得出1s/9600=104us
所以一个位的长度就是104us。知道位长度了就可以开始分割数据位了。

串口数据发送里是低位先传送,TTL是正逻辑电平。那现在就来对第一张图的波形进行解析。
上面的串口配置是9600,8数据位,无校验,1停止位。
上面读下来就是
0101010101
砍头去尾剩下10101010,因为是低位先传,来个倒序
01010101,读出来就是0x55
字符串是用ASCII码进行传送,因此5对应的ASCII码的16进制位是35.
之所以第二第三张图显示不同是因为分析仪设置不同,图二是ASCII码解析,图三是HEX解析

好了,下面是单片机的串口结构


看不清,看重要的

这里看到了串口的主要结构
灰色方框写的是UART_DR,就是串口数据寄存器
但是里面还包含了很多寄存器
有接收移位寄存器,发送移位寄存器,发送数据寄存器,接收数据寄存器
但是实际操作时读写的都是UART_DR这个地址
这是咋回事呢?
这其实是写UART_DR其实是要写到TDR,而读则是读到了RDR。

今天的实验很简单,就是用串口把接收到的数据再传回去
先看看配置流程

首先配置UART_CR1的M,选择数据长度
然后是UART_CR3,配置停止位
接下来是配置波特率,这个要小心,
波特率是通过主时钟分频来的,
UART_BRR要拆分配置
UART_BRR1还不能配置成00。
接下来是配置UART_CR2使能发送接收。
然后再下来就是写如要发送的数据到UART_DR.
最后是等待发送完成。

我这里就是简单的回传接收到的数据
貌似很简单,但实际操作还是遇到了很多麻烦
最开始我是接收到一个字节马上就回传,并且是在接收中断里处理。
结果是单字节完全正常,长字符串就乱码。
后面想想应该是有部分字节丢失导致的,因为串口的数据是连续传输,如果不及时读出则数据会被覆盖
后面就使用一个数组做接收缓存,还是出问题。
主要还是对字符串的结束判断出了问题。
之前一直以为字符串的结尾会有个‘\0’,结果是没有的。
后面想想也是,字符串为啥会有‘\0’?
这只是在储存进内存里的一个结束标识位,遇到这个标识默认是字符串已经结束。
在传输时并不会传输这个标志。

这咋办呢?得自己加一个啊,不如就加回车吧也就是\r\n判断\n结尾
万一要是没有回车结尾呢?
那就做个超时吧

结果就是下面的程序
  1. #include<iostm8s105k4.h>
  2. void init()
  3. {
  4.   CLK_SWCR=0x02;     //时钟配置
  5.   CLK_SWR=0xb4;      //外部晶体
  6.   CLK_CKDIVR=0x00;   //不分频
  7.   
  8.   UART2_CR1=0x00;    //1,8,n,1
  9.   UART2_CR3=0x00;
  10.   
  11.   UART2_BRR1=0x34;   //波特率 9600 8M/833
  12.   UART2_BRR2=0x01;
  13.   
  14.   UART2_CR2=0x2c;    //串口发送接收打开,开接收中断
  15.   
  16. }
  17. #pragma vector=0x17     //串口接收中断
  18. __interrupt void UART()
  19. {      
  20.   unsigned char buf[50]="";  //接收缓存
  21.   unsigned char *p=buf;      //定义指针
  22.   unsigned int count=0;      //超时计数
  23.   
  24.   while(1)                    //接收循环
  25.   {
  26.     while(!(UART2_SR&0x20))    //等待接收完成
  27.     {
  28.       count++;                  //接收超时计数
  29.       if(count>65000) break;    //接收超时,跳出等待
  30.     }
  31.     if(count>65000) break;      //接收超时,跳出接收
  32.     count=0;                    //计数复位
  33.     
  34.     *p=UART2_DR;                //取值
  35.     if((*p=='\n')||((p-buf)>=50)) break;     //字符串结束或超缓存跳出
  36.     p++;                        //下一位
  37.   }
  38.   
  39.   p=buf;                        //取缓存地址
  40.   while((*p!='\0')&&(*p!='\n')&&((p-buf)<50))   //当不为结束符且未超缓存时继续循环发送
  41.   {
  42.     UART2_DR=*p;                //送数据
  43.     while(!(UART2_SR&0x40));    //等待发送完成
  44.     p++;                        //下一位
  45.   }
  46. }
  47. int main( void )
  48. {
  49.   init();
  50.   asm("rim");           //允许中断
  51.   while(1);
  52. }

这回总算是正常了


最后再总结下串口乱码的原因,一个因为没有同步时钟,波特率偏差引起乱码
还有就是接收问题,有丢失字节,可能是接收不及时或者没接收完
串口输出一般不会出问题。




STM8首次学习实验~流水灯
http://bbs.mydigit.cn/read.php?tid=2452931

STM8学习之——中断
http://bbs.mydigit.cn/read.php?tid=2453643

STM8学习之——TIMER4定时器
http://bbs.mydigit.cn/read.php?tid=2456190

STM8学习之——timer1输入捕获
http://bbs.mydigit.cn/read.php?tid=2457109

STM8学习之——timer1外部时钟源模式2
http://bbs.mydigit.cn/read.php?tid=2459809

STM8学习之——timer1周期测量
http://bbs.mydigit.cn/read.php?tid=2461507

STM8学习之——周期测量的疑问
http://bbs.mydigit.cn/read.php?tid=2462114

STM8学习之——timer1频率占空比测量
http://bbs.mydigit.cn/read.php?tid=2464249

STM8学习之——timer1 PWM输出
http://bbs.mydigit.cn/read.php?tid=2467013

STM8学习之——AWU自动唤醒
http://bbs.mydigit.cn/read.php?tid=2477122

STM8学习之——BEEP资源
http://bbs.mydigit.cn/read.php?tid=2477224

STM8学习之——IWDG独立看门狗
http://bbs.mydigit.cn/read.php?tid=2477395

STM8学习之——WWDG窗口看门狗
http://bbs.mydigit.cn/read.php?tid=2477802

STM8学习之——UART串口
http://bbs.mydigit.cn/read.php?tid=2479924

本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共4条打赏M币+119
owenql M币 +8 優秀文章 2019-01-04
2545889167 M币 +20 stm8的串口,总的来说是不错的。简单易用 功能又多。完爆51好几条街 2018-07-19
發騷友 M币 +76 以資鼓勵 2018-07-18
66ok66 M币 +15 还请继续发扬这系列教学 2018-07-18
离线66ok66

发帖
1356
M币
860
专家
10
粉丝
21
只看该作者 1楼 发表于: 2018-07-18
请登录后查看
离线chenlei1910

发帖
11032
M币
1444
专家
2
粉丝
40
只看该作者 2楼 发表于: 2018-07-18
请登录后查看
离线2545889167

发帖
13268
M币
20754
专家
302
粉丝
4860
只看该作者 3楼 发表于: 2018-07-19
请登录后查看
离线2545889167

发帖
13268
M币
20754
专家
302
粉丝
4860
只看该作者 4楼 发表于: 2018-07-19
请登录后查看
离线zeze10000

发帖
2858
M币
8559
专家
35
粉丝
112
只看该作者 5楼 发表于: 2018-07-19
回 2545889167 的帖子
请登录后查看
离线2545889167

发帖
13268
M币
20754
专家
302
粉丝
4860
只看该作者 6楼 发表于: 2018-07-19
回 zeze10000 的帖子
请登录后查看
离线595953427@qq

发帖
610
M币
51
专家
0
粉丝
15
只看该作者 7楼 发表于: 2018-07-20
请登录后查看
离线13691937585

发帖
19
M币
15
专家
0
粉丝
2
只看该作者 8楼 发表于: 2019-01-03
请登录后查看
快速回复
限80 字节
“新手上路”发帖需审核后才能显示(请认真发帖),达到数码9级后取消此限制
 
上一个 下一个