首 页科技博览科普图片植物王国动物世界科普常识农村科普生活科普信息技术科普创作自然之谜
历史今天留言繁體中文
设为首页
加入收藏
联系我们
您当前的位置:科普知识网 -> 电子电工 -> IC电子 -> 博览内容 退出登录 用户管理
 

· 有线电视 · 电子系统
· 显示元件 · 接口电路
· 存储器 · 无线通信
· 传感控制 · EDA/PLD
· 单片机 · DSP技术
· 模拟技术 · 通信网络
· 测试仪表 · 视频音频
· 芯片应用 · 电子通信
· IC电子 · 电子设计
· 自控测量 · IC嵌入式
· IC系统 · EDA系统
· 传感控制 · 电源技术
· 接口电路 · 消费电子
· DSP产品 · 元件工艺
· 模拟技术 · 存储器设备
· 设计应用 · 智能网应用
· 电子电源 · 电子传感
热门博览
· 涡轮
· 什么是路肩?硬路肩?..
· 神秘的海底世界
· 民用飞机
· 电路设计
· 梁桥
· 航空发动机
· 环保--功在当代,利..
· 气球
· 双曲拱桥是一种什么..
相关博览
· [图文] HD44780液晶显..
· [组图] 解决串行接口..
· [组图] TMS320LF/LC..
· [组图] 三线制Microw..
· [组图] PIC单片机与触..
· [图文] 调试嵌入式系..
· [组图] 推动串行互连..
· 实现DSP与 FPGA 之间..
· [图文] 高速嵌入式系..
· 串行连接存储技术引..

串行通信接口SCI与串行外设接口SPI

作者:佚名  来源:不详  
本章要点:SCI与SPI是MCU与外界进行串行通信的两种重要方式.相对来说,SCI使用得更多.本章的主要内容有:(1)串行异步通信基本概念:通信格式,波特率,奇偶校验,传输方式(单工,全双工,半双工),RS-232C标准及电平转换;(2)具有串行通信功能的MCU最小系统的硬件电路原理及SCI的编程原理;(3)MC68HC908GP32的SCI模块编程结构;(4)规范的汇编及C语言串行通信子程序,并给出测试实例,包括PC机方程序;(5)MC68HC908GP32的SPI模块编程原理及应用举例.
学习指导:本章重点掌握SCI的编程,同时学习编程的规范.第1,2两节给出的基本上是与芯片无关的通用知识,了解这些知识对进行串行电路设计与编程很有帮助,要求重点掌握其基本含义.对于第2节末给出的具有串行通信功能的MC68HC908GP32的最小系统,属于硬件范畴,希望在这里能够掌握.学习嵌入式应用,不能一点不涉及硬件,该部分的撰写兼顾到对硬件感到困难的读者.学习第3节时,第一遍阅读,可以根据文中的提示有重点地看,其它内容可以暂时略过,待完成第4节的实验之后再回头理解一些寄存器的含义.串行通信的PC机方程序,使用VB,VC等高级语言编程,读者可以选择自己熟悉的语言.SPI部分对于初学者,要求理解其通信与编程的基本方法,实际应用时,可参考第6节的实例.
8.1 串行通信基本知识概要
本节简要概括了串行通信中的相关概念,为学习MCU的串行接口编程做准备.对于已经了解这方面知识的读者,可以略读本节.
8.1.1 基本概念
我们知道,"位"(bit)是二进制数字的简称,是可以拥有两种状态的最小二进制值,分别用"0"和"1"表示.在计算机中,通常一个信息单位用8位二进制表示,称为一个"字节"(byte).串行通信的特点是:数据以字节为单位,按位的顺序从一条传输线上发送出去.这里至少涉及到以下几个问题:第一,每个字节之间是如何区分的 第二,发送一位的持续时间是多少 第三,怎样知道传输是正确的 第四,可以传输多远 等等.这些问题属于串行通信的基本概念.串行通信分为异步通信与同步通信两种方式,本节主要给出异步串行通信的一些常用概念.正确理解这些概念,对串行通信编程是有益的.
(1)异步串行通信的格式
在MCU的英文芯片手册上,通常说SCI采用的是NRZ数据格式,英文全称是:"standard non-return-zero mark/space data format",可以译为:"标准不归零传号/空号数据格式".这是一个通信术语,"不归零"的最初含义是:用负电平表示一种二进制值,正电平表示另一种二进制值,不使用零电平."mark/space"即"传号/空号"分别是表示两种状态的物理名称,逻辑名称记为"1/0".对学习嵌入式应用的读者而言,只要理解这种格式只有"1","0"两种逻辑值就可以了.图8-1给出了8位数据,无校验情况的传送格式.
这种格式的空闲状态为"1",发送器通过发送一个"0"表示一个字节传输的开始,随后是数据位(在MCU中一般是8位或9位,可以包含校验位).最后,发送器发送1到2位的停止位,表示一个字节传送结束.若继续发送下一字节,则重新发送开始位,开始一个新的字节传送.若不发送新的字节,则维持"1"的状态,使发送数据线处于空闲.从开始位到停止位结束的时间间隔称为一帧(frame).所以,也称这种格式为帧格式.
通过这段内容,我们知道了异步串行通信中,通过"开始位"与"停止位"区分每个传送的字节.所以,每发送一个字节,都要发送"开始位"与"停止位",这是影响异步串行通信传送速度的因素之一.同时因为每发送一个字节,必须首先发送"开始位",所以称之为"异步"(asynchronous)通信.
(2)串行通信的波特率
位长(bit length),也称为位的持续时间(bit duration).其倒数就是单位时间内传送的位数.人们把每秒内传送的位数叫做波特率(baud rate).波特率的单位是:位/秒,记为bps.bps是英文bit per second的缩写,习惯上这个缩写不用大写,而用小写.通常情况下,波特率的单位可以省略.
通常使用的波特率有300,600,900,1200,1800,2400,4800,9600,19200,38400.在包含开始位与停止位的情况下,发送一个字节是10位,很容易计算出,在各种波特率下,发送1K字节所需的时间.显然,这个速度相对于目前的许多通信方式是慢的,那么,异步串行通信的速度能否提得很高呢 答案是否定的.因为随着波特率的提高,位长变小,以致很容易受到电磁源的干扰,通信就不可靠了.当然,还有通信距离问题,距离小,可以适当提高波特率,后面还会涉及此问题.
(3)奇偶校验
在异步串行通信中,如何知道传输是正确的 最常见的方法是增加一个位(奇偶校验位),供错误检测使用.字符奇偶校验检查(character parity checking)称为垂直冗余检查( vertical redundancy checking,VRC),它是每个字符增加一个额外位使字符中"1"的个数为奇数或偶数.奇数或偶数依据使用的是"奇校验检查"还是"偶校验检查"而定.当使用"奇校验检查"时,如果字符数据位中"1"的数目是偶数,校验位应为"1",如果"1"的数目是奇数,校验位应为"0".当使用"偶校验检查"时,如果字符数据位中"1"的数目是偶数,则校验位应为"0",如果是奇数则为"1".
这里列举奇偶校验检查的一个实例,看看ASCII字符"R", 其位构成是1010010.由于字符"R"中有三个1位,若使用奇校验检查,则校验位为0;如果使用偶校验检查,则校验位为1.因而,ASCII字符"R"如下所示:
数据位 校验位
—————————————
1 0 1 0 0 1 0 0 奇校验检查 (要求:1的个数为奇数)
1 0 1 0 0 1 0 1 偶校验检查 (要求:1的个数为偶数)
在传输过程中,若有1位(或奇数个数据位)发生错误,使用奇偶校验检查,可以知道发生传输错误.若有2位(或偶数个数据位)发生错误,使用奇偶校验检查,不能知道发生传输错误.但是奇偶校验检查方法简单,使用方便,发生一位错误的概率远大于发生二位错误的概率,所以"奇偶校验"这种方法还是最为常用的一种校验方法.几乎所有MCU的串行异步通信接口中,都提供这种功能.
(4)串行通信的传输方式
在串行通信中,经常用到"单工","双工","半双工"等术语.它们是串行通信的不同传输方式.下面简要介绍这些术语的基本含义.
单工(Simplex):数据传送是单向的,一端为发送端,另一端为接收端.这种传输方式中,除了地线之外,只要一根数据线就可以了.有线广播就是单工的.
全双工(Full-duplex):数据传送是双向的,且可以同时接收与发送数据.这种传输方式中,除了地线之外,需要两根数据线,站在任何一端的角度看,一根为发送线,另一根为接收线.一般情况下,MCU的异步串行通信接口均是全双工的.
半双工(Half-duplex):数据传送也是双向的,但是在这种传输方式中,除了地线之外,一般只有一根数据线.任何一个时刻,只能由一方发送数据,另一方接收数据,不能同时收发.在freescale的HC08系列MCU中,监控模式的通信就采用这种方式.
8.1.2 RS-232C总线标准
现在回答"可以传输多远"这个问题.MCU引脚一般输入/输出使用TTL电平,而TTL电平的"1"和"0"的特征电压分别为2.4V和0.4V(目前一些使用3V供电的MCU中,该特征值有所变动),它适用于板内数据传输.若用TTL电平将数据传输到5m之外,那么可靠性是值得考究的.为了使信号传输得更远,美国电子工业协会EIA(Electronic Industry Association) 制订了串行物理接口标准RS-232C.RS-232C采用负逻辑,-3V~-15V为逻辑"1",+3V~+15V为逻辑"0".RS-232C最大的传输距离是30m,通信速率一般低于20Kbps.当然,实际应用中,也有人用降低通信速率的方法,通过RS-232电平,将数据传送到300m之外,这是很少见的,且稳定性很不好.
RS-232C总线标准最初是为远程数据通信制订的,但目前主要用于几米到几十米范围内的近距离通信.有专门的书籍介绍这个标准,但对于一般的读者,不需要掌握RS-232C标准的全部内容,只要了解本节介绍的这些基本知识就可以使用RS-232.目前一般的PC机均带有1到2个串行通信接口,人们也称之为RS-232接口,简称"串口",它主要用于连接具有同样接口的室内设备.早期的标准串行通信接口是25芯插头,这是RS-232C规定的标准连接器(其中:2条地线,4条数据线,11条控制线,3条定时信号,其余5条线备用或未定义).后来,人们发现在计算机的串行通信中,25芯线中的大部分并不使用,逐渐改为使用9芯串行接口.一段时间内,市场上还有25芯与9芯的转接头,方便了两种不同类型之间的转换.后来,使用25芯串行插头极少见到,25芯与9芯对接头也极少有售.因此,目前几乎所有计算机上的串行口都是9芯接口.图8-2给出了9芯串行接口的排列位置,相应引脚含义见表8-1.其中已用黑体字标识的是MCU中用到的三根线:接收线,发送线,地线.其它为进行远程传输时接调制解调器之用,有的也可作为硬件握手信号,初学时可以忽略这些信号的含义.
表8-1 9芯串行接口引脚含义表
引脚号
功 能
引脚号
功 能
1
2
3
4
5
接收线信号检测(载波检测DCD)
接收数据线(RXD)
发送数据线(TXD)
数据终端准备就绪(DTR)
信号地(SG)
6
7
8
9
数据通信设备准备就绪(DSR)
请求发送(RTS)
清除发送
振铃指示
在MCU中,若用RS-232C总线进行串行通信,则需外接电路实现电平转换.在发送端需要用驱动电路将TTL电平转换成RS-232C电平,在接收端需要用接收电路将RS-232C电平转换为TTL电平.电平转换器不仅可以由晶体管分立元件构成,也可以直接使用集成电路.目前使用MAX232芯片较多,该芯片使用单一+5V电源供电实现电平转换.图8-3给出了MAX232的引脚.
引脚含义简要说明如下:
Vcc(16脚):正电源端,一般接+5V
GND(15脚):地
VS+(2脚):VS+=2Vcc-1.5V
VS-(6脚):VS-=-2Vcc-1.5V
C2+,C2-(4,5脚):一般接1μF的电解电容
C1+,C1-(1,3脚):一般接1μF的电解电容
输入输出引脚分两组,基本含义见表8-2.在实际使用时,若只需要一路SCI,可以使用其中的任何一组.
表8-2 MAX232芯片输入输出引脚分类与基本接法
组别
TTL电平引脚
方向
典型接口
232电平引脚
方向
典型接口
1
11
12
输入
输出
接MCU的TxD
接MCU的RxD
13
14
输入
输出
连接到接口与其它设备通过232相接
2
10
9
输入
输出
同上
8
7
输入
输出
同上
利用MAX232将TTL电平转换为RS-232电平的电路接法将在下一节结合SCI的外围硬件电路讨论.
8.2 SCI的外围硬件电路与基本编程原理
所有型号MCU的串行通信接口(Serial Communication Interface,SCI),都具有发送引脚TxD,接收引脚RxD,它们是TTL电平引脚.要利用这两个引脚与外界实现异步串行通信,还必须将TTL电平转为RS-232电平,这可利用上节介绍的MAX232来完成.本节将以MC68HC908GP32 MCU为例,给出具有串行通信功能的MCU最小系统电路的详细设计电路.另外,还从通用角度讨论SCI的基本编程结构与编程原理,为实际编程做准备.
8.2.1 SCI的外围硬件电路
SCI的外围硬件电路,主要目的是将MCU的发送引脚TxD与接收引脚RxD,通过RS-232电平转换芯片转换为RS-232电平.这里以MC68HC908GP32为例,给出一个可以实际工作的电路,读者在此基础上,可以设计08系列MCU的其它型号的工作电路,也可在此基础上进一步扩展组成较为通用的单片机应用系统.在嵌入式应用的实际电路设计时,首先需要考虑MCU的工作支撑电路,然后是各种接口电路.图8-4给出了具有串行通信功能的MC68HC908GP32最小系统电路原理图.下面对其作一些必要的说明,希望读者对照图8-4中各个部分进行阅读.图中使用虚线框将各个功能电路进行了分割.
(1)电源供给与滤波
GP32芯片的20,19脚(Vcc,Vss)为芯片的电源输入端,1,2脚(VDDA,VSSA)为内部PLL模块的电源供给.接在电源与地之间的0.1μ电容为滤波电容.PLL电路目的在于由频率小的外部晶振产生较大频率的内部总线时钟,提高芯片的抗干扰性.由于这部分内容涉及的编程内容很少,但原理较难理解,所以放入第12章介绍.这里只要知道GP32内有PLL电路就可以了,而且GP32内的PLL电路模块需要外接电源.在MCU的第3脚,接有内部PLL模块的外部滤波电路.滤波电路的作用主要是增强电路工作稳定性.
(2)晶振电路
接MCU第4,5脚(OSC2,OSC1)之间的电路为晶振电路,这里选用的晶振频率为f=32.768KHz.通过内部PLL电路模块,可获得小于8MHz的内部总线频率.电路及其元件参数是由GP32参考手册确定的.实际开发中,嵌入式应用工程师往往根据参考手册提供的电路及参数,通过自己的实践,构筑MCU的外围支撑电路,而不深究其工作原理.
(3)复位电路
接在MCU第6脚()的电路为芯片硬件复位电路.正常工作时该脚通过10K电阻接到电源正极(这里设为5V电源供电),所以应为高电平.若按下复位按钮RST,则第6脚通过51Ω接地,为低电平,芯片复位.
(4)SCI电平转换电路
MCU的串行通信引脚12(TxD),13(RxD)分别接MAX232的11(T1IN),12(R1OUT),MAX232的13(R1IN),14(T1OUT)分别为232电平的接收与发送引脚.基本过程是:
发送过程:MCU的12(TxD)(TTL电平)经过MAX232的11(T1IN)送到MAX232内部,在内部TTL电平被"提升"为232电平,通过14(T1OUT)发送出去.
接收过程:外部232电平经过MAX232的13(R1IN)进入到MAX232的内部,在内部232电平被"降低"为TTL电平,经过12(R1OUT)送到MCU的13(RxD),进入MCU内部.
8.2.2 SCI的基本编程原理
从基本原理角度看,串行通信接口SCI的主要功能是:接收时,把外部的单线输入的数据变成一个字节的并行数据送入MCU内部;发送时,把需要发送的一个字节的并行数据转换为单线输出.图8-5给出了普遍意义上的SCI的编程结构.为了设置波特率SCI应具有波特率寄存器.为了能够设置通信格式,是否校验,是否允许中断等,SCI应具有控制寄存器.而要知道串口是否有数据可收,数据是否发送出去等,需要有SCI状态寄存器.当然,若一个寄存器不够用,控制与状态寄存器可能有多个.而SCI数据寄存器存放要发送的数据,也存放接收的数据,这并不冲突,因为发送与接收的实际工作是通过"发送移位寄存器"和"接收移位寄存器"完成的.编程时,程序员并不直接与"发送移位寄存器"和"接收移位寄存器"打交道,只与数据寄存器打交道,所以MCU中并没有设置"发送移位寄存器"和"接收移位寄存器"的映像地址.发送时,程序员通过判定状态寄存器的相应位,了解是否可以发送一个新的数据.若可以发送,则将待发送的数据放入"SCI数据寄存器"中就可以了,剩下的工作由MCU自动完成:将数据从"SCI数据寄存器"送到"发送移位寄存器",硬件驱动将"发送移位寄存器"的数据一位一位地按照规定的波特率移到发送引脚TxD,供对方接收.接收时,数据一位一位地从接收引脚RxD进入"接收移位寄存器",当收到一个完整字节时,MCU会自动将数据送入"SCI数据寄存器",并将状态寄存器的相应位改变,供程序员判定并取出数据.
8.3 SCI模块的编程结构
本节从编程角度介绍MC68HC908GP32单片机的SCI.从外部引脚来看,负责串行通信的是PTE0/TxD,PTE1/RxD两个引脚,当允许SCI时,它们作为串行通信引脚,分别称为串行发送引脚TxD,串行接收引脚RxD.从程序员角度看,涉及SCI的有7个寄存器,其中1个波特率寄存器,3个控制寄存器,2个状态寄存器,1个数据寄存器,只要理解和掌握这7个寄存器的用法,就可以进行SCI编程.
8.3.1 SCI的寄存器
MC68HC908GP32单片机的SCI有7个寄存器,地址为$0013~$0019,下面按初始化顺序分别阐述这些寄存器的功能及用法.初学者注意,为了容易理解这些寄存器的用法,请着重掌握SCI波特率寄存器的设置方法以及SCI控制寄存器和SCI状态寄存器中带有下划线的位.
(1)SCI波特率寄存器(SCI Baud Rate Register,SCBR)
SCI波特率寄存器SCBR的作用是设置串行通信的波特率.通常情况下,选择内部总线时钟为串行通信的时钟源,此时利用SCBR对总线频率fBUS可以进行分频得到串行通信的波特率.SCBR的地址是:$0019,定义为:
数据位
D7 D6 D5 D4 D3 D2 D1 D0
定义
x x SCP1 SCP0 x SCR2 SCR1 SCR0
复位
0 0 0 0 0 0 0 0
D7,D6,D3:未定义.设置时,为了方便,一般取0.
D5~D4 — SCP位:波特率预分频位(SCI Baud Rate Prescaler Bits).这2位定义波特率预分频值,记为:PD,定义如下:
SCP1,SCP0=00 PD=1
=01 PD=3
=10 PD=4
=11 PD=13
D2~D0 — SCR位:波特率选择位(SCI Baud Rate Select Bits).这3位定义波特率另一分频值,记为:BD,定义如下:
SCR2,SCR1,SCR0=000 BD=1 (20)
=001 BD =2 (21)
=010 BD =4 (22)
=011 BD =8 (23)
=100 BD =16 (24)
=101 BD =32 (25)
=110 BD =64 (26)
=111 BD =128 (27)
设fSCI为串行通信时钟源频率,fSCI= fBUS或CGMXCLK,取决于CONFIG2的SCIBDSRC,一般设定SCIBDSRC=1,SCI用内部总线时钟,则fSCI= fBUS,则波特率的定义公式为:
Bt=fBUS /(64×PD×BD)
例如:fBUS=2.4576MHz,取PD=1(即SCP1,SCP0=00),BD=4(即SCR2,SCR1,SCR0=010),则波特率=2457600 /(64×1×4) = 9600.
(2)SCI控制寄存器1(SCI Control Register 1,SCC1)
SCI控制寄存器共有3个,分别称为SCC1,SCC2,SCC3.对它们的写入,实现对SCI的设置.下面分别介绍.带有下划线的位,为初学时必须重点掌握的位.SCC1的地址是:$0013,定义为:
数据位
D7 D6 D5 D4 D3 D2 D1 D0
定义
LOOPS ENSCI TXINV M WAKE ILTY PEN PTY
复位
0 0 0 0 0 0 0 0
D7 — LOOPS位:循环模式选择位(Loop Mode Select Bit),LOOPS=1,循环模式;LOOPS=0,正常功能.在循环模式下,接收引脚RxD与SCI内部断开,内部发送数据直接作为接收的输入,用于自测试.
D6 — ENSCI位:SCI允许位(Enable SCI Bit).ENSCI=1,允许SCI,这意味着PTE0/TxD,PTE1/RxD两个引脚作为串行通信引脚使用,而不作为普通I/O.否则,若设ENSCI=0,则禁止SCI,PTE0/TxD,PTE1/RxD两个引脚则作为普通I/O使用.
D5 — TXINV位:发送反转标志位(Transmit Inversion Bit).TXINV=1,发送输出为反码;TXINV=0正常码输出.
D4 — M位:模式—字符长度选择位(Mode — Character Length Bit).定义收发数据格式,只有两种可能:M=1,9位字符;M=0,8位字符.
D3 — WAKE位:唤醒条件位(Wakeup Condition Bit).WAKE=1,地址唤醒;WAKE=0,空闲线唤醒.关于唤醒功能(Wake-up feature),这里作概要介绍.初学时跳过此段.在一个典型的多处理器系统中,软件协议通常在消息的开始判断地址.唤醒功能允许无关的MCU忽略消息的剩余部分,同时禁止这些MCU接收器的标志(和中断)处理,直到数据线返回到空闲状态.SCI接收器可以被一串包含10个(或11个)1的空闲字符串唤醒.发送器软件必须在发送连续消息的间隙提供必须的空闲字符串,并保证空闲字符串不在消息中出现.还有一种将休眠中的MCU唤醒的办法:使MCU接收到的字符的最高位为1.MC68HC08系列单片机的SCI接收器具有唤醒功能.这个功能在多处理器系统中非常有用,暂时没有工作的微处理器可以处于休眠状态以节省电力,需要工作时再由主机将其唤醒.
D2 — ILTY位:空闲线类型位(Idle Line Type Bit),决定SCI何时开始计数"空闲字符"的位数.ILTY=1,空闲字符位从"停止位"开始计数;ILTY=0,空闲字符位从"起始位"开始计数.从"起始位"开始计数,则"停止位"前的一串"1"可能产生错误的空闲线条件.从"停止位"开始计数,可避免错误的空闲线识别,但需要适当地同步发送操作.
D1 — PEN位:奇偶校验允许位(Parity Enable Bit).PEN=1,允许奇偶校验;PEN=0,不进行奇偶校验.
D0 — PTY位:奇偶校验类型选择位(Parity Bit).PTY=1,奇校验;PTY=0,偶校验.不进行奇偶校验时,该位无意义,一般写0.
(3)SCI控制寄存器2(SCI Control Register 2,SCC2)
SCC2的地址是:$0014,定义为:
数据位
D7 D6 D5 D4 D3 D2 D1 D0
定义
SCTIE TCIE SCRIE ILIE TE RE RWU SBK
复位
0 0 0 0 0 0 0 0
D7 — SCTIE位:发送中断允许位(SCI Transmit Interrupt Enable Bit).SCTIE=1,允许产生发送中断请求;反之不允许.
D6 — TCIE位:发送完成中断允许位(Transmission Complete Interrupt Enable Bit).TCIE=1,允许发送完成产生中断;反之不允许.
D5 — SCRIE位:接收中断允许位(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位:发送终止位(Send Break Bit).SBK=1,发送终止字符(逻辑1);SBK=0,正在发送非终止字符.
(4)SCI控制寄存器3(SCI Control Register 3,SCC3)
SCC3的地址是:$0015,定义为:
数据位
D7 D6 D5 D4 D3 D2 D1 D0
定义
R8 T8 DMARE DMATE ORIE NEIE FEIE PEIE
复位
0 0 0 0 0 0 0 0
D7 — R8位:接收位8 (Received bit 8).该位只读.
D6 — T8位:发送位8(Transmitted Bit 8).
D5 — DMARE位:DMA接收允许位(DMA Receive Enable Bit).(本MCU无此功能,应为0).
D4 — DMATE位:DMA发送允许位(DMA Transfer Enable Bit).(本MCU无此功能,应为0).
D3 — ORIE位:接收器溢出中断允许位(Receiver Overrun Interrupt Enable Bit).ORIE=1,允许接收器溢出中断;反之不允许.
D2 — NEIE位:接收器噪声错误中断允许位(Receiver Noise Error Interrupt Enable Bit).NEIE=1,允许接收器噪声错误中断;反之不允许.
D1 — FEIE位:接收器帧错误中断允许位(Receiver Framing Error Interrupt Enable Bit).FEIE=1,允许接收器帧错误中断;反之不允许.
D0 — PEIE位:接收器奇偶错误中断允许位(Receiver Parity Error Interrupt Enable Bit).PEIE=1,允许接收器奇偶错误中断;反之不允许.
(5)SCI状态寄存器1(SCI Status Register 1,SCS1)
SCI状态寄存器共有2个,分别称为SCS1,SCS2.对它们的读出,可以得到当前SCI的状态.SCS1为只读寄存器,它的地址是:$0016,定义为:
数据位
D7 D6 D5 D4 D3 D2 D1 D0
定义(只读)
SCTE TC SCRF IDLE OR NF FE PE
复位
1 1 0 0 0 0 0 0
D7 — SCTE位:发送缓冲区空标志位 (SCI Transmitter Empty bit).该位为1时表明要发送的数据已经移入发送移位寄存器,可以发送一个新的数据.
D6 — TC位:发送完成标志位(Transmission Complete Bit).该位为1,表明发送已经完成,该位为0,表明发送正在进行.
D5 — SCRF位:接收器满标志位(SCI Receiver Full Bit).该位为1,表明接收器已满,可以从SCI数据寄存器SCDR中读取收到的数据.
D4 — IDLE位:接收器空闲标志位(Receiver Idle Bit).该位为1,表明接收器处于空闲状态.
D3 — OR位:接收器溢出标志位(Receiver Overrun Bit).该位为1,表明接收器溢出.
D2 — NF位:接收器噪声标志位(Receiver Noise Flag Bit).该位为1,表明接收器出现噪声错误.
D1 — FE位:接收器帧错误标志位(Receiver Framing Error Bit).该位为1,表明接收器出现帧错误.
D0 — PE位:接收器奇偶错误标志位(Receiver Parity Error Bit).该位为1,表明接收器出现奇偶校验错误.
(6)SCI状态寄存器2(SCI Status Register 2,SCS2)
SCS2为只读寄存器,它的地址是:$0017,定义为:
数据位
D7 D6 D5 D4 D3 D2 D1 D0
定义(只读)
BKF RPF
复位
0 0 0 0 0 0 0 0
D7~D2:未定义.
D1 — BKF位:终止码标志位(Break Flag Bit).该位为1,检测到终止码.
D0 — RPF位:接收进行标志位(Reception in Progress Flag Bit).该位为1,表明正在接收.
(7)SCI数据寄存器(SCI Data Register —SCDR)
SCDR为SCI系统最常用的寄存器,它的地址是:$0018.写入时,为要发送的8位数据,记为:T7~T0;读出时,为接收的8位数据,记为:R7~R0.不受复位影响.
8.3.2 串行口初始化与收发编程的基本方法
不论用查询方式还是中断方式进行串行通信编程,在程序初始化时均必须对SCI进行初始化,主要进行波特率设置,通信格式的设置,发送接收数据方式的设置等,本小节给出最基本的用法,以作为HC08系列单片机的串行通信编程入门.下一小节将给出规范的串行通信编程子程序,读者可以直接将其应用于实际的嵌入式应用系统的开发中.
(1)SCI初始化
有关口地址定义已经在头文件GP32.H中给出, SCC1,SCC2,SCC3,SCBR,SCS1,SCS2,SCDR可以直接使用.
对SCI进行初始化,最少由以下三步构成:
第一步:定义波特率.一般选择内部总线时钟为串行通信的时钟源(这个设置在MCU的系统初始化中完成,令系统设置寄存器CONFIG2的SCIBDSRC位为1即可,从学习顺序角度,本书将这部分内容放在第12章,此处默认系统初始化时已经做了这样的设置).设MCU的系统初始化时已经定义总线频率为fBUS,同时准备定义串行通信波特率,记为Bt.通过选择SCI波特率寄存器SCBR的波特率预分频位SCP(两位),波特率选择位SCR(三位),以便选择合适的分频系数PD,BD,代入公式Bt=fBUS /(64×PD×BD),使得Bt等于需要的值.当然,从表面上看,由这个公式,已知fBUS,Bt,求PD,BD两个未知数不行.但只要注意到,在介绍SCI波特率寄存器SCBR时,PD,BD取值是有限制的,这样,由fBUS,Bt可以"拼凑"出PD,BD,从而得到波特率寄存器SCBR的设定值.为此,不少书籍还专门列了一个表,给出不同fBUS,Bt下的PD,BD的"拼凑"值.这里举例说明,设总线频率fBUS=2.4576MHz,准备定义波特率Bt=9600,则由公式Bt=fBUS /(64×PD×BD)可以"拼凑"出,PD=1(即SCP1,SCP0=00),BD=4(即SCR2,SCR1,SCR0=010),波特率寄存器SCBR的未定义位取0,则SCBR的值应为二进制"00000010",程序如下:
;总线频率fBUS=2.4576MHz,定义波特率Bt=9600
LDA #%00000010
STA SCBR
第二步:写控制字到SCI控制寄存器1(SCC1).设置是否允许SCI,数据长度,输出格式,选择唤醒方法,是否校验等.例如,设定允许SCI,正常码输出,8位数据,无校验,SCC1取值应为二进制"01000000",程序如下:
;设置允许SCI,正常码输出,8位数据,无校验
LDA #%01000000
STA SCC1
实际上,这种情况只是令SCC1的SCI允许位(第6位)为1,其它位取默认值.
第三步:写控制字到SCI控制寄存器2(SCC2).设置是否允许发送与接收,是中断接收还是查询接收等.例如,设置允许发送(TE=1),允许接收(RE=1),查询方式收发,SCC2取值应为二进制"00001100",程序如下:
;设置允许发送,允许接收,查询方式收发
LDA #%00001100
STA SCC2
用查询方式,可以不对SCI控制寄存器3(SCC3)初始化,另外几个寄存器供后面编程使用,不需初始化.
(2)发送一个数据与接收一个数据
一般情况下,对SCI的初始化只在程序的初始化部分进行一次,串行通信的基础编程是发送与接收数据.发送数据是通过判断状态寄存器SCS1的第7位(SCTE)进行的,而接收数据是通过判断状态寄存器SCS1的第5位(SCRF)进行的.不论是发送还是接收,均使用SCI数据寄存器SCDR.发送时,将要发送的数据送入SCDR即可,接收时,从SCDR中取出的即是收到的数据.
例如,下面的程序将寄存器A中的数从串行引脚TxD发送出去.通过对状态寄存器SCS1的第7位(SCTE)判断是否可以向数据寄存器SCDR送数,若SCTE=1可以送数,否则必须等待.
;串行发送A中的数
BRCLR 7,SCS1,* ;SCS1.7=0 为0则等待
STA SCDR ;SCS1.7=1,可以发送数据
要以查询方式接收一个数据,首先通过状态寄存器SCS1的第5位(SCRF)判断有没有数据可收,若SCRF=1,则有数据可收,下面程序持续等待串行口(实际上是RxD引脚)直到接收到一个数,数据接收后放入寄存器A中:
;查询方式接收一个串行数据,接收的数据放入寄存器A中
BRCLR 5,SCS1,* ;SCS1.5=0 为0则等待
LDA SCDR ;SCS1.5=1,可以取出数据
8.4 串行通信编程实例
本节给出较规范的用08汇编语言及08C语言编的串行通信子程序,包括SCI初始化,发送一个字节,接收一个字节,发送N个字节,接收N个字节等子程序,然后给出一个使用这些子程序的测试程序,并给出PC机方程序.读者可以直接使用这些子程序进行08系列MCU的串行通信编程.
8.4.1 08汇编语言串行通信子程序
(1)SCI初始化汇编子程序
对串行口的初始化一般在主循环之前进行,即使以中断方式接收或发送,在初始化子程序中只定义查询方式收发.允许中断的设置,在进入主循环之前进行.下面给出的初始化程序,将在本教程的各个实例中使用.
串行口初始化汇编语言例
*SCIInit.asm:串行口初始化子程序------------------------*
*功 能:对串行口进行初始化,允许SCI,正常码输出,8位数据, *
* 无校验等,允许发送器允许接收器.查询方式收发, *
* 波特率为9600(设fBUS=2.4576MHz) *
*入 口:无 *
*出 口:无 *
*------------------------------------------------------*
SCIInit:
PSHA
;总线频率fBUS=2.4576MHz,定义波特率Bt=9600
LDA #%00000010
STA SCBR
;设置允许SCI,正常码输出,8位数据,无校验
LDA #%01000000
STA SCC1
;设置允许发送,允许接收,查询方式收发
LDA #%00001100
STA SCC2
PULA
RTS
(2)串行发送与接收汇编通用子程序
仔细分析可以发现,与串行通信相关的程序,发送与接收使用同一个寄存器的不同位作为测试标志,发送与接收的数据寄存器地址相同.而在串行通信中,发送一个字节与发送N个字节,接收一个字节与接收N个字节的子程序是最基本的,因此这里给出这些基本子程序.为了方便实际应用,对程序做了规范,可以应用于08系列的任何一个型号MCU.读者应仔细理解这些子程序的编程思路,以便为后面的学习打下扎实的基础.
串行发送与接收汇编通用子程序HC08SCI.ASM
*H08SCI.ASM--------------------------------------------*
*文件描述:本文件包含了HC08串行通信子程序,分别为: *
*(1)SCISend1:串行发送A中的1个字节 *
*(2)SCISendN:串行发送N个字节 *
*(3)SCIRe1:串行接收一个字节->A *
*(4)SCIReN:串行接收N个字节 *
*------------------------------------------------------*
*[寄存器及相关位定义]
ReSendStatusR EQU SCS1 ;SCI状态寄存器1
ReTestBit EQU 5 ;接收缓冲区满标志位
SendTestBit EQU 7 ;发送缓冲区空标志位
ReSendDataR EQU SCDR ;SCI数据寄存器
*SCISend1:串行发送A中的1个字节-------------------------*
*功 能:串行口发送A中的1个字节数据 *
*入 口:A=待发送的数据 *
*出 口:无 *
*堆栈深度:2 *
*------------------------------------------------------*
SCISend1:
BRCLR SendTestBit,ReSendStatusR,SCISend1
STA ReSendDataR
RTS
*SCISendN:串行发送N个字节------------------------------*
*功 能:串行发送以HX为首地址的N个字节数据 *
*入 口:A=字节个数 HX=首地址 *
*出 口:无 *
*堆栈深度:2+1=3 *
*------------------------------------------------------*
SCISendN:
;在堆栈区开辟1个字节作临时变量
AIS #-!1
;若发送字节数为0,退出
STA !1,SP
CMP #!0
BEQ SCISendN_EXIT
SCISendN_1:
LDA ,X ;从存储器中取出待发送的数据
JSR SCISend1
AIX #!1
DBNZ !1,SP,SCISendN_1 ;N-1≠0转
SCISendN_EXIT:
;释放1个字节临时变量
AIS #!1
RTS
*SCIRe1:串行接收一个字节->A----------------------------*
*功 能:(1) 串行接收1个字节的数据放在A中 *
* (2) 约655350时钟周期内收不到数返回, *
* 若时钟周期=0.4us 大约等待2.6S *
*入 口:无 *
*出 口:A=接收的数据 C=是否收到数据标志 0收到 1未收到 *
*堆栈深度:2+2=4 *
*------------------------------------------------------*
SCIRe1:
PSHH
PSHX
;等待接收一个字节数据
LDHX #$FFFF ;循环次数
SCIRe1_1:
BRCLR ReTestBit,ReSendStatusR,SCIRe1_2 ;无数据,转
LDA ReSendDataR ;收到的数据放入A中
CLC ;C=0
BRA SCIRe1_3 ;收到数据,退出
SCIRe1_2:
NOP
AIX #-$1
CPHX #$0000
BNE SCIRe1_1
;等待时间到,未收到数据,令c=1,A=FF,返回
LDA #$FF
SEC ;C=1
SCIRe1_3:
PULX
PULH
RTS
*SCIReN:串行接收N个字节--------------------------------*
*功 能:串行接收N个字节放在以HX为首地址的内存中 *
*入 口:A=待接收数据的字节数N,HX=接收数据存放的首地址 *
*出 口:C=是否收到数据标志 0收到 1未收到 *
*堆栈深度:2+4+1=7 *
*内部调用:SCIRe1 *
*------------------------------------------------------*
SCIReN:
;在堆栈区开辟1个字节作临时变量
AIS #-!1
;若接受字节数为0,退出
STA !1,SP
CMP #!0
BEQ SCIReN_EXIT
SCIReN_1:
JSR SCIRe1 ;调用接收1个字节的子程序
BCS SCIReN_EXIT ;C=1未收到数据,退出
STA ,X ;收到数据,放入内存
AIX #!1 ;HX+1->HX
DBNZ !1,SP,SCIReN_1
SCIReN_EXIT:
;释放1个字节临时变量
AIS #!1
RTS
8.4.2 08汇编语言串行通信测试实例
为了验证子程序的正确性,这里给出简明的测试实例.由于串行通信涉及两个设备,所以本例选用MCU为一方,PC机为另一方,PC机方程序用VB编程.首先给出MCU方以查询方式进行接收,随后还给出MCU方以中断方式接收的实例,以便比较.程序中给出了详细的注释.
下列实例中,不论是查询方式,还是中断方式,也不论是汇编语言,还是08C语言,MCU方的程序功能是一致的:把通过串行口收到的数据发送回去.PC机方的VB测试程序只有一个,在各实例目录的VB_SCI子目录中.
(1)查询方式MCU方主程序
实例编号:A02_1 路径:\ASM\A02_1串行通信查询方式 (H08SCI_1.ASM)
*------------------------------------------------------------*
*文 件 名:H08SCI_1.asm *
*硬件连接:无 *
*程序描述:利用查询方式把收到的数据发送回去 *
*目 的:初步掌握利用查询方式进行串行通信的基本知识 *
*--------------《嵌入式应用技术基础教程》教学实例----------------*
*[头文件]
$include "GP32ASM.H" ;包含GP32的头文件
*[两个起始地址名]
RAMstartAddr equ $0040 ;RAM的起始地址
FlashStartAddr equ $8000 ;程序开始地址
*[内存变量]
org RAMstartAddr ;RAM的起始地址
SerialBuff rmb 1 ;数据存储单元
*=======================================================
*[主程序]
org FlashStartAddr ;程序起始地址
MainInit: ;复位后程序从此开始执行
;[系统初始化]
SEI
LDHX #$023F ;堆栈初始化
TXS
JSR GP32Init ;调系统初始化子程序GP32Init
;[串行口初始化]
JSR SCIInit
;[程序总循环入口]
MainLoop:
;[等待接收1个数据]
LDA #!1
LDHX #SerialBuff
JSR SCIReN
BCS MainLoop ;未收到数据,继续等待
;[发送接到的一个数据]
LDA #!1
LDHX #SerialBuff
JSR SCISendN
BRA MainLoop
*[外部子程序存放处,这些子程序都在当前目录中]
$INCLUDE "H08SCI.asm"
$INCLUDE "GP32init.asm"
$INCLUDE "SCIInit.asm"
*[中断向量]
ORG $FFFE ;复位矢量
DW MainInit
(2)PC机方VB程序
图8-6给出了PC机方VB程序的界面.其功能是:在"发送窗口"的文本框输入字符,单击"发送"按钮,其文本框中的字符被发送出去.任何时候,只要PC机串行口收到数据,则显示在"接收窗口"."接收窗口"内的两个文本框,分别显示接收数据的字符和十六进制数.这个VB程序在本书的几个串行实例的目录中是一致的.同时,也可方便地用于整个学习过程.
实例编号:A02_1 路径:\ASM\A02_1串行通信查询方式\VB_SCI
'程序描述:
' (1)把发送窗口中的数据从COM1发送出去
' (2)把接收到的数据显示在接收窗口中
'-------------------------------------------------------
Option Explicit '检查未经声明的变量
Dim SendData() As Byte '发送数据数组
Dim RecvData() As Byte '接收数据数组
Private Sub Form_Load()
'串行口初始化
Call SCIinit(1, "9600,N,8,1")
'清空有关文本框
TxtSEND.Text = ""
TxtRECV.Text = ""
'开放串行中断
MSComm1.RThreshold = 1
End Sub
Private Sub CmdSEND_Click() '单击"发送"按钮
Dim i As Integer
If TxtSEND.Text = "" Then
TxtRECV.Text = ""
GoTo CmdSEND_Click_Exit
End If
ReDim SendData(Len(TxtSEND.Text) - 1)
For i = 0 To Len(TxtSEND.Text) - 1
SendData(i) = Asc(Mid$(TxtSEND.Text, i + 1, 1))
Next i
MSComm1.Output = SendData
CmdSEND_Click_Exit:
End Sub
Public Sub MSComm1_OnComm() '串行接收中断
Dim i As Integer
Static S1 As String
If Len(Trim(TxtRECV.Text)) = 0 Then S1 = ""
MSComm1.RThreshold = 0 '关闭串行中断
RecvData = MSComm1.Input
For i = LBound(RecvData) To UBound(RecvData)
S1 = S1 & Chr$(RecvData(i))
Next i
TxtRECV.Text = S1
If Len(S1) >= 70 Then S1 = ""
MSComm1.RThreshold = 1 '开放串行中断
End Sub

Private Sub CmdCLR_Click() '单击"清空"按钮
TxtSEND.Text = ""
TxtRECV.Text = ""
End Sub

Private Sub CmdEXIT_Click() '单击"退出"按钮
If MSComm1.PortOpen = True Then MSComm1.PortOpen = False
End
End Sub
Rem 串行口初始化
Private Sub SCIinit(ByVal COMx As Byte, ByVal SCIFormat As String)
If MSComm1.PortOpen = True Then
MSComm1.PortOpen = False
End If
MSComm1.CommPort = COMx '串行口号
MSComm1.Settings = SCIFormat '定义传输格式
MSComm1.InputMode = comInputModeBinary '二进制数据格式
MSComm1.RThreshold = 0 '关闭串行中断
MSComm1.InputLen = 0 '一次读取缓冲区全部数据
MSComm1.PortOpen = True '打开串行口
MSComm1.InBufferCount = 0
End Sub
(3)中断方式MCU方主程序
实例编号:A02_2 路径:\ASM\A02_2串行通信中断方式 (H08SCI_2.ASM)
*------------------------------------------------------*
*文 件 名:H08SCI_2.asm *
*硬件连接:无 *
*程序描述:利用中断方式把收到的数据发送回去 *
*目 的:初步掌握利用中断方式进行串行通信的基本知识 *
*-------《嵌入式应用技术基础教程》教学实例------------*/
*[头文件]
$include "GP32ASM.H" ;包含GP32的头文件
*[两个起始地址名]
RAMstartAddr equ $0040 ;RAM的起始地址
FlashStartAddr equ $8000 ;程序开始地址
*[内存变量]
org RAMstartAddr ;RAM的起始地址
SerialBuff rmb 8 ;缓冲区
*======================================================*
*[主程序]
org FlashStartAddr ;程序起始地址
MainInit: ;复位后程序从此开始执行
;[系统初始化]
SEI
LDHX #$023F ;堆栈初始化
TXS
JSR GP32Init ;调系统初始化子程序GP32Init
;[串行口初始化]
JSR SCIInit
BSET 5,SCC2 ;设置接收中断允许
;[开放总中断]
CLI
;[程序总循环入口]
MainLoop:
NOP
NOP
BRA MainLoop
*[接收中断子程序]
SCIRecINT:
SEI ;关总中断
PSHH
;[接收1个数据]
JSR SCIRe1
;[发送接到的数据]
JSR SCISend1
PULH
CLI ;开总中断
RTI ;中断返回
*[以下为子程序存放处,这些子程序都在当前目录中]
$INCLUDE "H08SCI.asm"
$INCLUDE "GP32init.asm"
$INCLUDE "SCIInit.asm"
*------------------------------------------------------*
ORG $FFE4 ;SCI接收中断矢量
DW SCIRecINT
ORG $FFFE ;复位矢量
DW MainInit
8.4.3 08C语言串行通信子程序与测试实例
(1)SCI初始化08C语言子程序
串行口初始化08C语言例
/*SCIInit:串行口初始化子程序--------------------------------------------*
*功 能: 对串行口进行初始化,默认为允许SCI,正常码输出,8位 *
* 数据,无校验等,允许发送器允许接收器.查询方式收发, *
* 波特率为9600 (设fBUS=2.4576MHz) *
*参 数:无 *
*返 回:无 *
*-------------------------------------------------------------------------------*/
#include "GP32C.H"
void SCIInit(void)
{ //总线频率fBUS=2.4576MHz,定义波特率Bt=9600
SCBR=0b00000010;
//设置允许SCI,正常码输出,8位数据,无校验
SCC1=0b01000000;
//设置允许发送,允许接收,查询方式收发
SCC2=0b00001100;
}
(2)串行发送与接收08C语言通用子程序
串行发送与接收08C语言通用子程序SCI.C
/*-----------------------------------------------------*
*文件描述:本文件包含了串行通信的4子程序,分别为: *
*(1)SCISend1:串行发送1字节 *
*(2)SCISendN:串行发送n字节 *
*(3)SCIRe1:串行接收1字节 *
*(4)SCIReN:串行接收n字节 *
*-------------《嵌入式应用技术基础教程》--------------*/
//[以下为子程序源代码]
//[包含头文件]
#include "SCI.h"
/*SCISend1:串行发送1个字节-----------------------------*
*功 能:串行发送1个字节 *
*参 数:要发送的数据 *
*返 回:无 *
*-----------------------------------------------------*/
void SCISend1(unsigned char o)
{//判断ReStatusR的第SendTestBit位是否为1,是1可以发送
while(1)
if ((ReSendStatusR & (1< { ReSendDataR=o;
break;}
}
/*SCISendN:串行发送N个字节-----------------------------*
*功 能:发送数组中的N个字节数据 *
*参 数:待发送的数据字节数及其要存放的数组首地址 *
*返 回:无 *
*-----------------------------------------------------*/
void SCISendN(unsigned char n,unsigned char ch[])
{int i;
for(i=0;i SCISend1(ch[i]);
}
/*SCIRe1:串行收一个字节数据----------------------------*
*功 能:从串行口接收1个字节的数据 *
*参 数:标志指针p *
*返 回:接收到的数据(若接收失败,返回0xff) *
*说 明:参数*p带回接收标志=0收到数据,=1未收到数据 *
*-----------------------------------------------------*/
unsigned char SCIRe1(unsigned char *p)
{ unsigned int k;
unsigned char i;
//ReStatusR第ReTestBit位为1表示可接收数据
for(k=0;k<0xfbbb;k++)
if ((ReSendStatusR & (1<=0xfbbb)
{i=0xff;
*p=0x01;}
return i; //返回接收到的数据
}
/*SCIReN:HC08串行接收N个字节---------------------------*
*功 能:接收N个字节数据,并存放在ch数组中 *
*参 数:待接收的数据字节数及其存放的数组首地址 *
*返 回:接收标志=0收到数据,=1未收到数据 *
*-----------------------------------------------------*/
unsigned char SCIReN(unsigned char n,unsigned char ch[])
{int m;
unsigned char fp;
m=0;
while (m {
ch[m]=SCIRe1(&fp);
if (fp==1) return 1;
m++;
}
return 0;
}
(3)查询方式08C语言主程序
实例编号:C02_1 路径:\C\C02_1串行通信查询方式 (H08SCI_1.prj)
/*-----------------------------------------------------*
*工 程 名:H08SCI_1 *
*硬件连接:无 *
*程序描述:把收到的数据发送回去 *
*目 的:初步掌握利用查询方式进行串行通信的基本知识 *
*-------《嵌入式应用技术基础教程》教学实例------------*/
//头文件
#include "GP32C.H" //包含头文件
#include "SCI.h" //串行通信子程序头文件
//函数声明
extern void SCIInit(void); //串行口初始化子程序
//内存变量声明
unsigned char SerialBuff[]; //存放接收数据的数组
//主程序
void main()
{
unsigned char i;
SCIInit(); //调串行口初始化子程序
while(1)
{
i=SCIReN(1,SerialBuff); //等待接收1个数据
if(i==0) SCISendN(1,SerialBuff); //发送接到的数据
}
}
(4)中断方式08C语言主程序
实例编号:C02_2 路径:\C\C02_2串行通信中断方式 (H08SCI_2.prj)
/*-----------------------------------------------------------*
*工 程 名:H08SCI_2 *
*硬件连接:无 *
*程序描述:把收到的数据发送回去 *
*目 的:初步掌握利用中断方式进行串行通信编程 *
*-------------《嵌入式应用技术基础教程》教学实例--------------*/
//头文件
#include "GP32C.H" //包含头文件
#include "SCI.h" //串行通信子程序头文件
//函数声明
extern void SCIInit(void); //串行口初始化子程序
//内存变量声明
unsigned char SerialBuff[]; //存放接收数据的数组
//主程序
void main()
{
asm("SEI"); //禁止所有中断
SCIInit(); //串行口初始化
SCC2=(1 LDX R0 ;地址基值
INCX ;移到低8位上
ADD ADValue,X ;与上次低8位相加
STA ADValue,X ;放回原处
DECX ;地址退1,回到高8位
LDA TLC2543D ;取出高4位->A
ADC ADValue,X ;与高位带进位相加
STA ADValue,X ;放回原处
INC R0 ;地址基值+2
INC R0
LDX R2
CBEQX #$00,ADP3 ;若为0,下一片TLC2543
BRA ADP0
ADP3:
LDA R1 ;下一片片号
SEC
ROLA
STA R1
CBEQA #%11110111,ADP6 ;完成3片一次采集
BRA ADPP
ADP6: ;完成3片一次采集,继续
DBNZ R3,AD16
;求16次平均
MOV #$00,R0
MOV #!33,R1 ;共33路
ADP7:
LDX R0
INCX
LDA ADValue,X
AND #$F0
NSA
STA ADValue,X
DECX
LDA ADValue,X
NSA
PSHA
AND #$0F
STA ADValue,X ;高4位完成
PULA
AND #$F0
INCX
ADD ADValue,X
STA ADValue,X ;低8位完成
INC R0 ;基址+2
INC R0
DBNZ R1,ADP7
RTS
练习与思考题
1.单片机串行通信接口为什么要进行电平转换 如何进行电平转换
2.简述串行通信收发数据的工作过程.
3.编写一程序,其功能是:以查询方式从串行口等待接收一个字节的数据,收到后,再通过串行口将收到的一个字节的数据发送出去.验证该程序可以通过微机向MCU发送一字节的数据,同时通过串行口接收一个字节的数据,使收到的数据与发出的数据相同.
4.以串行中断方式编程完成第3题的功能.
5.简要说明串行通信接口(SCI)与串行外设接口(SPI)的异同点.
6.简述SPI的收发数据的工作过程.
7.除本章给出的实例外,请另举一例说明SPI的应用方法.[提示:利用SPI可以实现两个单片机之间的连接,请给出电路设计及编程方法]
第8章 串行通信接口SCI与串行外设接口SPI
图8-2 9芯串行接口排列
9
8
7
6
图8-1 SCI数据格式
开始位
停止位
第7位
第6位
第5位
第4位
1μ×4
TTL电平
转为232电平
TTL电平
OUT IN
+5V
第1位
第3位
+5V GND
第2位
5
3
2
1
4
第0位
图8-8 TLC2543的封装管脚图
Vcc
EOC
I/O CLOCK
DATA INPUT
DATA OUT
REF+
REF-
AIN10
AIN9
AIN0
AIN1
AIN2
AIN3
AIN4 AIN5
AIN6
AIN7
AIN8 AIN9
1 20
2 19
3 18
4 17
5 16
6 15
14
13
12
10 11
SPSCK SPSCK
图8-6 串行测试程序PC机方VB程序界面
图8-7 CPHA/时序
SCI波特率寄存器
SCI状态寄存器
SCI 控制寄存器
发送引脚TxD
接收引脚RxD
发送移位寄存器
接收移位寄存器
MCU 的 内 部 总 线 (Internal Bus)
SCI 数据寄存器
图8-5 SCI编程模型
1 2 3 4 5 6 7 8
16 15 14 13 12 11 10 9
MAX232CPE
图8-3 MAX232引脚
232电平
OUT IN
1 2 3 4 5 6 7 8 9 10
40 39 38 37 36 35 34 33 32 31
MC68HC908GP32
0.1μ
+5V
30 29 28 27 26 25 24 23 22 21
PLL滤波
10K
0.01μ
0.47μ
晶振电路
150K
32.768
15P
10K
20P
复位电路
0.1μ
RST他TTT
51Ω
10K
+5V
11 12 13 14 15 16 17 18 19 20
0.1μ
+5V
图8-4 具有串行通信功能的MC68HC908G932最小系统电路原理图
MC68HC908GP32
PTC0
MISO
MOSI
SPSCK
PTC1
PTC2
TLC2543(第0片)
AIN0
:
DATA OUT :
DATA INPUT :
I/O CLOCK AIN10
模拟量输入
:
:
:
TLC2543(第1片)
AIN0
:
DATA OUT :
DATA INPUT :
I/O CLOCK AIN10
:
:
:
TLC2543(第2片)
AIN0
:
DATA OUT :
DATA INPUT :
I/OCLOCK AIN10
:
:
:
图8-9 基于SPI的A/D转换扩展电路
从MCU
波特率发生器
MOSI MOSI
主MCU
MISO MISO
移位寄存器
移位寄存器
图8-6 SPI全双工主-从连接

免责声明:作品版权归所属媒体与作者所有!!本站刊载此文仅为普及科学技术知识提供更多信息。如果您认为我们侵犯了您的版权,请告知!本站核实后立即删除。kpzsnet#126.com (#改为@)
[] [返回上一页] [打 印] [收 藏]
下一篇博览:实验系统介绍
∷相关博览评论∷    (评论内容只代表网友观点,与本站立场无关!) [更多评论...]
关于本站 - 帮助 - 合作 - 声明 - 连接 - 地图 -
Copyright ?2002-2005 Kpzs.Net. All Rights Reserved .
BY::KPZS.NET