16位单片机 让计数器1ms怎么让fbus

FBUS串口调试工具|FBUS串口调试工具下载 v1.2绿色免费版_ - pc6下载站当前位置: >>
XS128 串行通信接口SCI
第5章 串行通信接口SCI目前几乎所有的台式电脑都带有 9 芯的异步串行通信口,简称串行口或 COM 口。由于历史的原因, 通常所说的串行通信就是指异步串行通信。USB、以太网等也用串行方式通信,但与这里所说的异步串 行通信物理机制不同。 有的台式电脑带有两个串行口 COM1 和 COM2, 部分笔记本电脑也带有串行口。 随着 USB 接口的普及, 串行口的地位逐渐降低,但是作为设备间简便的通信方式,在相当长的时间内,串行口还不会消失,在 市场上也可很容易的购买到 USB 到串行口的转接器。 因为简单且常用的串行通信只需要三根线 (发送线、 接收线和地线) ,所以串行通信仍然是 MCU 与外界通信的简便方式之一。 实现异步串行通信功能的模块在一部分 MCU 中被称为通用异步收发器(Universal Asynchronous Receiver/Transmitters,UART) ,在另一些 MCU 中被称为串行通信接口( Serial Communication Interface,SCI) 。串行通信接口可以将终端或个人计算机连接到 MCU,也可将几个分散的 MCU 连接成 通信网络。 本章主要内容有:①异步串行通信的通用基础知识;②XS128 的 SCI 模块的编程结构与 SCI 构件设 计,并测试这个构件;③借助 XS128 的串行接收中断来阐述中断概念与编程方法,并给出编程实例。对 基于构件的编程思想,再次在设计 SCI 构件中加以阐述,读者在阅读时可以仔细体会,以求得对编程方 法更深刻的理解。通过本章学习了中断编程例子后,至此,以一个 MCU 为蓝本学习嵌入式系统硬件软件 基础知识的基本要素已经完成, 后续章节将进行知识的不断积累与扩展, 学习新模块的工作原理与驱动 软件设计,但基本思想与方法方法是一致的。5.1 异步串行通信的通用基础知识本节简要概述异步串行通信中常用的基本概念与硬件连接方法,为学习 MCU 的串行通信接口编程 做准备。5.1.1 串行通信的基本概念D位‖(bit)是单个二进制数字的简称,是可以拥有两种状态的最小二进制值,分别用D0‖和D1‖表示。 在计算机中,通常一个信息单位用 8 位二进制表示,称为一个D字节‖(byte) 。串行通信的特点是:数 据以字节为单位,按位的顺序(例如最高位优先)从一条传输线上发送出去。这里至少涉及到以下几个 问题:第一,每个字节之间是如何区分开的?第二,发送一位的持续时间是多少?第三,怎样知道传输 是正确的?第四, 可以传输多远?这些问题属于串行通信的基本概念。 串行通信分为异步通信与同步通 信两种方式,本节主要给出异步串行通信的一些常用概念。正确理解这些概念,对串行通信编程是有益 的。 1.异步串行通信的格式 在 MCU 的英文芯片手册上,通常说的异步串行通信采用的是 NRZ(不归零)数据格式,英文全称 是:Dstandard non-return-zero mark/space data format‖,可以译为:D标准不归零传号/空号数据格式‖。 这是一个通信术语,D不归零‖的最初含义是:用负电平表示一种二进制值,正电平表示另一种二进制 值, 不使用零电平。 Dmark/space‖即D传号/空号‖分别是表示两种状态的物理名称, 逻辑名称记为D1/0‖。 对学习嵌入式应用的读者而言,只要理解这种格式只有D1‖、D0‖两种逻辑值就可以了。图 5-1 给出了 8 位数据、无校验情况的传送格式。 开始位第0位第1位第2位第3位第4位第5位第6位第7位停止位图5-1 串行通信数据格式这种格式的空闲状态为D1‖,发送器通过发送一个D0‖表示一个字节传输的开始,随后是数据位 (在 MCU 中一般是 8 位或 9 位,可以包含校验位) 。最后,发送器发送 1 到 2 位的停止位,表示 一个字节传送结束。若继续发送下一字节,则重新发送开始位,开始一个新的字节传送。若不发送 新的字节,则维持D1‖的状态,使发送数据线处于空闲。从开始位到停止位结束的时间间隔称为一 帧(frame)。所以,也称这种格式为帧格式。 每发送一个字节, 都要发送D开始位‖与D停止位‖, 这是影响异步串行通信传送速度的因素之一。 同时因为每发送一个字节,必须首先发送D开始位‖,所以称之为D异步‖(Asynchronous)通信。 2.串行通信的波特率 位长(Bit Length) ,也称为位的持续时间(Bit Duration) 。其倒数就是单位时间内传送的位数。 人们把每秒内传送的位数叫做波特率(Baud Rate) 。波特率的单位是:位/秒,记为 bps。bps 是英 文 bit per second 的缩写,习惯上这个缩写不用大写,而用小写。通常情况下,波特率的单位可以 省略。 通常使用的波特率有 600、 900、 1200、 1800、 2400、 4800、 9600、 19200、 38400、 57600、 115200、 128000 等。在包含开始位与停止位的情况下,发送一个字节需 10 位,很容易计算出,在各波特率 下,发送 1K 字节所需的时间。显然,这个速度相对于目前许多通信方式而言是慢的,那么,异步 串行通信的速度能否提得很高呢?答案是不能。因为随着波特率的提高,位长变小,以至于很容易 受到电磁源的干扰,通信就不可靠了。当然,还有通信距离问题,距离小,可以适当提高波特率, 但这样毕竟提高的幅度非常有限,达不到大幅度提高的目的。 3.奇偶校验 在异步串行通信中,如何知道传输是正确的?最常见的方法是增加一个位(奇偶校验位) ,供 错误检测使用。字符奇偶校验检查(Character Parity Checking)称为垂直冗余检查(Vertical Redundancy Checking,VRC) ,它是为每个字符增加一个额外位使字符中D1‖的个数为奇数或偶数。 奇数或偶数依据使用的是D奇校验检查‖还是D偶校验检查‖而定。当使用D奇校验检查‖时,如果字符 数据位中D1‖的数目是偶数,校验位应为D1‖,如果D1‖的数目是奇数,校验位应为D0‖。当使用D偶校 验检查‖时,如果字符数据位中D1‖的数目是偶数,则校验位应为D0‖,如果是奇数则为D1‖。 这里列举奇偶校验检查的一个实例,看看 ASCII 字符DR‖,其位构成是 1010010。由于字符DR‖ 中有 3 个位为D1‖,若使用奇校验检查,则校验位为 0;如果使用偶校验检查,则校验位为 1。 在传输过程中,若有 1 位(或奇数个数据位)发生错误,使用奇偶校验检查,可以知道发生传 输错误。若有 2 位(或偶数个数据位)发生错误,使用奇偶校验检查,就不能知道已经发生了传输 错误。但是奇偶校验检查方法简单,使用方便,发生 1 位错误的概率远大于 2 位的概率,所以D奇 偶校验‖这种方法还是最为常用的校验方法。几乎所有 MCU 的串行异步通信接口,都提供这种功 能。 4.串行通信的传输方式 在串行通信中,经常用到D单工‖、D双工‖、D半双工‖等术语。它们是串行通信的不同传输方式。 下面简要介绍这些术语的基本含义。 (1)单工(Simplex) :数据传送是单向的,一端为发送端,另一端为接收端。这种传输方式 中,除了地线之外,只要一根数据线就可以了。有线广播就是单工的。 (2)全双工(Full-duplex) :数据传送是双向的,且可以同时接收与发送数据。这种传输方式 中,除了地线之外,需要两根数据线,站在任何一端的角度看,一根为发送线,另一根为接收线。 一般情况下,MCU 的异步串行通信接口均是全双工的。 (3)半双工(Half-duplex) :数据传送也是双向的,但是在这种传输方式中,除地线之外,一 般只有一根数据线。任何时刻,只能由一方发送数据,另一方接收数据,不能同时收发。5.1.2 RS-232 总线标准现在回答D可以传输多远‖这个问题。MCU 引脚输入/输出一般使用 TTL(Transistor Transistor Logic)电平,即晶体管-晶体管逻辑电平。而 TTL 电平的D1‖和D0‖的特征电压分别为 2.4V 和 0.4V (目前使用 3V 供电的 MCU 中,该特征值有所变动) ,即大于 2.4V 则识别为D1‖,小于 0.4V 则识 别为D0‖。它适用于板内数据传输。若用 TTL 电平将数据传输到 5m 之外,那么可靠性就很值得考 究了。为使信号传输得更远,美国电子工业协会 EIA(Electronic Industry Association)制订了串行 物理接口标准 RS-232C, 以下简称 RS-232。 RS-232 采用负逻辑, -15V~-3V 为逻辑D1‖, +3V~+15V 为逻辑D0‖。RS-232 最大的传输距离是 30m,通信速率一般低于 20Kbps。当然,在实际应用中, 也有人用降低通信速率的方法,通过 RS-232 电平,将数据传送到 300m 之外,这是很少见的,且 稳定性很不好。 RS-232 总线标准最初是为远程数据通信制订的,但目前主要用于几米到几十米范围内的近距 离通信。有专门的书籍介绍这个标准,但对于一般的读者,不需要掌握 RS-232 标准的全部内容, 只要了解本节介绍的这些基本知识就可以使用 RS-232。 目前一般的 PC 机均带有 1 到 2 个串行通信 接口,人们也称之为 RS-232 接口,简称D串口‖,它主要用于连接具有同样接口的室内设备。早期 的标准串行通信接口是 25 芯插头,这是 RS-232 规定的标准连接器(其中:2 条地线,4 条数据线, 11 条控制线,3 条定时信号,其余 5 条线备用或未定义) 。 后来,人们发现在计算机的串行通信中,25 芯线中的大部分并不使用,逐渐改为使用 9 芯串 行接口。一段时间内,市场上还有 25 芯与 9 芯的转接头,方便了两种不同类型之间的转换。后来, 使用 25 芯串行插头极少见到,25 芯与 9 芯转接头也极少有 售。因此,目前几乎所有计算机上的串行口都是 9 芯接口。 9 6 7 8 图 5-2 给出了 9 芯串行接口的排列位置,相应引脚含义见表 1 5 4 2 3 5-1。 嵌 在 RS-232 通信中,常常使用精简的 RS-232 通信,通信 图5-2 9芯串行接口排列 时仅使用 3 根线:RXD(接收线) 、TXD(发送线)和 GND (地线) 其他为进行远程传输时接调制解调器之用, 。 有的也可作为硬件握手信号 (如请求发送 RTS 信号与允许发送 CTS 信号) ,初学时可以忽略这些信号的含义。表 5-1 9 芯串行接口引脚含义表 引脚号 1 2 3 4 5 功能 接收线信号检测(载波检测 DCD) 接收数据线(RXD) 发送数据线(TXD) 数据终端准备就绪(DTR) 信号地(SG) 引脚号 6 7 8 9 功能 数据通信设备准备就绪(DSR) 请求发送(RTS) 允许发送(CTS) 振铃指示5.1.3 TTL 电平到 RS-232 电平转换电路在 MCU 中,若用 RS-232 总线进行串行通信,则需外接电路实现电平转换。在发送端,需要 用驱动电路将 TTL 电平转换成 RS-232 电平; 在接收端, 需要用接收电路将 RS-232 电平转换为 TTL 电平。电平转换器不仅可以由晶体管分立元件构成,也可以直接使用集成电路。目前广泛使用 MAX232 芯片较多,该芯片使用单一+5V 电源供电实现电平转换。图 5-3 给出了 MAX232 的引脚 说明。 引脚含义简要说明如下: Vcc(16 脚) :正电源端,一般接+5V。 GND(15 脚) :地。 VS+(2 脚) :VS+=2Vcc-1.5V=8.5V。 VS-(6 脚) :VS-=-2Vcc-1.5V=-11.5V。 C2+、C2-(4、5 脚) :一般接 1?F 的电解电容 C1+、C1-(1、3 脚) :一般接 1?F 的电解电容。 输入输出引脚分两组,基本含义见表 5-2。在实际使用时,若只需要一路串行通信接口,可以 使用表 5-2 MAX232 芯片输入输出引脚分类与基本接法 组别 1 2 TTL 电平引脚 11(T1IN) 12(R1OUT) 10(T2IN) 9(R2OUT) 方向 输入 输出 输入 输出 典型接口 接 MCU 的 TXD 接 MCU 的 RXD 接 MCU 的 TXD 接 MCU 的 RXD 232 电平引脚 13 14 8 7 方向 输入 输出 输入 输出 典型接口 接到 9 芯接口的 2 脚 RXD 接到 9 芯接口的 3 脚 TXD 接到 9 芯接口的 2 脚 RXD 接到 9 芯接口的 3 脚 TXD232 电平TTL 电平T1IN R1IN R1OUT T1OUT+5V GND +16 15 14 13 12 11 10 9 MAX232CPE 1 2 3 4 5 6 7 8+ + +5V + +1? F×5TTL 电平 转为 232 电平V1图5-3 MAX232引脚图 图5-4 串行通信接口电平转换电路其中的任何一组。 焊接到 PCB 板上的 MAX232 芯片检测方法:正常情况下, (1)T1IN=5V,则 T1OUT=-9V; T1IN=0V, T1OUT=9V。 将 R1IN 与 T1OUT 相连, T1IN=5V, R1OUT=5V; T1IN=0V, 则 (2) 令 则 令 则 R1OUT=0V。 具有串行通信接口的 MCU,一般具有发送引脚(TXD)与接收引脚(RXD) ,不同公司或不 同系列的 MCU,使用的引脚缩写名可能不一致,但含义相同。串行通信接口的外围硬件电路,主 要目的是将 MCU 的发送引脚 TXD 与接收引脚 RXD 的 TTL 电平, 通过 RS-232 电平转换芯片转换 为 RS-232 电平。图 5-4 给出了基本串行通信接口的电平转换电路。 MAX232 芯片进行电平转换基本原理是: 发送过程:MCU 的 TXD(TTL 电平)经过 MAX232 的 11 脚(T1IN)送到 MAX232 内部,在内 部 TTL 电平被D提升‖为 232 电平,通过 14 脚(T1OUT)发送出去。 接收过程:外部 232 电平经过 MAX232 的 13 脚(R1IN)进入到 MAX232 的内部,在内部 232 电平被D降低‖为 TTL 电平,经过 12 脚(R1OUT)送到 MCU 的 RXD,进入 MCU 内部。 进行 MCU 的串行通信接口编程时, 只针对 MCU 的发送与接收引脚, MAX232 无关, 与 MAX232 只是起到电平转换作用。5.1.4 串行通信编程模型从基本原理角度看,串行通信接口 SCI 的主要功能是:接收时,把外部的单线输入的数据变 成一个字节的并行数据送入 MCU 内部;发送时,把需要发送的一个字节的并行数据转换为单线输 出。图 5-5 给出了一般 MCU 的 SCI 模块的功能描述。为了设置波特率 SCI 应具有波特率寄存器。 为了能够设置通信格式、是否校验、是否允许中断等,SCI 应具有控制寄存器。而要知道串口是否 有数据可收、数据是否发送出去等,需要有 SCI 状态寄存器。当然,若一个寄存器不够用,控制 与状态寄存器可能有多个。而 SCI 数据寄存器存放要发送的数据,也存放接收的数据,这并不冲 突,因为发送与接收的实际工作是通过“发送移位寄存器”和“接收移位寄存器”完成的。编程时, 程序员并不直接与“发送移位寄存器”和“接收移位寄存器”打交道,只与数据寄存器打交道,所 以 MCU 中并没有设置“发送移位寄存器”和“接收移位寄存器”的映像地址。发送时,程序员通 过判定状态寄存器的相应位,了解是否可以发送一个新的数据。若可以发送,则将待发送的数据放 入DSCI 数据寄存器‖中就可以了, 剩下的工作由 MCU 自动完成: 将数据从DSCI 数据寄存器‖送到D发 送移位寄存器‖,硬件驱动将D发送移位寄存器‖的数据一位一位地按照规定的波特率移到发送引脚 TxD,供对方接收。接收时,数据一位一位地从接收引脚 RxD 进入D接收移位寄存器‖,当收到一 个完整字节时,MCU 会自动将数据送入DSCI 数据寄存器‖,并将状态寄存器的相应位改变,供程 序员判定并取出数据。接收 引脚 RxD 接收移位寄存器 发送 引脚 TxD 发送移位寄存器15SPH 15 H MCU 的内部总线(Internal Bus) 8 7 X 0 SCI状态寄存器 SCI 控制寄存器 SCI波特率寄存器 70SCI 数据寄存器图5-5 SCI编程模型5.2 XS128的SCI模块寄存器7 本节从编程角度介绍 MCU 的 SCI 模块。该芯片有两个串行口 SCI0 和 SCI1。 从外部引脚来看,负责串行通信的是 PS0/RxD0、PS1/TxD0、PS2/RxD1、PS3/TxD1 四个引脚。当 允许 SCI 时,这些引脚作为串行通信引脚;每个串口模块包含 2 个引脚,分别称为串行发送引脚 15 TxD 和串行接收引脚 RxD。 本章以 SCI0 为例来介绍 SCI 模块, SCI1 的使用方法与 SCI0 完全相同, SPH 只是相关寄存器映像地址不同,以下统称 SCI 模块,具体使用时在头文件中区分使用哪个串口。 15 H 8 7 X0 MC9S12XS128 从程序员角度看,SCI 模块有 11 个 8 位寄存器,表 5-3 给出了主要寄存器的基本信息。只要 理解和掌握这 8 个寄存器的用法,就可以进行 SCI 编程。 下面从编程角度介绍 SCI 模块的寄存器(波特率寄存器、控制寄存器、状态寄存器和数据寄 存器) 。表 5-3 XS128 的 SCI 寄存器 地址 SCI0 $00C8 $00C9 $00CA $00CB $00CC SCI1 $00D0 $00D1 $00D2 $00D3 $00D4 寄存器名称与缩写 波特率寄存器 (SCIBDH、SCIBDL) 控制寄存器 (SCICR1、SCICR2) 访问权限 读/写 读/写 基本功能 设置波特率 设置传输格式、中断使能状态寄存器 只读 中断标志、发送与接收状态 (SCISR1、SCISR2) $00CD $00D5 $00CE $00D6 数据寄存器 读/写 收发的数据 (SCIDRH、SCIDRL) $00CF $00D7 说明:由于有两个串行口,使用 SCIx 时,寄存器名称中 SCI 改为 SCIx,x=0,1。1. SCI 波特率寄存器(SCI Baud Rate Register,SCIBDH/L) 波特率寄存器[SCIBDH:SCIBDL],分为波特率寄存器的高 8 位与低 8 位。SCIBDH 的高 3 位为 0, SCIBDH 的低 5 位与 SCIBDL 一起给出了共 13 位的串行通信分频系数 BR,其取值范围是 1~8191。 [SCIBDH:SCIBDL]不能为 0,复位时为 4。 SCIBDH:数据位 定义 复位 D7 x 0 D6 x 0 D5 x 0 D4 SBR12 0 D3 SBR11 0 D2 SBR10 0 D1 SBR9 0 D0 SBR8 0SCIBDL:数据位 定义 复位 D7 SBR7 0 D6 SBR6 0 D5 SBR5 SBR0 0 D4 SBR4 0 D3 SBR3 0 D2 SBR2 1 D1 SBR1 0 D0 SBR0 0串行通信模块的时钟源为内部总线,设 fSCI 为串行通信时钟源频率,则 fSCI=fBUS。数据手册给 出的计算 SCI 波特率 Bt 的公式为: Bt=fBUS/(16×BR) 一般情况下,内部总线频率 fBUS 是已知的,波特率 Bt 是编程者希望设定的,然后根据 fBUS、 Bt 求出 BR 的值: BR=fBUS/(16×Bt) 例 如 , fSCI=fBUS=18.6608Mhz=Hz , 希 望 设 定 波 特 率 Bt=9600 , 可 以 求 得 BR=×,转为十六进制为 0x80,则 SCIBRH=0x00,SCIDBL=0x80。要注意 遵循根据手册的要求,先写 SCIBRL 再写 SCIBRH。若是使用 SCI0,则程序如下: SCI0BDH=0x00; //先给高位赋值 SCI0BDL=0x80; //后给低位赋值 注意:若 fBUS=25Mhz,则 BR=×≈163,由于不能整除,所以有时 存在一定误差,这是允许的。 2. SCI控制寄存器1(SCI Control Register1,SCICR1)数据位 定义 复位 D7 LOOPS 0 D6 SCISWAI 0 D5 RSRC PT 0 D4 M 0 D3 WAKE 0 D2 ILT 0 D1 PE 0 D0 PT 0D7―LOOPS 位, 循环模式选择位(Loop Select Bit)。 LOOPS=1, 允许自发自收方式; LOOPS=0, 正常模式。在允许自发自收方式下,接收引脚 RxD 与 SCI 内部断开,内部发送数据直接作为接收 的输入,用于自测试。接收器的输入由 RSRC 位决定。 D6―SCISWAI 位,等待模式下 SCI 禁止位(SCI Stop in Wait Mode Bit)。SCISWAI=1,禁止 SCI 模块,即允许在 Wait 模式下停止 SCI;SCISWAI=0,允许 SCI 模块。 D5-RSRC 位,接收器资源位(Receiver Source Bit)。当 LOOPS=1 时,RSRC 位决定了接收移 位寄存器接收数据的来源。RSRC=1,RXD 引脚和 SCI 模块断开,SCI 使用 TXD 引脚来进行发送 与接收;RSRC=0,发送器的输出作为接收器的输入。 D4―M 位,模式/字符长度选择位(Data Format Mode Bit)。定义收发数据格式,M=1,9 位传 送;M=0,8 位传送。 D3―WAKE 位,唤醒方式位(Wakeup Condition Bit)。WAKE=1,地址唤醒;WAKE=0,空闲线 唤醒。 D2―ILT 位,全 1 空闲字符位计算方式位(Idle Line Type Bit),决定 SCI 何时开始计数“空闲字 符”的位数。ILTY=1,空闲字符位从“停止位”开始计数;ILTY=0,空闲字符位从“起始位”开 始计数。 D1―PE 位,奇偶校验允许位(Parity Enable Bit)。PE=1,允许奇偶校验;PE=0,不进行奇偶校 验。 D0―PT 位,奇偶校验类型选择位(Parity Type Bit)。PT=1,奇校验;PT=0,偶校验。不进行奇 偶校验时,该位无意义,一般写 0。 3. SCI控制寄存器2(SCI Control Register1,SCICR2)数据位 定义 复位 D7 TIE 0 D6 TCIE 0 D5 RIE 0 D4 ILIE 0 D3 TE 0 D2 RE 0 D1 RWU 0 D0 SBK 0D7―TIE 位,发送中断允许位(Transmitter Interrupt Enable Bit)。SCTIE=1,允许产生发送中断 请求;反之不允许。 D6―TCIE 位,发送完成中断允许位(Transmission Complete Interrupt Enable Bit)。TCIE=1,允 许发送完成产生中断;反之不允许。 D5―RIE 位,接收中断允许位(SCI Receive Interrupt Enable Bit)。SCRIE=1,允许产生接收中断 请求;反之不允许。 D4―ILIE 位,空闲线中断允许位(Idle Line Interrupt Enable Bit)。ILIE=1,允许产生空闲中断请 求;反之不允许。 D3―TE 位,发送器允许位(Transmitter Enable Bit)。TE=1,允许发送器发送;反之不允许发送 器发送。 D2―RE 位,接收器允许位(Receiver Enable Bit)。RE=1,允许接收器接收;反之不允许接收器 接收。 D1―RWU 位,接收器唤醒位(Receiver Wakeup Bit)。RWU=1,等待状态;RWU=0,正常操作。 D0―SBK 位, 发送 13 或 14 位全 0 信号(Send Break Bit)。 SBK=1, 发送终止字符(逻辑 1); SBK=0, 正在发送非终止字符。 MCU 复位后,SCI0CR2 寄存器中默认的值是全部为 0。可以看出,所有中断都是禁止的,SCI 口本身也是被禁止的,因为 TE 和 RE 位为 0。没有初始化 SCI0 口之前,SCI0 口为普通 I/O 口的输 入口,初始化 SCI0 口必须允许 SCI0 口的发送和接收,即向该寄存器写入立即数$0C 以给 TE 和 BERRM1 0 0 1 1功能 RE 位置 1。 比特错误检测电路使能 4. SCI替换状态寄存器1(SCI 在传输比特的第 9 个时钟接 1 收输入样本发生 Alternative Status Register,SCIASR1) 在传输比特的第 13 个时钟 0 接收输入样本发生 1 保留 数据位 D7 D6 D5 D4 D3 D2 D1 D0 ― ― ― ― BERRV BERRIF BKDIF 定义(只读) RXEDGIF PE 0 0 0 0 复位 0 0 0 0 0 D7―RXEDGIF 位, 接收输入活动沿中断位。 该位是确定的, 如果一个活动沿 (如果 RXPOL=0, BERRM0 0是下降沿。如果 RXPOL=1,是上升沿)在 RXD 输入出现,改位写 1 清零。该位为 0,表明接收输 入没有活动的输入发生。该位为 1,表示在接收输入没有活动沿发生。 D2―BERRV 位,比特错误位(Noise Flag)。当比特错误检测电路使能和一个期望值不匹配发生 时,BERRV 反映了 RXD 输入的状态。该位只有在 BERRIF=1 时有意义。该位为 0 时,表明一个 低输入是样本的,高输入位期望的。该位为 1,表明一个高输入是在装配值,低输入是期望值。 D1―BERRIF 位,比特错误中断标志位(Framing Error Flag)。该位是确定的,当比特错误检测 电路使能和在 RXD 的样本值和传输值不匹配时。如果 BERRIE 中断使能位被置,一个中断将会发 生。该位写 1 清零。该位为 0,表明没有不匹配值检测到。该为位 1,表明一个比匹配值发生。 D0―BKDIF 位,打断检测中断标志。该位是确定的,如果打断检测电路使能并接收到一个打 断信号时。如果 BKDIE 中断使能位被置,一个中断将会发生。该位写 1 请零。该位为 0,表明没 有打断信号接收到。为 1 时,表明有打断信号接收到。 5. SCI替换控制寄存器1 (SCI Alternative Control Register 1 ,SCIACR1)数据位 定义(只读) 复位 D7 RXEDGIE 0 ― BERRIE BKDIE 0 0 0 0 0 0,RXEDGIF 中断请求禁止。该位为 D7―RXEDGIE 位,接收输入活动沿中断使能位。该位为 0 0 D6 ― PE 0 D5 ― D4 ― D3 ― D2 D1 D01,RXEDGIF 中断请求使能。 D1―BERRIE 位,比特错误中断使能。该位使能比特错误中断标志,BERRIF,去产生中断请 求。该位为 0,表明 BERRIF 中断请求禁止。该位为 1,表明 BERRIF 中断请求使能。 D0―位,打断检测中断使能。该位使能打断检测中断位,BKDIF,去生成中断请求。该位为 0, BKDIF 中断请求禁止。该位为 1,表明 BKDIF 中断请求使能。 6. SCI替换控制寄存器2 (SCI Alternative Control Register 2,SCIACR2)数据位 定义(只读) 复位 D7 ― 0 D6 ― PE 0 D5 ― 0 D4 ― 0 D3 ― 0 0 D2 BERRM1 0 D1 BERRM0 0 D0 BKDF 0D2,D1―比特错误模式。这两个位决定比特错误检测特征功能。见表 5-4。. D0―打断检测特征使能位。该位使能打断检测电路。该位为 0 打断检测电路禁止,该位为 1 打断电路使能。表 5-4 比特错误检测特征功能表7. SCI状态寄存器1(SCI Status Register,SCISR1)数据 位 定义 (只读) 复位 D7 TDRE 1 D6 TC PE 1 D5 RDRF 0 D4 IDLE 0 D3 OR D2 NF D1 FE D0 PF0 0 0 0 0 D7―TDRE 位, 发送数据寄存器空标志位(Transmit Data Register Empty Flag)。 该位为 1 时表明 要发送的数据已经移入发送移位寄存器,数据寄存器(SCIDRH/SCIDRL)为空,可以发送一个新的 数据。 D6―TC 位,发送完成标志位(Transmit Complete Flag)。该位为 1,表明发送已经完成,该位为 0,表明发送正在进行。 D5―RDRF 位,接收数据寄存器满标志位(Receive Data Register Full Flag)。该位为 1,表明接 收器已满,可以从 SCI 数据寄存器 SCIDRH/SCIDRL 中读取收到的数据。 D4―IDLE 位,线路空闲标志位(Idle Line Flag)。当接收 10 个连续的逻辑 1(M=0)或接收 11 个 连续的逻辑 1(M=1)时,IDLE 位即被设置为 1。IDLE=1 表明接收器处于空闲状态。注意当接收唤 醒位 RWU=1 时,空闲线的状态不能影响 IDLE 位。 D3―OR 位,溢出标志位(Overrun Bit)。该位为 1,表明接收器溢出。 D2―NF 位,噪声标志位(Noise Flag)。该位为 1,表明接收器出现噪声错误。 D1―FE 位,帧错误标志位(Framing Error Flag)。该位为 1,表明接收器出现帧错误。 D0―PF 位,奇偶错误标志位(Parity Error Flag)。该位为 1,表明接收器出现奇偶校验错误。该 位写无效。 8. SCI状态寄存器2(SCI Status Register,SCISR2)数据位 定义 复位 D7 AMAP 0 D6 ― 0 D5 ― 0 D4 TXPOL 0 D3 RXPOL 0 D2 BK13 0 D1 TXDIR 0 D0 RAF 0D7―AMAP 位,该位控制哪些共享相同地址空间的寄存器是可访问的。在复位条件下,串口 的功能表现为之前的版本。设置改为位 1,允许访问另一个系列的控制和状态寄存器并波特率和控 制寄存器 1。AMAP=0,SCIBDH (0x0000),SCIBDL (0x0001), SCICR1 (0x0002)标记的寄存器是可访 问的。AMAP=1,SCIASR1 (0x0000),SCIACR1 (0x0001), SCIACR2 (0x00002)标记的寄存器是可访 问的。 D6~D5,未定义。 D4―TXPOL,发送极性位。该位控制发送数据的极性。在正常模式 NRZ 格式下,1 表示高, 0 表示低。在反转极性下刚好相反 TXPOL=0,正常极性。TXPOL=1,反转极性。 D3―RXPOL,接收极性位。RXPOL=0,正常极性。RXPOL=0,反转极性。 D2―BK13 位,终止码标志位(Break Transmit character length)。BK13=1,终止码长度为 13 或 14 位;BK13=0,终止码长度为 10 或 11 位。帧错误不受该位的影响。 D1―TXDIR 位,单线模式下发送引脚的数据传输方向位(Transmitter pin data direction in Single-Wire mode)。 在单线模式下, 该位用来决定 TxD 引脚用于发送数据还是接收数据。 TXDIR=1, 表明 TxD 用于发送数据;TXDIR=0,表明 TxD 用于接收数据。所谓单线模式就是将 RxD 与 SCI 断开, 只使用 TxD 发送和接收数据, 并且由 TXDIR 位决定是发送还是接收。 LOOPS=1、 当 RSRC=1 时,使能单线模式。 D0-RAF 位,接收进行标志位(Receiver Active Flag)。该位为 1,表明正在接收。 9. SCI数据寄存器(SCI Data Register,SCIDRH/L) SCI 数据寄存器[SCIDRH:SCIDRL]。当使用 8 位数据格式时,只使用 SCIDRL 寄存器。当使用 9 位数据格式发送数据时,先写 SCIDRH 寄存器,再写 SCIDRL 寄存器。 SCIDRH:数据位 读操作 写操作 复位 D7 R8 ― 0 D6 ― T8 0 D5 0 ― 0 D4 0 ― 0 D3 0 ― 0 D2 0 ― 0 D1 0 ― 0 D0 0 ― 0 SCIDRL:数据位 读操作 写操作 复位 D7 R7 T7 0 D6 R6 T6 0 D5 R5 T5 0 D4 R4 T4 0 D3 R3 T3 0 D2 R2 T2 0 D1 R1 T1 0 D0 R0 T0 0SCIDRH:只有 D7、D6 被定义,分别记为 R8、T8。当 SCI 配置为 9 位数据格式(M=1)时,R8 为收到的第 9 位数据,T8 则存放要发送的第 9 位数据。 SCIDRL:读出时,为接收的数据,记作 R7~R0;写入时,为要发送的数据,记作 T7~T0。5.3 XS128的SCI构件设计与测试无论用查询方式还是中断方式进行串行通信编程,在程序初始化时均必须对 SCI 进行初始化, 主要进行波特率设置、通信格式的设置、发送接收数据方式的设置等。本小节给出最基本的方法, 作为 S12X 系列 MCU 的串行通信编程入门知识。下一小节将给出规范的串行通信编程子程序,读 者可以直接将其应用于实际的嵌入式应用系统的开发中。5.3.1 SCI 初始化有关寄存器地址的定义已经在头文件 MC9S12XS128.h 中给出,SCIBDH、SCIBDL、SCICR1、 SCICR2、SCISR1、SCISR2、SCISDRH、SCISDRL 等接口可以直接使用。 对 SCI 进行初始化,最少由以下三步构成(以 SCI0 为例): 第一步定义波特率。一般选择内部总线时钟为串行通信的时钟源。设 MCU 系统初始化时已定 义总线频率为 fBUS, 同时准备定义串行通信波特率记为为 Bt, 可通过设置 SCI 波特率寄存器 SCI0BD 的波特率选择位 SBR[12:0](13 位)以便选择合适的分频系数,代入公式 Bt=fBUS/(16× SCI0BD) , 使得 Bt 等于预设的波特率值。 这里举例说明, 设总线频率 fBUS=32Mhz, 准备定义波特率 Bt=9600, 则由公式 Bt=fBUS/(16× BR)可以得到 SCI0BD≈208,则 SCI0BD 的值应为二进制“” , 即 SCI0BDL=$D0,SCI0BDH=$00,程序如下。 //总线频率 fBUS=32MHz,定义波特率 Bt=9600(针对 SCI0) SCI0BDH=0x00; //需先给给高位赋值 SCI0BDL=0x80; //后给低位赋值 第二步写控制字到 SCI 控制寄存器 1(SCI0CR1) 。设置是否允许 SCI、数据长度、输出格式、 选择唤醒方法、是否校验等。如若设定允许 SCI、正常码输出、8 位数据、无校验,则 SCI0CR1 取值应为二进制“” ,程序如下。 //设置允许 SCI,正常码输出、8 位数据、无校验 SCI0CR1=0x00; 实际上,这种情况只要取 SCI0CR1 各位的默认值即可。 第三步写控制字到 SCI 控制寄存器 2(SCI0CR2) 。设置是否允许发送与接收、是中断接收还 是查询接收等。如若设置允许发送(TE=1) 、允许接收(RE=1) 、查询方式收发,则 SCI0CR2 取值 应为二进制“” ,程序如下: //设置允许发送、允许接收,查询方式收发 SCI0CR2=0x0C; 另外几个寄存器供后面编程使用,不需初始化。 5.3.2 发送一个数据与接收一个数据一般情况下,对 SCI 的初始化仅在程序的初始化部分进行一次即可,而串行通信的基本用途 就是编程来发送与接收数据。 发送数据是通过判断状态寄存器 SCI0SR1 的第 7 位 (TDRE) 进行的, 而接收数据是通过判断状态寄存器 SCI0SR1 的第 5 位(RDRF)进行的。不论是发送还是接收,均 会使用 SCI 数据寄存器 SCI0DRL。 发送时将要发送的数据送入 SCI0DRL 即可, 接收时从 SCI0DRL 中取出的即是收到的数据。 例如, 下面的程序将字节型变量 i 中的数从串行引脚 TxD 发送出去。 通过对状态寄存器 SCI0SR1 的第 7 位(TDRE)判断是否可以向数据寄存器 SCI0DRL 送数,若 TDRE=1 可以送数,否则必须 等待。 //判断 SCI0SR1 的第 7 位(TDRE)是否为 1,是 1 则可以发送数据 Data while(1) if ((SCI0SR1 &(1&&7)) != 0) // SCI0SR1.7=0?为 0 则等待 { // SCI0SR1.7=1,可以发送数据 SCI0DRL =i; } 要以查询方式接收一个数据,首先通过状态寄存器 SCI0SR1 的第 5 位(RDRF)判断有没有数 据可收,若 RDRF=1 则有数据可收,下面程序持续等待串行口(实际上是 RxD 引脚)接收一个字 节数据。 //查询方式接收一个字节的数据放入字节型变量 i 中: while(1) if ((SCI0SR1 &(1&&5)) != 0) // SCI0SR1.5=0?为 0 则等待 { // SCI0SR1.5=1,可以取出数据 i = SCI0DRL; } 在实际编写串行通信接收子函数时,不采用永久循环形式,而改用测试一段时间,若无数据可 接收,则带错误标志返回。5.3.3 SCI 构件SCI 具有初始化、接收和发送三种基本操作。按照构件的思想,可将它们封装成几个独立的功 能函数,初始化函数完成对 SCI 模块的工作属性的设定,接收和发送功能函数则完成实际的通信 任务。对 SCI 模块进行编程,实际上已经涉及到对硬件底层寄存器的直接操作,因此,可将初始 化、接收和发送三种基本操作所对应的功能函数共同放置在命名为 SCI.c 的文件中,并按照相对严 格的构件设计原则对其进行封装,同时配以命名为 SCI.h 的头文件,用来定义模块的基本信息和对 外接口。 头文件 SCI.h 中的内容可分为两个主要的部分, 它们分别是 5 个函数原型的声明和外设模块寄 存器相关信息的定义。前者给出了本 SCI 构件对上层构件或软件所提供的接口函数,而后者则指 明了本“元构件”与具体硬件相关的信息。 串行通信头文件 SCI.h 含有串行通信寄存器和标志位定义,以及串行通信相关函数声明,下表 简要给出了它的主要内容。以初始化函数 SCIInit 为例,通道号、当前的系统时钟、希望实现的通 信波特率以及初始化时是否使能中断,都被设计为函数参数。这样的话,应用程序和上层构件在使 用(调用)它时,将具有极大的灵活性。文件还给出了必要的硬件相关信息,当要把该构件移植到 其他芯片时,就必须检查并修改这些信息。5.3.4 编程实例1.查询方式的串行通信测试工程实例 (1)硬件连接 接 PC 机串口 (2)具体实现 SCI0 模块首先向 PC 机发送字符串 “Hello! World!” 然后等待接收 PC 机从串口发送来的数据, , 若成功接收到 1 个数据 (调用 SCIRe1 函数接收数据)则立即将该数据回发给 PC 机 , (调用 SCISend1 函数发送数据) ,随后继续等待接收 1 个数据并回发,如此循环。 注:使用的波特率为 9600,并使用 SCI0 和 PC 机通信 该实例的详细代码可随书资料。 2.中断方式的串行通信测试工程实例 (1)硬件连接 接 PC 机串口 (2)具体实现 PC 机向 XS128 发送数据,XS128 收到后返回。 该实例的详细代码可参阅附带的代码文件。5.4 XS128的中断源与第一个带有中断的编程实例5.4.1 中断与异常的通用知识中断是 MCU 实时地处理内部或外部事件的一种内部机制。当某种内部或外部事件发生时,中 断系统将迫使 CPU 暂停正在执行的程序,转而去进行中断事件的处理,中断处理完毕后,又返回 被中断的程序处,继续执行下去。实际上中断提供了一种方法来保存当前 CPU 状态和寄存器,转 而执行中断服务子程序,然后恢复 CPU 状态,以便返回执行中断之前的处理状态。与只是程序指 令的软件中断不同,中断由硬件事件触发。 中断的处理过程一般为:关中断(在此中断处理完成前,不处理其它中断) 、保护现场、执行 中断服务程序、恢复现场、开中断等。 异常是 CPU 强行从正常的程序执行切换到由某些内部或外部条件所要求的处理任务上去,这 些任务是优先于处理器正在执行的任务的。引起异常的外部条件是来自外围设备、硬件断点请求、 访问错误和复位等;引起异常的内部条件是指令、不对界错误、违反特权级和跟踪等。许多处理器 把硬件复位和硬件中断都归类为异常, 把硬件复位看作是一种具有最高优先级的异常; 把来自外围 设备的强行任务切换请求称为中断。处理器对复位、中断、异常具有同样的处理过程,在谈及这个 处理过程时统称为异常。 处理器在指令流水线的译码或者执行阶段识别异常, 若检测到一个异常, 则强行中止后面尚未 流到该阶段的指令。 对于在指令译码阶段检测到的异常, 以及对于与执行阶段有关的指令异常来说, 由于引起的异常与该指令本身无关, 指令并没有得到正确执行, 所以为该类异常保存的程序计数器 的值指向引起该异常的指令,以便异常返回后重新执行。对于中断和跟踪异常,异常与指令本身有 关,处理器在执行完当前指令后才识别和检测这类异常,故为该类异常保存的 PC 值是指向要执行 的下一条指令。5.4.2 XS128 的中断机制详解1.XS128的XINT中断解析模块 在 S12X 系列的微控制器中都有一个 XINT 模块,该模块主要用于解析中断请求的优先级并且将中 断向量交给 CPU(对于 S12XS 系列而言只有 CPU,其它如 XE 系列还存在 XGATE,可以完成中断的 处理)执行。 XINT 相关配置寄存器如下: 1 ○ 中断向量基址寄存器( Interrupt Vector Base Register,INT_CFADDR )数据 位 定义 复位 D7 1 D6 1 D5 1 D4 D3 D2 1 D1 1 D0 1 IVB_ADDR[7:0] 1 1Interrupt Vector Base Register,简写为 IVBR。该寄存器用于设定中断向量地址的高位的值,比如说 位于 0xFF10~0xFFFE 的向量的高位地址为 0xFF,那么 IVBR 寄存器的值就为 0xFF。一般情况下这个 寄存器不需要设置,只有当中断向量被移动到其他地址的时候,这个寄存器才需要设值。 2 ○ 中断请求配置地址寄存器( Interrupt Request Configuration Address Register,IRCAR ) D D D D D D D D 数据 0 2 0 1 0 0 0 定义 7 INT_CFADDR[7:4] 6 5 4 3 位 0 0 0 1 0 0 0 0 复位 这个寄存器和下面的 INT_CFDATA0C7 这 8 个寄存器配合使用, 用来索引默认的 128 个中断向量地 址。具体的使用会在 5.4.4 的中断编程实例中说明。 3 ○ 中断请求配置数据寄存器( Interrupt Request Configuration Data Registers,INT_CFDATA0C7 ) INT_CFDATA0:数据位 定义 复位 7 RQST 0 6 0 0 5 0 0 4 0 0 3 0 0 2 0 1 PRIOLVL[2:0] 0 0 1INT_CFDATA1:数据位 定义 复位 7 RQST 0 6 0 0 5 0 0 4 0 0 3 0 0 2 0 1 PRIOLVL[2:0] 0 0 1INT_CFDATA2:数据位 定义 复位 7 RQST 0 6 0 0 5 0 0 4 0 0 3 0 0 2 0 1 PRIOLVL[2:0] 0 0 1INT_CFDATA3:数据位 定义 复位 7 RQST 0 6 0 0 5 0 0 4 0 0 3 0 0 2 0 1 PRIOLVL[2:0] 0 0 1INT_CFDATA4:数据位 定义 复位 7 RQST 0 6 0 0 5 0 0 4 0 0 3 0 0 2 0 1 PRIOLVL[2:0] 0 0 1 INT_CFDATA5:数据位 定义 复位 7 RQST 0 6 0 0 5 0 0 4 0 0 3 0 0 2 0 1 PRIOLVL[2:0] 0 0 1INT_CFDATA6:数据位 定义 复位 7 RQST 0 6 0 0 5 0 0 4 0 0 3 0 0 2 0 1 PRIOLVL[2:0] 0 0 1INT_CFDATA7:数据位 定义 复位 7 RQST 0 6 0 0 5 0 0 4 0 0 3 0 0 2 0 1 PRIOLVL[2:0] 0 0 1这 8 个寄存器中的第 7 位,RQST 用于设定中断是由 CPU 处理还是由 XGATE 处理。 RQST=0, 当 CPU 来处理中断,当 RQST=1,XGATE 来处理中断。对于 XS128 而言,它没有 XGATE,所以该位 不需要配置,默认位 0 就可以了。 低三位 PRIOLVL[2:0]用于设定优先级。优先级的情况可以参见表 5-5。表5-5 中断优先级对照表 优先级 低 PRIOLVL2 0 0 0 0 1 1 1 高 1 PRIOLVL2 0 0 1 1 0 0 1 1 PRIOLVL2 0 1 0 1 0 1 0 1 意义 中断请求被关 中断等级1 中断等级2 中断等级3 中断等级4 中断等级5 中断等级6 中断等级7注:INT_CFDATA0-7 这 8 个寄存器一次可以设定 8 个中断向量优先等级,而中断请求配置地 址寄存器 INT_CFADDR 的高 4 位 INT_CFADDR[7:4]可以设定=16 个地址,那么 16*8=128。即 INT_CFADDR 和 INT_CFDATA0-7 进行组合可以设定 128 个向量的优先级, 这个刚好和 S12X 系列 的中断向量表(可参见 5.4.2 第 3 小节)是对应的。采用这样的一个机制设定优先级是为了和 S12 系列保持兼容。 2.XS128的中断执行过程 XS128 与大多其他 MCU 一样,如果在使能的中断源中发生一个事件,与之关联的只读的中断状态 标志会被置位。只有程序开放 CPU 总中断(条件码寄存器 CCR 中的全局中断屏蔽 I 位为 0) ,中断才会 被响应。复位后,I 被自动初始化为 1(禁止中断) ,屏蔽了所有可屏蔽中断源。用户程序在清除 I 位以 允许 CPU 响应中断之前必须初始化堆栈指针和完成系统其他设置。 当 CPU 响应中断时,I 位自动置 1,以避免其他中断打断中断服务例程 ISR(即中断嵌套) 。通常, 从中断服务例程 ISR 返回时,CCR 中的 I 位恢复成 0。若 I=0 时,若两个或更多中断等待时,高优先级 的中断源被首先服务。在很少的情况下,若 I 位在 ISR 中被清除,这就开放了总中断,允许中断嵌套, 这种编程方式,初学者一般不使用。这种方法容易导致难于调试的隐蔽错误,只有编程经验丰富的工程 师在特别需要的情况下才使用。 在编程时,在中断服务例程 ISR 开始的地方最好有清除中断标志语句,这样该中断源若有新的一 次中断请求,也不会被遗漏,但新的中断请求只有等到当前 ISR 完成之后才会得到响应。 中断发生时,CPU 内部寄存器被自动保存在堆栈中。在中断之前,堆栈指针 SP 指向了堆栈中下一 个有效的字节位置。CPU 中寄存器 PC、Y、X、D、CCR 依次入栈,入栈之后,SP 指向堆栈中的下一 个有效位置,这是一个比保存条件码寄存器 CCR 的地址小 1 的地址。入栈的 PC 值是主程序中在中断 返回时将执行的下一条指令所在地址。中断服务子程序以一条中断返回指令 RTI 结束。执行 RTI 指令 时中断返回,此时,堆栈中保存的值以相反的顺序从堆栈中恢复到 CCR、D、X、Y、PC 中。图 5-6 给 出了中断过程 CPU 中寄存器进出栈情况。(注:这里的 D 是指 A+B)图5-6 中断过程CPU寄存器进出栈情况XS128 的中断过程详细描述如下: CPU 每执行完一条指令,若程序有开放某些中断及总中断(使用 CLI 指令) ,则 CPU 按照优 先级次序查询所有中断标志位,若某个中断已发生,则响应该中断请求。当 CPU 收到一个许可的 中断请求,它在相应中断之前要完成当前指令。中断顺序遵守与 SWI 指令相同的循环顺序,包括: (1)在堆栈中保存 CPU 寄存器――CPU 内的寄存器 PC、Y、X、D、CCR 依次进栈。 (2)CCR 中的 I 位置 1, 即自动关总中断 (即相当于自动执行 SEI 指令) 防止其他中断进入。 , (3)在目前等待的中断中取出最高优先级中断的中断向量,从相应的中断向量地址取出中断 向量(即中断服务程序的入口地址)送给 PC。 (4)执行中断服务程序,直到执行中断返回指令 RTI。RTI 指令从堆栈中依次弹出 CCR、D、 X、Y、PC,使 CPU 返回原来中断处继续执行。 (5)若中断过程也允许响应新的中断,可在中断服务程序中用 CLI 指令开放中断。一般不建 议这样做,可用其他编程技巧处理相关问题。 3.XS128的中断优先级 在 XS128 中存在有 8 个等级。第 0 等级表示中断关闭,其他 1 到 7,优先级逐步提高,这个可 以参见表 5-5。 而设定优先级是通过 INT_CFADDR 和 INT_CFDATA0-7 这两个寄存器进行设定的。在这里, 将结合下面的中断代码,解释如何配合使用这两类寄存器设定优先级。const tIsrFunc _InterruptVectorTable[] @0xFF10 = { /* ISR name No. Address Pri isr_default, /* 0x08 0xFF10 isr_default, /* 0x09 0xFF12 isr_default, /* 0x0A 0xFF14 1 isr_default, /* 0x0B 0xFF16 1 isr_default, /* 0x0C 0xFF18 1 isr_default, /* 0x0D 0xFF1A 1 isr_default, /* 0x0E 0xFF1C 1 Name ivVsi ivVsyscall ivVReserved118 ivVReserved117 ivVReserved116 ivVReserved115 ivVReserved114 */ */ */ */ */ */ */ */ 。。。 。。。部分代码已省略 isr_default, isr_default, isr_default, isr_default, isr_default, isr_default, isr_default, isr_default, isr_default, SCI0_Recv, isr_default, isr_default, isr_default, isrTimOver, isr_default, /* 0x62 /* 0x63 /* 0x64 /* 0x65 /* 0x66 /* 0x67 /* 0x68 /* 0x69 /* 0x6A /* 0x6B /* 0x6C /* 0x6D /* 0x6E /* 0x6F /* 0x70 0xFFC4 1 ivVcrgscm */ 0xFFC6 1 ivVcrgplllck */ 0xFFC8 1 ivVReserved27 */ 0xFFCA 1 ivVReserved26 */ 0xFFCC 1 ivVporth */ 0xFFCE 1 ivVportj */ 0xFFD0 1 ivVReserved23 */ 0xFFD2 1 ivVatd0 */ 0xFFD4 1 ivVsci1 */ 0xFFD6 1 ivVsci0 */ 0xFFD8 1 ivVspi0 */ 0xFFDA 1 ivVtimpaie */ 0xFFDC 1 ivVtimpaaovf */ 0xFFDE 1 ivVtimovf */ 0xFFE0 1 ivVtimch7 */上面这段代码是来自工程 isr.c 文件中(读者可以从附带得光盘中获得) 。通过观察我们可以发 现相邻的两个中断向量地址间隔为 2,那么从 0~F 就有 8 个向量点,这个 8 和 XS128 具有的 INT_CFDATA0-7 这 8 个寄存器是对应的。下面举例说明:对于第一个中断 ivVsi,它的地址为 0xFF10,如果要设定它的优先级的话,需要先设定 INT_CFADDR 这个寄存器的值为 0x10,然后给 INT_CFDATA0 这个寄存器赋值来设定优先级。对于第二个中断 ivVsyscall,它的地址为 0xFF12, 如果要设定它的优先级的话,需要先设定 INT_CFADDR 这个寄存器的值也为 0x10,然后给 INT_CFDATA1 这个寄存器赋值来设定优先级。接下来的 6 个中断依次设定相应的 INT_CFDATAx 寄存器。到下面的中断地址 0xFF20 的时候,INT_CFADDR 这个寄存器的值就为 0x20 了。 一次类 推,对于串口 0 接受中断 ivVsci0,地址为 0xFFD6,那么只要先设定 INT_CFADDR 寄存器的值为 0xD0,再设定 INT_CFDATA3 这个寄存器就可以完成优先级的设定了,如果你明白这里面为什么 是 INT_CFDATA3 这个寄存器,那么你就懂了。图5-7 中断优先级执行流程图如图 5-7 所示,是中断优先级的执行流程图。首先 L0(代表等级 0) ,然后有高等级中断 L3 发生,转入 L3,在 L3 的执行过程中,有更高等级中断 L7 发生,转入 L7 的运行,当 L7 运行完毕, 转而执行 L3,而这个时候有优先级为 L2 的中断发生,比将要执行的 L1 高,于是执行 L2,然后 L1,再到 L0,执行完毕,RTI 返回。 4.XS128的中断源与中断向量表 XS128 的中断向量如表 5-6 所示。表 5-6 XS128 的中断源与中断向量表 向量地址 Vector base + $F8 Vector base + $F6 Vector base + $F4 Vector base + $F2 Vector base + $F0 Vector base + $EE Vector base + $EC Vector base + $EA Vector base + $E8 Vector base + $E6 Vector base + $E4 Vector base + $E2 Vector base + $E0 Vector base + $DE Vector base + $DC Vector base + $DA Vector base + $D8 Vector base + $D6 中断源 Unimplemented instruction trap SWI XIRQ IRQ Real time interrupt TIM timer channel 0 TIM timer channel 1 TIM timer channel 2 TIM timer channel 3 TIM timer channel 4 TIM timer channel 5 TIM timer channel 6 TIM timer channel 7 TIM timer overflow TIM Pulse accumulator A overflow TIM Pulse accumulator input edge SPI0 SCI0 CCR 掩码 None None X Bit 1 Bit 1 Bit 1 Bit 1 Bit 1 Bit 1 Bit 1 Bit 1 Bit 1 Bit 1 Bit 1 Bit 1 Bit 1 Bit 1 Bit 1 Bit 本地使能 None None None IRQCR (IRQEN) CRGINT (RTIE) TIE (C0I) TIE (C1I) TIE (C2I) TIE (C3I) TIE (C4I) TIE (C5I) TIE (C6I) TIE (C7I) TSRC2 (TOF) PACTL (PAOVI) PACTL (PAI) SPI0CR1 (SPIE, SPTIE) SCI0CR2 (TIE, TCIE, RIE, ILIE) SCI1CR2 (TIE, TCIE, RIE, ILIE) ATD0CTL2 (ASCIE) 停止唤 等待唤 醒 醒 ― ― ― ― Yes Yes Yes Yes Refer to CRG interrupt section No Yes No Yes No Yes No Yes No Yes No Yes No Yes No Yes No Yes No Yes No Yes Yes YesVector base + $D4SCI11 BitYesYesVector base + $FD2 Vector base + $D0 Vector base + $CE Vector base + $CC Vector base + $CA Vector base + $C8 Vector base + $C6 Vector base + $C4 Vector base + $C2 To Vector base + $BC Vector base + $BA Vector base + $B8 Vector base + $B6 Vector base + $B4 Vector base + $B2 Vector base + $B0 Vector base + $AE ToATD01 BitYesYesPort J Port HCRG PLL lock CRG self-clock mode预留 1 Bit PIEJ(PIEJ7-PIEJ0) 1 Bit PIEH (PIEH7-PIEH0) 预留 预留 1 Bit CRGINT(LOCKIE) 1 Bit CRGINT (SCMIE)Yes YesYes YesRefer to CRG interrupt section Refer to CRG interrupt section预留 FLASH Fault Detect FLASH CAN0 wake-up CAN0 errors CAN0 receive CAN0 transmit 1 Bit 1 Bit 1 Bit 1 Bit 1 Bit 1 Bit FCNFG2 (SFDIE, DFDIE) FCNFG (CCIE) CAN0RIER (WUPIE) CAN0RIER (CSCIE, OVRIE) CAN0RIER(RXFIE) CAN0TIER (TXEIE[2:0]) No No Yes No No No No Yes Yes Yes Yes Yes预留 Vector base + $90 Vector base + $8E Vector base + $8C Vector base + $8A To Vector base + $82 Vector base + $80 Vector base + $7E Vector base + $7C Vector base + $7A Vector base + $78 Vector base + $76 Vector base + $74 Vector base + $72 To Vector base + $40 Vector base + $3E Vector base + $3C To Vector base + $14 Vector base + $12 Vector base + $10Port P Interrupt PWM emergency shutdown1 Bit 1 Bit 预留PIEP (PIEP7-PIEP0) PWMSDN (PWMIE)Yes NoYes YesLow-voltage interrupt (LVI) Autonomous periodical interrupt (API) High Temperature Interrupt(HTI) Periodic interrupt timer channel 0 Periodic interrupt timer channel 1 Periodic interrupt timer channel 2 Periodic interrupt timer channel 31 Bit 1 Bit 1 Bit 1 Bit 1 Bit 1 Bit 1 Bit 预留VREGCTRL (LVIE) VREGAPICTRL (APIE) VREGHTCL(HTIE) PITINTE (PINTE0) PITINTE (PINTE1) PITINTE (PINTE2) PITINTE (PINTE3)No Yes No No No No NoYes Yes Yes Yes Yes Yes YesATD0 Compare Interrupt1 BitATD0CTL2 (ACMPIE)YesYes预留 System Call Interrupt (SYS) ― Spurious interrupt ― 16 位向量地址基址 None None ― ― ― ―5.4.3 XS128 的中断编程方法这里的 XS128 中断仅是在 SCI,涉及其他模块的中断的应用方法会在后续章节之中分别介绍。 在 XS128 之中, 其中有些步骤可由芯片内部机制自行完成。 SCI 采用中断方式收发数据时, 当 需要编写中断处理程序。在 CW 环境下使用 XS128 芯片中断的步骤是: (1)在 main.c 中,依照D关总中断→开模块中断→开总中断‖的顺序打开模块中断; (2)在 isr.c 文件中,编写中断服务程序,修改中断向量表; XS128 MCU 开始运行后,要关闭总中断,它就相当于一个总闸门,如果总闸不开,所有中断 都不可能发生。这需要汇编指令来实现: SEI //关总中断 CLI //开总中断 为了方便代码移植,在 MCUInit.h 文件中做了如下定义: #define EnableInterrupts() asm(&CLI&) //开放总中断 #define DisableInterrupts() asm(&SEI&) //禁止总中断 XS128 的中断编程的可概括为下述 3 个步骤: (1)新建(或者复制)一个 isr.c 文件,并加入工程中。 (2)定义中断向量表(复制 isr.c 的应修改中断向量表) 。 在 XS128 的 Flash 地址空间中,有一段是用来存储所有的中断矢量,通常放在最后的 Flash 页 面上。 该区域每两个字节存储的是一个中断处理函数的地址, 各个中断处理函数的地址共同组成一 个逻辑上十分规则的区域――中断向量表。 XS128 的中断向量表如下所示: /* 未定义的中断处理函数,本函数不能删除,默认 */ __interrupt void isr_default(void) { DisableInterrupt(); /* Write your interrupt code here ... */ EnableInterrupt(); } //中断矢量表,如果需要定义其它中断函数,请修改下表中的相应ISR_func_t const ISR_func_t ISR_vectors[] @0xFF10= { /* ISR name No. Address Pri Name */ isr_default, /* 0x08 0xFF10 ivVsi */ isr_default, /* 0x09 0xFF12 ivVsyscall */ isr_default, /* 0x0A 0xFF14 1 ivVReserved118 */ isr_default, /* 0x0B 0xFF16 1 ivVReserved117 */ isr_default, /* 0x0C 0xFF18 1 ivVReserved116 */ isr_default, /* 0x0D 0xFF1A 1 ivVReserved115 */ //此处略去若干中断源。 isr_default /* 0x7C 0xFFF8 ivVtrap */ // RESET defined in Project.prm };中断向量表是一个指针数组,内容是中断函数的地址。 首先要定义该中断向量表的地址,XS128 的中断向量从 0xFF10 开始(不同的 MCU 中断矢量 起始地址是不相同的,使用时需要查阅相关的技术手册) ,要使用预编译指令将中断向量表的首地 址定义在 0xFF10。 中断向量表格式:const tIsrFunc _InterruptVectorTable[] @0xFF10 == {中断处理函数名,中断处理函 数名……}。其中 tIsrFunc 的定义为:typedef void (*near tIsrFunc)(void) 。 中断向量表内容,是从中断向量表起始地址开始顺序增加,均与 Flash 的中断向量地址相对应,如 果某个中断不需要使用,要将在数组对应的项中填入 isr_default。isr_default ()是中断向量表中不需要使 用的中断填入的函数,它是一个空函数。参见 5.4.3 节中断处理函数文件(isr.c)之中的 isr_default ()函 数定义。 (3)定义 ISR 并在中断向量表中填入相应 ISR 的名称。如中断处理函数文件(isr.c)之中的函数 interrupt void SCI0_Recv(void)的定义。//串行接受中断 __interrupt void SCI0_Recv(void) { uint8 uint8 SerialBuff[1]; DisableInterrupt(); i = SCIReN(0,1,SerialBuff); if (i == 0) SCISendN(0,1,SerialBuff); EnableInterrupt(); }//禁止总中断 //等待接收1个数据 //发送接到的数据 //开放总中断通过上述 3 个步骤,就可以定义好所需要的中断了。在实际编程中,可以直接从给定的 C 工程框 架中得到Disr.c‖文件,该文件中只定义了一个空中断处理函数Disr_default‖,和由这个空函数名组成的中 断向量表。用户只须定义所需的中断处理函数,并用该函数名代替向量表中相应位置上的Disr_default‖ 即可。 (4)在主函数中打开中断模块中断,再打开总中断。5.4.4 XS128 的中断优先级编程示例对于需要设定优先级的工程,其实相比于普通中断例程其实就是多了一个中断优先级的设定过程。 具体设定优先级的方法在 5.4.2 第 3 小节已经介绍了,在这里我们只附上代码加以说明。 在随书光盘中附有中断优先级的例程。在这个例程中共有 3 个中断,PIT 中断,串口中断,定时器 中断。//0.1 主程序使用的变量定义 uint32 mRuncount=0; //运行计数器 //0.2 关总中断 DisableInterrupt(); //0.3 芯片初始化 MCUInit(); //0.4 模块初始化 Light_Init(Light_Run_PORT,Light_Run,Light_OFF); //RUN指示灯初始化 SCIInit(0,SYSTEM_CLOCK,9600); //串口0初始化 SCISendN(0,14,msg); //串口发送&Hello! World!& PITInit(); //定时器PIT初始化 TimerInit(); //定时器Timer初始化 //0.5 中断优先级 IntP(Vtimovf,1); //(1)定时器Timer溢出中断优先级为1 IntP(Vpit0,3); //(2)定时器PIT0中断优先级为3 IntP(Vsci0,6); //(3)串口0接收中断优先级为6 //0.6 开放中断 EnableSCIReInt0; EnableT EnablePIT0; EnableInterrupt();//开放SCI0接收中断 //开放Timer定时器中断 //开放定时器0溢出中断 //开放总中断为了处理中断优先级,代码中我们增加了 INTP.H 和 INTP.C 用于中断优先级的处理。上述代码中 的 IntP 函数就在这两个文件中定义,具体代码可参见随书光盘。 在主函数中的初始化函数中设定这几个中断的优先级。设定 PIT 的优先级为 3,串口的中断优先级 为 6,定时器的优先级为 1。具体设定代码如下: (下面仅列出串口的优先级设定代码,其他类似)IntP(Vsci0,6); //(3)串口0接收中断优先级为6其实相当于下面的两句代码: INT_CFADDR = 0xD0; INT_CFDATA2=6; 即 Vsci0 其实等于 0x0000FFD6, 那么其也等于 0xFFD6, 更具上面的讲解分析可以得到 0xD0 和 6。 这样只要串口中断发生,不管前边有其它什么定时器中断还是 PIT 中断,都会被强制挂起,执行串 口中断。读者可以把玩一下这个例程的代码,这样会对优先级的执行过程有一个更深刻的理解。 第 5 章 串行通信接口 SCI第5章 串行通信接口SCI目前几乎所有的台式电脑都带有 9 芯的异步串行通信口,简称串行口或 COM 口。由于历史的原因, 通常所说的串行通信就是指异步串行通信。USB、以太网等也用串行方式通信,但与这里所说的异步串 行通信物理机制不同。 有的台式电脑带有两个串行口 COM1 和 COM2, 部分笔记本电脑也带有串行口。 随着 USB 接口的普及, 串行口的地位逐渐降低,但是作为设备间简便的通信方式,在相当长的时间内,串行口还不会消失,在 市场上也可很容易的购买到 USB 到串行口的转接器。 因为简单且常用的串行通信只需要三根线 (发送线、 接收线和地线) ,所以串行通信仍然是 MCU 与外界通信的简便方式之一。 实现异步串行通信功能的模块在一部分 MCU 中被称为通用异步收发器(Universal Asynchronous Receiver/Transmitters,UART) ,在另一些 MCU 中被称为串行通信接口( Serial Communication Interface,SCI) 。串行通信接口可以将终端或个人计算机连接到 MCU,也可将几个分散的 MCU 连接成 通信网络。 本章主要内容有:①异步串行通信的通用基础知识;②XS128 的 SCI 模块的编程结构与 SCI 构件设 计,并测试这个构件;③借助 XS128 的串行接收中断来阐述中断概念与编程方法,并给出编程实例。对 基于构件的编程思想,再次在设计 SCI 构件中加以阐述,读者在阅读时可以仔细体会,以求得对编程方 法更深刻的理解。通过本章学习了中断编程例子后,至此,以一个 MCU 为蓝本学习嵌入式系统硬件软件 基础知识的基本要素已经完成, 后续章节将进行知识的不断积累与扩展, 学习新模块的工作原理与驱动 软件设计,但基本思想与方法方法是一致的。5.1 异步串行通信的通用基础知识本节简要概述异步串行通信中常用的基本概念与硬件连接方法,为学习 MCU 的串行通信接口编程 做准备。5.1.1 串行通信的基本概念D位‖(bit)是单个二进制数字的简称,是可以拥有两种状态的最小二进制值,分别用D0‖和D1‖表示。 在计算机中,通常一个信息单位用 8 位二进制表示,称为一个D字节‖(byte) 。串行通信的特点是:数 据以字节为单位,按位的顺序(例如最高位优先)从一条传输线上发送出去。这里至少涉及到以下几个 问题:第一,每个字节之间是如何区分开的?第二,发送一位的持续时间是多少?第三,怎样知道传输 是正确的?第四, 可以传输多远?这些问题属于串行通信的基本概念。 串行通信分为异步通信与同步通 信两种方式,本节主要给出异步串行通信的一些常用概念。正确理解这些概念,对串行通信编程是有益 的。 1.异步串行通信的格式 在 MCU 的英文芯片手册上,通常说的异步串行通信采用的是 NRZ 数据格式,英文全称是: Dstandard non-return-zero mark/space data format‖,可以译为:D标准不归零传号/空号数据格式‖。这是 一个通信术语,D不归零‖的最初含义是:用负电平表示一种二进制值,正电平表示另一种二进制值, 不使用零电平。Dmark/space‖即D传号/空号‖分别是表示两种状态的物理名称,逻辑名称记为D1/0‖。对 学习嵌入式应用的读者而言,只要理解这种格式只有D1‖、D0‖两种逻辑值就可以了。图 5-1 给出了 8 位数据、无校验情况的传送格式。 第 5 章 串行通信接口 SCI开始位第0位第1位第2位第3位第4位第5位第6位第7位停止位图5-1 串行通信数据格式这种格式的空闲状态为D1‖,发送器通过发送一个D0‖表示一个字节传输的开始,随后是数据位 (在 MCU 中一般是 8 位或 9 位,可以包含校验位) 。最后,发送器发送 1 到 2 位的停止位,表示 一个字节传送结束。若继续发送下一字节,则重新发送开始位,开始一个新的字节传送。若不发送 新的字节,则维持D1‖的状态,使发送数据线处于空闲。从开始位到停止位结束的时间间隔称为一 帧(frame)。所以,也称这种格式为帧格式。 每发送一个字节, 都要发送D开始位‖与D停止位‖, 这是影响异步串行通信传送速度的因素之一。 同时因为每发送一个字节,必须首先发送D开始位‖,所以称之为D异步‖(Asynchronous)通信。 2.串行通信的波特率 位长(Bit Length) ,也称为位的持续时间(Bit Duration) 。其倒数就是单位时间内传送的位数。 人们把每秒内传送的位数叫做波特率(Baud Rate) 。波特率的单位是:位/秒,记为 bps。bps 是英 文 bit per second 的缩写,习惯上这个缩写不用大写,而用小写。通常情况下,波特率的单位可以 省略。 通常使用的波特率有 600、 900、 1200、 1800、 2400、 4800、 9600、 19200、 38400、 57600、 115200、 128000 等。在包含开始位与停止位的情况下,发送一个字节需 10 位,很容易计算出,在各波特率 下,发送 1K 字节所需的时间。显然,这个速度相对于目前许多通信方式而言是慢的,那么,异步 串行通信的速度能否提得很高呢?答案是不能。因为随着波特率的提高,位长变小,以至于很容易 受到电磁源的干扰,通信就不可靠了。当然,还有通信距离问题,距离小,可以适当提高波特率, 但这样毕竟提高的幅度非常有限,达不到大幅度提高的目的。 3.奇偶校验 在异步串行通信中,如何知道传输是正确的?最常见的方法是增加一个位(奇偶校验位) ,供 错误检测使用。字符奇偶校验检查(Character Parity Checking)称为垂直冗余检查(Vertical Redundancy Checking,VRC) ,它是为每个字符增加一个额外位使字符中D1‖的个数为奇数或偶数。 奇数或偶数依据使用的是D奇校验检查‖还是D偶校验检查‖而定。当使用D奇校验检查‖时,如果字符 数据位中D1‖的数目是偶数,校验位应为D1‖,如果D1‖的数目是奇数,校验位应为D0‖。当使用D偶校 验检查‖时,如果字符数据位中D1‖的数目是偶数,则校验位应为D0‖,如果是奇数则为D1‖。 这里列举奇偶校验检查的一个实例,看看 ASCII 字符DR‖,其位构成是 1010010。由于字符DR‖ 中有 3 个位为D1‖,若使用奇校验检查,则校验位为 0;如果使用偶校验检查,则校验位为 1。 在传输过程中,若有 1 位(或奇数个数据位)发生错误,使用奇偶校验检查,可以知道发生传 输错误。若有 2 位(或偶数个数据位)发生错误,使用奇偶校验检查,就不能知道已经发生了传输 错误。但是奇偶校验检查方法简单,使用方便,发生 1 位错误的概率远大于 2 位的概率,所以D奇 偶校验‖这种方法还是最为常用的校验方法。几乎所有 MCU 的串行异步通信接口,都提供这种功 能。 4.串行通信的传输方式 在串行通信中,经常用到D单工‖、D双工‖、D半双工‖等术语。它们是串行通信的不同传输方式。 下面简要介绍这些术语的基本含义。 (1)单工(Simplex) :数据传送是单向的,一端为发送端,另一端为接收端。这种传输方式 中,除了地线之外,只要一根数据线就可以了。有线广播就是单工的。 第 5 章 串行通信接口 SCI(2)全双工(Full-duplex) :数据传送是双向的,且可以同时接收与发送数据。这种传输方式 中,除了地线之外,需要两根数据线,站在任何一端的角度看,一根为发送线,另一根为接收线。 一般情况下,MCU 的异步串行通信接口均是全双工的。 (3)半双工(Half-duplex) :数据传送也是双向的,但是在这种传输方式中,除地线之外,一 般只有一根数据线。任何时刻,只能由一方发送数据,另一方接收数据,不能同时收发。5.1.2 RS-232 总线标准现在回答D可以传输多远‖这个问题。MCU 引脚输入/输出一般使用 TTL(Transistor Transistor Logic)电平,即晶体管-晶体管逻辑电平。而 TTL 电平的D1‖和D0‖的特征电压分别为 2.4V 和 0.4V (目前使用 3V 供电的 MCU 中,该特征值有所变动) ,即大于 2.4V 则识别为D1‖,小于 0.4V 则识 别为D0‖。它适用于板内数据传输。若用 TTL 电平将数据传输到 5m 之外,那么可靠性就很值得考 究了。为使信号传输得更远,美国电子工业协会 EIA(Electronic Industry Association)制订了串行 物理接口标准 RS-232C, 以下简称 RS-232。 RS-232 采用负逻辑, -15V~-3V 为逻辑D1‖, +3V~+15V 为逻辑D0‖。RS-232 最大的传输距离是 30m,通信速率一般低于 20Kbps。当然,在实际应用中, 也有人用降低通信速率的方法,通过 RS-232 电平,将数据传送到 300m 之外,这是很少见的,且 稳定性很不好。 RS-232 总线标准最初是为远程数据通信制订的,但目前主要用于几米到几十米范围内的近距 离通信。有专门的书籍介绍这个标准,但对于一般的读者,不需要掌握 RS-232 标准的全部内容, 只要了解本节介绍的这些基本知识就可以使用 RS-232。 目前一般的 PC 机均带有 1 到 2 个串行通信 接口,人们也称之为 RS-232 接口,简称D串口‖,它主要用于连接具有同样接口的室内设备。早期 的标准串行通信接口是 25 芯插头,这是 RS-232 规定的标准连接器(其中:2 条地线,4 条数据线, 11 条控制线,3 条定时信号,其余 5 条线备用或未定义) 。 后来,人们发现在计算机的串行通信中,25 芯线中的大部分并不使用,逐渐改为使用 9 芯串 行接口。一段时间内,市场上还有 25 芯与 9 芯的转接头,方便了两种不同类型之间的转换。后来, 使用 25 芯串行插头极少见到,25 芯与 9 芯转接头也极少有 售。因此,目前几乎所有计算机上的串行口都是 9 芯接口。 9 6 7 8 图 5-2 给出了 9 芯串行接口的排列位置,相应引脚含义见表 1 5 4 2 3 5-1。 嵌 在 RS-232 通信中,常常使用精简的 RS-232 通信,通信 图5-2 9芯串行接口排列 时仅使用 3 根线:RXD(接收线) 、TXD(发送线)和 GND (地线) 其他为进行远程传输时接调制解调器之用, 。 有的也可作为硬件握手信号 (如请求发送 RTS 信号与允许发送 CTS 信号) ,初学时可以忽略这些信号的含义。表 5-1 9 芯串行接口引脚含义表 引脚号 1 2 3 4 5 功能 接收线信号检测(载波检测 DCD) 接收数据线(RXD) 发送数据线(TXD) 数据终端准备就绪(DTR) 信号地(SG) 引脚号 6 7 8 9 功能 数据通信设备准备就绪(DSR) 请求发送(RTS) 允许发送(CTS) 振铃指示5.1.3 TTL 电平到 RS-232 电平转换电路在 MCU 中,若用 RS-232 总线进行串行通信,则需外接电路实现电平转换。在发送端,需要 用驱动电路将 TTL 电平转换成 RS-232 电平; 在接收端, 需要用接收电路将 RS-232 电平转换为 TTL 第 5 章 串行通信接口 SCI电平。电平转换器不仅可以由晶体管分立元件构成,也可以直接使用集成电路。目前广泛使用 MAX232 芯片较多,该芯片使用单一+5V 电源供电实现电平转换。图 5-3 给出了 MAX232 的引脚 说明。 引脚含义简要说明如下: Vcc(16 脚) :正电源端,一般接+5V。 GND(15 脚) :地。 VS+(2 脚) :VS+=2Vcc-1.5V=8.5V。 VS-(6 脚) :VS-=-2Vcc-1.5V=-11.5V。 C2+、C2-(4、5 脚) :一般接 1?F 的电解电容 C1+、C1-(1、3 脚) :一般接 1?F 的电解电容。 输入输出引脚分两组,基本含义见表 5-2。在实际使用时,若只需要一路串行通信接口,可以 使用表 5-2 MAX232 芯片输入输出引脚分类与基本接法 组别 1 2 TTL 电平引脚 11(T1IN) 12(R1OUT) 10(T2IN) 9(R2OUT) 方向 输入 输出 输入 输出 典型接口 接 MCU 的 TXD 接 MCU 的 RXD 接 MCU 的 TXD 接 MCU 的 RXD 232 电平引脚 13 14 8 +5V 7+232 电平方向 TTL 电平 输出 输入 输出典型接口R1IN 输入 T1IN 接到 R1OUT T1OUT9 芯接口的 2 脚 RXDGND接到 9 芯接口的 3 脚 TXD 接到 9 芯接口的 2 脚 RXD 接到 9 芯接口的 3 脚 TXD16 15 14 13 12 11 10 9 MAX232CPE 1 2 3 4 5 6 7 8+ + +5V + +1? F×5TTL 电平 转为 232 电平V图5-3 MAX232引脚图1 图5-4 串行通信接口电平转换电路其中的任何一组。 焊接到 PCB 板上的 MAX232 芯片检测方法:正常情况下, (1)T1IN=5V,则 T1OUT=-9V; T1IN=0V, T1OUT=9V。 将 R1IN 与 T1OUT 相连, T1IN=5V, R1OUT=5V; T1IN=0V, 则 (2) 令 则 令 则 R1OUT=0V。 具有串行通信接口的 MCU,一般具有发送引脚(TXD)与接收引脚(RXD) ,不同公司或不 同系列的 MCU,使用的引脚缩写名可能不一致,但含义相同。串行通信接口的外围硬件电路,主 要目的是将 MCU 的发送引脚 TXD 与接收引脚 RXD 的 TTL 电平, 通过 RS-232 电平转换芯片转换 为 RS-232 电平。图 5-4 给出了基本串行通信接口的电平转换电路。 MAX232 芯片进行电平转换基本原理是: 发送过程:MCU 的 TXD(TTL 电平)经过 MAX232 的 11 脚(T1IN)送到 MAX232 内部,在内 部 TTL 电平被D提升‖为 232 电平,通过 14 脚(T1OUT)发送出去。 接收过程:外部 232 电平经过 MAX232 的 13 脚(R1IN)进入到 MAX232 的内部,在内部 232 电平被D降低‖为 TTL 电平,经过 12 脚(R1OUT)送到 MCU 的 RXD,进入 MCU 内部。 进行 MCU 的串行通信接口编程时, 只针对 MCU 的发送与接收引脚, MAX232 无关, 与 MAX232 只是起到电平转换作用。5.1.4 串行通信编程模型从基本原理角度看,串行通信接口 SCI 的主要功能是:接收时,把外部的单线输入的数据变 第 5 章 串行通信接口 SCI成一个字节的并行数据送入 MCU 内部;发送时,把需要发送的一个字节的并行数据转换为单线输 出。图 5-5 给出了一般 MCU 的 SCI 模块的功能描述。为了设置波特率 SCI 应具有波特率寄存器。 为了能够设置通信格式、是否校验、是否允许中断等,SCI 应具有控制寄存器。而要知道串口是否 有数据可收、数据是否发送出去等,需要有 SCI 状态寄存器。当然,若一个寄存器不够用,控制 与状态寄存器可能有多个。而 SCI 数据寄存器存放要发送的数据,也存放接收的数据,这并不冲 突,因为发送与接收的实际工作是通过“发送移位寄存器”和“接收移位寄存器”完成的。编程时, 程序员并不直接与“发送移位寄存器”和“接收移位寄存器”打交道,只与数据寄存器打交道,所 以 MCU 中并没有设置“发送移位寄存器”和“接收移位寄存器”的映像地址。发送时,程序员通 过判定状态寄存器的相应位,了解是否可以发送一个新的数据。若可以发送,则将待发送的数据放 入DSCI 数据寄存器‖中就可以了, 剩下的工作由 MCU 自动完成: 将数据从DSCI 数据寄存器‖送到D发 送移位寄存器‖,硬件驱动将D发送移位寄存器‖的数据一位一位地按照规定的波特率移到发送引脚 TxD,供对方接收。接收时,数据一位一位地从接收引脚 RxD 进入D接收移位寄存器‖,当收到一 个完整字节时,MCU 会自动将数据送入DSCI 数据寄存器‖,并将状态寄存器的相应位改变,供程 序员判定并取出数据。接收 引脚 RxD 接收移位寄存器 发送 引脚 TxD 发送移位寄存器15SPH 15 H MCU 的内部总线(Internal Bus) 8 7 X 0 SCI状态寄存器 SCI 控制寄存器 SCI波特率寄存器 70SCI 数据寄存器图5-5 SCI编程模型5.2 XS128的SCI模块寄存器70 本节从编程角度介绍 MC9S12XS128 MCU 的 SCI 模块。该芯片有两个串行口 SCI0 和 SCI1。 从外部引脚来看,负责串行通信的是 PS0/RxD0、PS1/TxD0、PS2/RxD1、PS3/TxD1 四个引脚。当 允许 SCI 时,这些引脚作为串行通信引脚;每个串口模块包含 2 个引脚,分别称为串行发送引脚 15 TxD 和串行接收引脚 RxD。 本章以 SCI0 为例来介绍 SCI 模块, SCI1 的使用方法与 SCI0 完全相同, SPH 只是相关寄存器映像地址不同,以下统称 SCI 模块,具体使用时在头文件中区分使用哪个串口。 从程序员角度看,SCI 模块有 15 个 8 位寄存器,表 5-3 给出了主要寄存器的基本信息。只要 11 H 理解和掌握这 8 个寄存器的用法,就可以进行 SCI 编程。 8 7 下面从编程角度介绍 SCI 模块的寄存器(波特率寄存器、控制寄存器、状态寄存器和数据寄 X 存器) 。 0表 5-3 XS128 的 SCI 寄存器 地址 SCI0 SCI107寄存器名称与缩写 访问权限 基本功能7 0 第 5 章 串行通信接口 SCI $00C8 $00C9 $00CA $00CB $00CC $00D0 $00D1 $00D2 $00D3 $00D4 波特率寄存器 (SCIBDH、SCIBDL) 控制寄存器 (SCICR1、SCICR2)读/写 读/写设置波特率 设置传输格式、中断使能状态寄存器 只读 中断标志、发送与接收状态 (SCISR1、SCISR2) $00CD $00D5 $00CE $00D6 数据寄存器 读/写 收发的数据 (SCIDRH、SCIDRL) $00CF $00D7 说明:由于有两个串行口,使用 SCIx 时,寄存器名称中 SCI 改为 SCIx,x=0,1。1. SCI 波特率寄存器(SCI Baud Rate Register,SCIBDH/L) 波特率寄存器[SCIBDH:SCIBDL],分为波特率寄存器的高 8 位与低 8 位。SCIBDH 的高 3 位为 0, SCIBDH 的低 5 位与 SCIBDL 一起给出了共 13 位的串行通信分频系数 BR,其取值范围是 1~8191。 [SCIBDH:SCIBDL]不能为 0,复位时为 4。 SCIBDH:数据位 定义 复位 D7 x 0 D6 x 0 D5 x 0 D4 SBR12 0 D3 SBR11 0 D2 SBR10 0 D1 SBR9 0 D0 SBR8 0SCIBDL:数据位 定义 复位 D7 SBR7 0 D6 SBR6 0 D5 SBR5 SBR0 0 D4 SBR4 0 D3 SBR3 0 D2 SBR2 1 D1 SBR1 0 D0 SBR0 0串行通信模块的时钟源为内部总线,设 fSCI 为串行通信时钟源频率,则 fSCI=fBUS。数据手册给 出的计算 SCI 波特率 Bt 的公式为: Bt=fBUS/(16×BR) 一般情况下,内部总线频率 fBUS 是已知的,波特率 Bt 是编程者希望设定的,然后根据 fBUS、 Bt 求出 BR 的值: BR=fBUS/(16×Bt) 例 如 , fSCI=fBUS=18.6608Mhz=Hz , 希 望 设 定 波 特 率 Bt=9600 , 可 以 求 得 BR=×,转为十六进制为 0x80,则 SCIBRH=0x00,SCIDBL=0x80。要注意 遵循根据手册的要求,先写 SCIBRL 再写 SCIBRH。若是使用 SCI0,则程序如下: SCI0BDH=0x00; //先给高位赋值 SCI0BDL=0x80; //后给低位赋值 注意:若 fBUS=25Mhz,则 BR=×≈163,由于不能整除,所以有时 存在一定误差,这是允许的。 2. SCI控制寄存器1(SCI Control Register1,SCICR1)数据位 定义 复位 D7 LOOPS 0 D6 SCISWAI 0 D5 RSRC PT 0 D4 M 0 D3 WAKE 0 D2 ILT 0 D1 PE 0 D0 PT 0D7―LOOPS 位, 循环模式选择位(Loop Select Bit)。 LOOPS=1, 允许自发自收方式; LOOPS=0, 正常模式。在允许自发自收方式下,接收引脚 RxD 与 SCI 内部断开,内部发送数据直接作为接收 的输入,用于自测试。接收器的输入由 RSRC 位决定。 D6―SCISWAI 位,等待模式下 SCI 禁止位(SCI Stop in Wait Mode Bit)。SCISWAI=1,禁止 SCI 模块,即允许在 Wait 模式下停止 SCI;SCISWAI=0,允许 SCI 模块。 第 5 章 串行通信接口 SCID5-RSRC 位,接收器资源位(Receiver Source Bit)。当 LOOPS=1 时,RSRC 位决定了接收移 位寄存器接收数据的来源。RSRC=1,RXD 引脚和 SCI 模块断开,SCI 使用 TXD 引脚来进行发送 与接收;RSRC=0,发送器的输出作为接收器的输入。 D4―M 位,模式/字符长度选择位(Data Format Mode Bit)。定义收发数据格式,M=1,9 位传 送;M=0,8 位传送。 D3―WAKE 位,唤醒方式位(Wakeup Condition Bit)。WAKE=1,地址唤醒;WAKE=0,空闲线 唤醒。 D2―ILT 位,全 1 空闲字符位计算方式位(Idle Line Type Bit),决定 SCI 何时开始计数“空闲字 符”的位数。ILTY=1,空闲字符位从“停止位”开始计数;ILTY=0,空闲字符位从“起始位”开 始计数。 D1―PE 位,奇偶校验允许位(Parity Enable Bit)。PE=1,允许奇偶校验;PE=0,不进行奇偶校 验。 D0―PT 位,奇偶校验类型选择位(Parity Type Bit)。PT=1,奇校验;PT=0,偶校验。不进行奇 偶校验时,该位无意义,一般写 0。 3. SCI控制寄存器2(SCI Control Register1,SCICR2)数据位 定义 复位 D7 TIE 0 D6 TCIE 0 D5 RIE 0 D4 ILIE 0 D3 TE 0 D2 RE 0 D1 RWU 0 D0 SBK 0D7―TIE 位,发送中断允许位(Transmitter Interrupt Enable Bit)。SCTIE=1,允许产生发送中断 请求;反之不允许。 D6―TCIE 位,发送完成中断允许位(Transmission Complete Interrupt Enable Bit)。TCIE=1,允 许发送完成产生中断;反之不允许。 D5―RIE 位,接收中断允许位(SCI Receive Interrupt Enable Bit)。SCRIE=1,允许产生接收中断 请求;反之不允许。 D4―ILIE 位,空闲线中断允许位(Idle Line Interrupt Enable Bit)。ILIE=1,允许产生空闲中断请 求;反之不允许。 D3―TE 位,发送器允许位(Transmitter Enable Bit)。TE=1,允许发送器发送;反之不允许发送 器发送。 D2―RE 位,接收器允许位(Receiver Enable Bit)。RE=1,允许接收器接收;反之不允许接收器 接收。 D1―RWU 位,接收器唤醒位(Receiver Wakeup Bit)。RWU=1,等待状态;RWU=0,正常操作。 D0―SBK 位, 发送 13 或 14 位全 0 信号(Send Break Bit)。 SBK=1, 发送终止字符(逻辑 1); SBK=0, 正在发送非终止字符。 MCU 复位后,SCI0CR2 寄存器中默认的值是全部为 0。可以看出,所有中断都是禁止的,SCI 口本身也是被禁止的,因为 TE 和 RE 位为 0。没有初始化 SCI0 口之前,SCI0 口为普通 I/O 口的输 入口,初始化 SCI0 口必须允许 SCI0 口的发送和接收,即向该寄存器写入立即数$0C 以给 TE 和 RE 位置 1。 4. SCI替换状态寄存器1(SCI Alternative Status Register,SCIASR1)D3 D2 D1 D0 ― BERRV BERRIF BKDIF 0 0 0 0 0 D7―RXEDGIF 位, 接收输入活动沿中断位。 该位是确定的, 如果一个活动沿 (如果 RXPOL=0, 数据位 定义(只读) 复位 D7 RXEDGIF 0 D6 ― PE 0 D5 ― 0 D4 ― 0是下降沿。如果 RXPOL=1,是上升沿)在 RXD 输入出现,改位写 1 清零。该位为 0,表明接收输 入没有活动的输入发生。该位为 1,表示在接收输入没有活动沿发生。 第 5 章 串行通信接口 SCID2―BERRV 位,比特错误位(Noise Flag)。当比特错误检测电路使能和一个期望值不匹配发生BERRM1 0 0 1 1BERRM0 0 1 0 1功能 比特错误检测电路使能 在传输比特的第 9 个时钟接 收输入样本发生 在传输比特的第 13 个时钟 接收输入样本发生 保留时,BERRV 反映了 RXD 输入的状态。该位只有在 BERRIF=1 时有意义。该位为 0 时,表明 一个低输入是样本的,高输入位期望的。该位为 1,表明一个高输入是在装配值,低输入是期望值。 D1―BERRIF 位,比特错误中断标志位(Framing Error Flag)。该位是确定的,当比特错误检测 电路使能和在 RXD 的样本值和传输值不匹配时。如果 BERRIE 中断使能位被置,一个中断将会发 生。该位写 1 清零。该位为 0,表明没有不匹配值检测到。该为位 1,表明一个比匹配值发生。 D0―BKDIF 位,打断检测中断标志。该位是确定的,如果打断检测电路使能并接收到一个打 断信号时。如果 BKDIE 中断使能位被置,一个中断将会发生。该位写 1 请零。该位为 0,表明没 有打断信号接收到。为 1 时,表明有打断信号接收到。 5. SCI替换控制寄存器1 (SCI Alternative Control Register 1 ,SCIACR1)数据位 定义(只读) 复位 D7 RXEDGIE 0 ― BERRIE BKDIE 0 0 0 0 0 0,RXEDGIF 中断请求禁止。该位为 D7―RXEDGIE 位,接收输入活动沿中断使能位。该位为 0 0 D6 ― PE 0 D5 ― D4 ― D3 ― D2 D1 D01,RXEDGIF 中断请求使能。 D1―BERRIE 位,比特错误中断使能。该位使能比特错误中断标志,BERRIF,去产生中断请 求。该位为 0,表明 BERRIF 中断请求禁止。该位为 1,表明 BERRIF 中断请求使能。 D0―位,打断检测中断使能。该位使能打断检测中断位,BKDIF,去生成中断请求。该位为 0, BKDIF 中断请求禁止。该位为 1,表明 BKDIF 中断请求使能。 6. SCI替换控制寄存器2 (SCI Alternative Control Register 2,SCIACR2)数据位 定义(只读) 复位 D7 ― 0 D6 ― PE 0 D5 ― 0 D4 ― 0 D3 ― 0 0 D2 BERRM1 0 D1 BERRM0 0 D0 BKDF 0D2,D1―比特错误模式。这两个位决定比特错误检测特征功能。见表 5-4。. D0―打断检测特征使能位。该位使能打断检测电路。该位为 0 打断检测电路禁止,该位为 1 打断电路使能。表 5-4 比特错误检测特征功能表7. SCI状态寄存器1(SCI Status Register,SCISR1)数据 位 定义 (只读) 复位 D7 TDRE 1 D6 TC PE 1 D5 RDRF 0 D4 IDLE 0 D3 OR D2 NF D1 FE D0 PF0 0 0 0 0 D7―TDRE 位, 发送数据寄存器空标志位(Transmit Data Register Empty Flag)。 该位为 1 时表明要发送的数据已经移入发送移位寄存器,数据寄存器(SCIDRH/SCIDRL)为空,可以发送一个新的 数据。 第 5 章 串行通信接口 SCID6―TC 位,发送完成标志位(Transmit Complete Flag)。该位为 1,表明发送已经完成,该位为 0,表明发送正在进行。 D5―RDRF 位,接收数据寄存器满标志位(Receive Data Register Full Flag)。该位为 1,表明接 收器已满,可以从 SCI 数据寄存器 SCIDRH/SCIDRL 中读取收到的数据。 D4―IDLE 位,线路空闲标志位(Idle Line Flag)。当接收 10 个连续的逻辑 1(M=0)或接收 11 个 连续的逻辑 1(M=1)时,IDLE 位即被设置为 1。IDLE=1 表明接收器处于空闲状态。注意当接收唤 醒位 RWU=1 时,空闲线的状态不能影响 IDLE 位。 D3―OR 位,溢出标志位(Overrun Bit)。该位为 1,表明接收器溢出。 D2―NF 位,噪声标志位(Noise Flag)。该位为 1,表明接收器出现噪声错误。 D1―FE 位,帧错误标志位(Framing Error Flag)。该位为 1,表明接收器出现帧错误。 D0―PF 位,奇偶错误标志位(Parity Error Flag)。该位为 1,表明接收器出现奇偶校验错误。该 位写无效。 8. SCI状态寄存器2(SCI Status Register,SCISR2)数据位 定义 复位 D7 AMAP 0 D6 ― 0 D5 ― 0 D4 TXPOL 0 D3 RXPOL 0 D2 BK13 0 D1 TXDIR 0 D0 RAF 0D7―AMAP 位,该位控制哪些共享相同地址空间的寄存器是可访问的。在复位条件下,串口 的功能表现为之前的版本。设置改为位 1,允许访问另一个系列的控制和状态寄存器并波特率和控 制寄存器 1。AMAP=0,SCIBDH (0x0000),SCIBDL (0x0001), SCICR1 (0x0002)标记的寄存器是可访 问的。AMAP=1,SCIASR1 (0x0000),SCIACR1 (0x0001), SCIACR2 (0x00002)标记的寄存器是可访 问的。 D6~D5,未定义。 D4―TXPOL,发送极性位。该位控制发送数据的极性。在正常模式 NRZ 格式下,1 表示高, 0 表示低。在反转极性下刚好相反 TXPOL=0,正常极性。TXPOL=1,反转极性。 D3―RXPOL,接收极性位。RXPOL=0,正常极性。RXPOL=0,反转极性。 D2―BK13 位,终止码标志位(Break Transmit character length)。BK13=1,终止码长度为 13 或 14 位;BK13=0,终止码长度为 10 或 11 位。帧错误不受该位的影响。 D1―TXDIR 位,单线模式下发送引脚的数据传输方向位(Transmitter pin data direction in Single-Wire mode)。 在单线模式下, 该位用来决定 TxD 引脚用于发送数据还是接收数据。 TXDIR=1, 表明 TxD 用于发送数据;TXDIR=0,表明 TxD 用于接收数据。所谓单线模式就是将 RxD 与 SCI 断开, 只使用 TxD 发送和接收数据, 并且由 TXDIR 位决定是发送还是接收。 LOOPS=1、 当 RSRC=1 时,使能单线模式。 D0-RAF 位,接收进行标志位(Receiver Active Flag)。该位为 1,表明正在接收。 9. SCI数据寄存器(SCI Data Register,SCIDRH/L) SCI 数据寄存器[SCIDRH:SCIDRL]。当使用 8 位数据格式时,只使用 SCIDRL 寄存器。当使用 9 位数据格式发送数据时,先写 SCIDRH 寄存器,再写 SCIDRL 寄存器。 SCIDRH:数据位 读操作 写操作 复位 D7 R8 ― 0 D6 ― T8 0 D5 0 ― 0 D4 0 ― 0 D3 0 ― 0 D2 0 ― 0 D1 0 ― 0 D0 0 ― 0 第 5 章 串行通信接口 SCISCIDRL:数据位 读操作 写操作 复位 D7 R7 T7 0 D6 R6 T6 0 D5 R5 T5 0 D4 R4 T4 0 D3 R3 T3 0 D2 R2 T2 0 D1 R1 T1 0 D0 R0 T0 0SCIDRH:只有 D7、D6 被定义,分别记为 R8、T8。当 SCI 配置为 9 位数据格式(M=1)时,R8 为收到的第 9 位数据,T8 则存放要发送的第 9 位数据。 SCIDRL:读出时,为接收的数据,记作 R7~R0;写入时,为要发送的数据,记作 T7~T0。5.3 XS128的SCI构件设计与测试无论用查询方式还是中断方式进行串行通信编程,在程序初始化时均必须对 SCI 进行初始化, 主要进行波特率设置、通信格式的设置、发送接收数据方式的设置等。本小节给出最基本的方法, 作为 S12X 系列 MCU 的串行通信编程入门知识。下一小节将给出规范的串行通信编程子程序,读 者可以直接将其应用于实际的嵌入式应用系统的开发中。5.3.1 SCI 初始化有关寄存器地址的定义已经在头文件 MC9S12XS128.h 中给出,SCIBDH、SCIBDL、SCICR1、 SCICR2

我要回帖

更多关于 单片机 让蜂鸣器停止 的文章

 

随机推荐