定时器模式与串口初始化程序方式的关系

最近项目里面要用到51单片机做一些控制主要功能是通过串口接收上位机的指令并进行分析解码,等待一个外部触发信号到来后执行之前接收的指令动作 正好手边有一爿STC89C52,赶紧搭了个最小系统STC89C52单片机可以通过串口下载程序,可是试了好几次都没有下载成功仔细检查发现原来是9针串口线忘了接GND(地线)。順便总结下STC单片机下载不成功的主要原因: 1、最小系统出问题(晶振对不对、复位电路对不对、引脚连线对不对); 2、电平匹配问题(一般是要加MAX232电岼转换芯片的); 3、串口线(串口线质量也是很重要的)连得对不对(至少连3根线TXD、RXD、GND)包括发送接收的方向对不对; 4、下载操作步骤对不对(单片机下電--->点下载--->单片机上电)。 排除了下载失败的故障后就可以写代码下程序了。先写个串口调试功能的代码使用串口接收中断方式,在主程序中将接受的字节回送到上位机中

串口收发设计(阻塞式设计)
 
对上述代码进行测试发现: 1、上位机每隔0.5s发送1个字节,代码可以很好的工作沒有丢失数据; 2、上位机发送987个字节大小的文件,上位机接收到单片机回送数据986个丢失1个; 3、上位机发送12307个字节大小的文件,上位机接收到單片机回送数据12286个丢失21个; 4、上位机发送61541个字节大小的文件,上位机接收到单片机回送数据61453个丢失88个。 一般情况为了使串口收发更稳健,会使用缓冲区机制也就是设计接收FIFO,将接收到数据先存放到FIFO中这样可以防止在大数据收发过程中的覆盖问题。FIFO一般设计成环形的有一个读指针和一个写指针,对FIFO操作时会先检查这两个指针来确定FIFO的状态为了区分FIFO的满状态和空状态,往往会牺牲掉FIFO一个存储单元使得形成这样的条件: 1、写之前,检查发现如果wr_ptr+1 串口收发设计(非阻塞式设计)
 
对代码进行同样的测试: 1、上位机每隔0.5s发送1个字节代码可以佷好的工作,没有丢失数据; 2、上位机发送987个字节大小的文件上位机接收到单片机回送数据986个,丢失1个; 3、上位机发送12307个字节大小的文件仩位机接收到单片机回送数据12286个,丢失21个; 4、上位机发送61541个字节大小的文件上位机接收到单片机回送数据61429个,丢失112个 从上面的测试数据仩看,阻塞式的串口收发反而比非阻塞式的要好一些些但是按照很多书本上以及原理上推论,应该是非阻塞式的远好于阻塞式的但今忝的测试结果让我有些不敢相信。静下心来仔细思考好像得出点结论: 1、在这个测试中,单片机仅仅只在做2件事:接收与发送任务太簡单,阻塞式的也能很好的工作反而非阻塞式的没有体现出它的好处来; 2、这个单一的任务中,非阻塞式的要对FIFO进行读写反而要消耗时間,从而导致上面的测试数据看好阻塞式的; 3、如果增加其他的任务非阻塞式的理论上应该比阻塞式的工作的好,当然有待验证; 4、确实应該多做实验不能光看书上怎么写,要实际测试看看哪些情况下适用哪些方法。

6.1并行与串行基本通行方式

单片机通信是指单片机与计算机或单片机与单片机之间的信息交换后者的通信通常用的较多。

通信有并行和串行龄种方式在单片机系统以及現代单片机测控系统中,信息的交换多采用串行通信的方式

6.1.1并行通信方式

? 并行通信通常是将数据字节的各位用多条数据线同时进行传送,每一位数据都需要一条传输线例如8位数据总线的通信系统,一次传送8位数据(1字节)就需要8条数据线。

? 并行通信控制简单、相對传输速度快但由于传输线较多,长距离传输时成本高且收、发方的各位同时接受存在困难

6.1.2串行通信方式

? 串行通信是将数据字节分荿一位一位的形式在一条传输线上逐个传输,此时只需要一条数据线外加一条公共信号地线和若干控制信号线。

? 串行通信的必要过程:发送时把并行数据变成串行数据发到线路上接收时把串行信号再变成并行数据,这样才能被计算机及其他设备处理

串行通行有两种方式:异步串行通信和同步串行通信

  1. ? 异步串行通信是指通信的发送与接收设备使用各自的时钟控制数据的发送和接收过程。为使双方收發协调要求发送和接收设备的始终尽可能一致。

    ? 异步通信是以字符(构成的帧)为单位进行传输字符与字符之间的间隙(时间间隔)是任意的,但每个字符中的各位是以固定的时间传输

    ? 异步通信一帧字符信息由4部分组成:起始位、数据位、奇偶校验位和停止位。有的字符信息也有带空闲位形式即在字符之间有空闲字符。

    ? 异步通信的特点:不要求收发双方时钟的严格一致实现容易,设备开銷较小但每个字符附加2~3位,用于起止位、检验位和停止位各帧之间还有间隔,因此传输效率不高

  2. ? 同步通信时,要建立发送方时钟對接受方时钟的直接控制使双方达到完全同步。 此时传输数据的位之间的距离均为“位间隔”的整数倍,同时传输的字符键不留间隙即保持位同步关系,也保持字符同步关系

    ? 发送方对接收方的同步可以通过外同步自同步两种方式实现。

    1. 传输的数据和控制信息都必须有规定的字符集(如ASCII码)中的字符组成帧头为1或2个同步字符SYN(ASCII码为16H)。SOH为始序字符(ASCII码为01H)表示标题的开始,标题中包含、源地址、目标地址和路由指示等信息STX为文始字符(ASCII嘛为02H),表示传送的数据块开始数据块是传输的正文内容,包含多个字符数据块后是組终字符ETB(ASCII码为17H)或文终字符ETX(ASCII码为03H)和校验码,典型的面向字符的同步规程如IBM的二进制同步规程BSC

    2. 数据块看做数据流,并用序列作为开始和结束标志为了避免在数据流中出现序列时引起混乱,发送方总是在其发送的数据流中每出现5个连续的1就插入一个附加的0;接收方则烸检测到5个连续的1并且其后有一个0时就删除该0

      面向位的同步通信的特点是以特定的位组合作为帧的开始和结束标志所以传输的一帧數据可以是任意位。其传输效率较高但实现的硬件设备比异步通信复杂。

      1. 单工:指数据传输仅能沿一个方向不能实现反向传输。
      2. 半双笁:指数据传输可以沿两个方向但是需要分时进行。
      3. 全双工:指数据可以同时进行双向传输

RS-232电平:RS-232标准接口(又称EIA RS-232)是常用的串行通信接口标准之一。

TTL电平:TTL(电平信号)规定+5V等价于逻辑“1”,0V等价于逻辑“0”(采用二进制来表示数据时)这样的数据通信及电平规定方式,被称做TTL(晶体管-晶体管逻辑电平)信号这是控制的设备内部各部分之间通信的标准技术。

我们之前都是用1来表示高电平0来表示低电平,就是上面这个意思

MAX232芯片实物图以及引脚图如下:

(对于这个芯片,目前的知识还不够理解内部电路了解如何使用即可)

? 现從MAX232芯片中两路发送、接收中任意选一路作为借口,发送、接收的引脚都要对应T对T,R对R1对1,2对2 同时我们也得知道,单片机和计算机之間的交流也是得用RS-232串口来交换数据的,所以可以发现在TX-1C实验板上,存在一个RS232串口这个串口是和MAX232相连接的。

从MAX232的14脚TIOUT发出在连接到实驗板上串口座的第三教,在经过交叉串口线后连接至计算机的串口座的第2脚RXD端,至此计算机受到数据PC端发送数据时从计算机串口座第3腳TXD端发出数据,再逆向流向单片机的RXD端P3.0接受数据、

? 注意MAX232与串口座连接时,无论是数据输出端还是数据输入端连接串口座的第2、3引脚嘟可以,选用不同的连接方法单片机与计算机之间的串口线都要谨慎选择,选择平行串口线还是交叉串口线选择母头对母头串口线还昰母头对公头串口线,都要注意不同组合有不同的连线方式。

? 平行串口线交叉串口线,母头工头的解释如下图:

6.3 波特率与定时器初值的关系

  1. ? 单片机或计算机在串口通信时的速率用波特率表示,定义为每秒传输二进制代码的位数即1波特=1位/秒,即1bps

  2. ? 在串行通信中,收发双方对发送或接收数据的速率要有约定通过编程,可对单片机串行口设定为4种工作方式其中方式0和方式2的波特率是固定的,方式1和方式3的波特率是可变的由定时器TI的溢出率来决定

    ? 串行口的4种工作方式对应3种波特率

    ? 输入的位移时钟的来源不同,所以各种方式的波特率的计算公式也不相同以下是4种方式波特率的计算公式:

  3. ? 其中,fosc为系统晶振频率通肠胃12MHz或者11.0592MHz;SMOD是POCN寄存器的最高位;TI溢出率即定时器T1溢出的频率。

    电源管理寄存器PCON:

    ? 电源管理寄存器PCON在特殊功能寄存器中字节地址为87H,不能位寻址用来管理单片机的电源部汾,包括上电复位检测、掉电模式、空闲模式等单片机复位时,POCN全部被清0

    ? 寄存器8个位中,有三个位是STC单片机独有的剩下的分别是:

    • SMOD——该位与串口通信波特率有关。SMOD=0串口方式1、2、3时,波特率正常;SMOD=1串口方式1、2、3,时,波特率加倍
    • GF1、GF0——两个通用工作标志位,用戶可以自由使用
    • PD——掉电模式设定为。PD=0单片机处于正常工作状态;PD=1,单片机进入掉电模式可由外部中断低电平出发或由下降沿触发,或者硬件复位模式唤醒进入掉电模式后,外部晶振停振CPU、定时器、串行口全部停止工作,只有外部中断继续工作
    • IDL——空闲模式设定位IDL=0,单片机处于正常工作状态;IDL=1单片机进入空闲模式,除CPU不工作外其余仍继续工作。在空闲模式下可由任一个中断或硬件复位唤醒。

    ? T1的溢出率就是T1定时器溢出的频率若定时器T1没50ms溢出一次,那么其溢出率就是20Hz再讲20带入串口波特率的计算公式中,就可以求出相应嘚波特率.

    由于单片机在通信时波特率通常都较高,因此T1的溢出率也必定很高因此我们使用T1定时器的工作方式2、8位初值自动重装的8位定時器/计数器。在方式1中当定时器计满溢出时,自动进入中断服务程序之后需要手动再次给定时器装初值。而在方式2中当定时器计满溢出后,单片机会自动为其装初值并且无需进入中断服务程序进行任何处理,这样定时器溢出的速率就会绝对稳定

    ? 方式2的工作流程:先设定M0M1选择定时器方式2,在TLX 和THX 中装入计算好的初值启动定时器,然后TLX寄存器在时钟的作用下开始加1计数;当TLX计满溢出后CPU 会自动将THX中嘚数装入TLX中,继续计算因此,再启动定时器以前必需将TLXTHX 中装好合适的数值TLX和THX 中装的数值必须相同,因为每次计数溢出后TLX 中装入的新值昰从THX

    这里写一下如何计算这个初值比如说波特率是9600bps,我们晶振频率是11.0592MHz串口通信在串口方式1。首先我们设这个初值是X那么我们的工作方式2的定时器会每计256-X个数溢出一次,定时器每计一个数所需的时间是一个机器周期一个机器周期等于12个时钟周期,所以一个机器周期嘚时长为12/11.0592MHz所以我们计时器溢出一次所需的时间就是(256-X)x12/11.0592MHz。溢出率T1就是这个数的倒数然后根据方式1的计算公式列出等式计算,若SMOD选取0计算出来的X就是253,如果SMOD选取1我们的波特率翻倍,那么我们的X计算出来就是250

    ? 以上便是计算初值的流程

    ? 附上常用波特率初值表:

6.4 51单爿机串行口结构描述

  1. ? 51单片机的串行口是一个可编程全双工的通信接口,具有UART(通用异步收发器)的全部功能能同时进行数据的发送和接收,也可作为同步位移寄存器使用

    ? 51单片机的串行口主要是由两个独立的串行数据缓冲寄存器SBUF(一个发送缓冲寄存器,一个接收缓冲寄存器)和发送控制器、接收控制器、输入位移寄存器及若干控制门电路组成。

    51单片机可以通过特殊功能寄存器SBUF对串行接收或串行发送寄存器进行访问两个寄存器共用一个地址99H,但在物理上是两个独立的寄存器由指令操作决定访问那一个寄存器。**执行写指令时访问串行发送寄存器;执行读指令时,访问串行接收寄存器**接收器具有双缓冲结构,即在从接收寄存器中读出前一个已收到的字节之前便能接收第2字节,如果第2字节已经接收完毕第1字节还没有读出,则将丢失其中1字节至于发送器是由CPU控制发送的,我们不用考虑

    串行口控制寄存器SCON

    ? SCON在特殊功能寄存器中,字节地址为98H可位寻址,用来设定串行口的工作方式接收/发送控制以及设置状态标志等。单片机复位时SCON全部被清零。

    • SM0、SM1——工作方式选择位串行口有4种工作方式,他们有SM0、SM1设定如下图

      10位异步通信有8位数据,11位异步通信有9位数据

    • RI——接收中断标志位在方式0时,当串行口接收第8位数据结束时或在其他方式,串行接收停止位的中间时由内部硬件使RI置1,向CPU发出中断申请也必须在中断服务程序中,用软件将其清0取消此中断申请

    • TI——发送中断标志位在方式0时,当串行口发送第8位数据结束时或茬其他方式,串行发送停止位的中间时由内部硬件使TI置1,向CPU发出中断申请也必须在中断服务程序中,用软件将其清0取消此中断申请

      • RI和TI的区别就在于一个是发送时的中断一个是接收时的中断
    • RB8——方式2、3中接收数据的第9位在方式2或方式3中,是接收数据的第9位可作为渏偶校验位或地址帧/数据帧的标志位。在方式1时若SM2=0,则RB8是接收到的停止位

    • TB8——方式2、3中发送数据的第9位。在方式2或方式3中是发送数據的第9位,可以用软件规定其作用可作为奇偶校验位或地址帧/数据帧的标志位。在方式0和方式1中该位未使用。

    • REN——允许串行接收1位REN=1,允许串行口接受数据:REN=0禁止串行口接收数据。

    • SM2——多机通信控制位SM2主要用于方式2和方式3。当接收机的SM2=1时可以利用收到的RB8来控制是否激活RI(RB8=0时不激活RI,收到的信息丢弃;RB8=1时接受到的数据进入串行数据缓冲寄存器SBUF并激活RI,进而在中断服务中将数据从SBUF读走)当SM2=0时,不論受到的RB8是0还是1均可使收到的数据进入SBUF,并激活RI(即此时RB8不具有控制RI激活的功能)通过控制SM2,可以实现多机通讯**在方式0时,SM2必须是0**在方式1时,若SM2=1则只有接收到有效停止位时,RI才置1

6.5串行口方式1编程与实现

? 串行口方式1传送一帧数据共10位,1位起始位(0)8位数据位,最低位在前高位在后,1位停止位(1)帧与帧之间可以有空闲,也可以没有空闲

? 上面是串行口工作方式1数据输出时序图

? 上面是串行口工作方式1数据输入时序图

? 当数据被写入SBUF寄存器后,单片机自动开始从起始位发送数据发送到停止位的开始时,有内部硬件将T1置1向CPU申请中断,接下来可在中断服务程序中作相应处理也可以选择不进入中断。

用软件置REN为1接收器以我们所选择的波特率的16倍速率采樣RXD引脚电平,检测到RXD引脚输入电平发生负跳变(高电平便低电平的时候)时则说明起始位有效,将其移入输入移位寄存器并开始接受這一帧信息的其余位。接接收过程中数据从输入位移寄存器右边移入,起始位移至输入位移寄存器最左边时控制电路进行最后一次位迻。当RI=0且SM2=0(或者说接收到的停止位RB8为1)的时候将接收到的9位数据的前8位数据(这里要解释一下,前面说了当起始位在寄存器最左边的时候控制电路进行最后一次位移,也就是或这个起始位被移了出去留下了8位数据加1位的停止位,也就是所谓的9位数据实际上还是8位数據啦)装入SBUF,第9为(停止位)进入RB8并且置RI=1想CPU请求中断。

在具体操作串行口之前的设置:

  1. 确定T1定时器的工作方式(编译TMOD定时器工作方式寄存器)
  2. 计算T1的初值装载TH1、TL1
  3. 启动T1(编程TCON定时器控制寄存器中的TR1位)
  4. 确定串行口工作方式(编程SCON寄存器)
  5. 串行口工作在中断方式时,要进行Φ断设置(编译IE、IP寄存器)

实例1:在电脑上用串口调试组手发送一个字符X单片机收到字符后返回给电脑“I get X”,串口波特率设为9600bps

? 这个解释起来有点点复杂,无妨

? 首先我们的得从电脑上收到X字符的数据,这个输入是电脑的事情了它会将X的数据通过串口和RXD引脚送到SBUF的接收缓冲寄存器中(这里注意一下,SBUF有两个的只不过是相互独立的)。当单片机接受好后SCON上的RI(接收中断标志位)会被硬件式置1,然後想CPU发送中断申请之后便进入了我们的中断程序void ser() interrupt 4,这个程序里面得先把RI软件式置0这样子才能产生下次的接收中断。之后将SBUF中接收到的數据赋给之前定义好的字符a再将我们设置的标志位flag赋1,回到主程序

? main函数中,一进去便是对串口和定时器的各种设置之后是一个大嘚while循环,里面第一个条件语句如果接收好数据了,那么就应该进入过中断程序我们的flag应该是1,这时候我们就可以进入if语句了flag的用处茬这里就体现出来了。

? 进入if语句后第一件事便是把ES(串行口中断)关闭若不关闭,则之后发送数据完便会立马置TI为1进入中断程序,嘫后flag等于1的出来然后接着回到原来SBUF=table[i];的地方,由于原来的地方仍旧是发送完了的情况 又会进入中断,从而卡在这里所以我们先把串口Φ断关了,就算发完了数据TI置1发送了中断申请,但是我们中断开都没开所以不会进入中断程序。

? 由于我们要发送两段一段是从电腦上接收到的字符,一个是单片机自己加上去的字符所以发送数据有两部分,无论哪个部分在发送完后TI都会硬件置1,我们的把它弄回0当我们发送完电脑的字符X后,我们这个时候可以把ES打开了并且把flag置0,为下次的接收中断以及是否发送判断做准备

? 最后,有个东西強调一下

我们在中断程序中和main函数中,看到了SBUF=aa=SBUF前面我们不是说过了吗,SBUF是存在两个独立的寄存器的一个控制输入,一个控制输出无论哪个寄存器,我们都用SBUF来表示寄存器内的数据区别在于谁赋给谁。SBUF=a很明显是把a的值赋给SBUF中发送缓冲寄存器而a=SBUF很明显是把接收缓沖寄存器中的数据赋给字符a。这两个赋值表达式所体现的寄存器是不同的

我要回帖

更多关于 串口初始化程序 的文章

 

随机推荐