1 / 42

第 7 章 串行通信接口 (SCI)

第 7 章 串行通信接口 (SCI). 主要内容 异步串行通信的基础知识 电平转换电路与 SCI 通用编程原理 GP32SCI 模块寄存器 串行口初始化与收发编程的基本方法 串行通信通用函数与测试实例 串行通信进一步讨论. 停止位. 第 0 位. 第 2 位. 第 4 位. 第 6 位. 第 1 位. 第 3 位. 第 5 位. 第 7 位. 开始位. SCI 数据格式. 7.1 异步串行通信的基础知识. 7.1.1 基本概念 (1)异步串行通信的格式

huslu
Download Presentation

第 7 章 串行通信接口 (SCI)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第7章 串行通信接口(SCI) 主要内容 • 异步串行通信的基础知识 • 电平转换电路与SCI通用编程原理 • GP32SCI模块寄存器 • 串行口初始化与收发编程的基本方法 • 串行通信通用函数与测试实例 • 串行通信进一步讨论

  2. 停止位 第0位 第2位 第4位 第6位 第1位 第3位 第5位 第7位 开始位 SCI数据格式 7.1异步串行通信的基础知识 7.1.1 基本概念 (1)异步串行通信的格式 SCI通常采用NRZ数据格式,即:standard non-return-zero mark/space data format,译为:“标准不归零传号/空号数据格式”。“不归零”的最初含义是:用正、负电平表示二进制值,不使用零电平。“mark/space”即“传号/空号”分别是表示两种状态的物理名称,逻辑名称记为“1/0”。下图给出了8位数据、无校验情况的传送格式。

  3. (2)串行通信的波特率 波特率(baud rate):每秒内传送的位数。 波特率单位是位/秒,记为bps。通常情况下,波特率的单位可以省略。通常使用的波特率有300、600、900、1200、1800、2400、4800、9600、19200、38400。

  4. (3)奇偶校验 字符奇偶校验检查(character parity checking)称为垂直冗余检查( vertical redundancy checking,VRC),它是每个字符增加一个额外位使字符中“1”的个数为奇数或偶数。 奇校验:如果字符数据位中“1”的数目是偶数,校验位应为“1”,如果“1”的数目是奇数,校验位应为“0”。 偶校验:如果字符数据位中“1”的数目是偶数,则校验位应为“0”,如果是奇数则为“1”。

  5. (4)串行通信的传输方式 单工(Simplex):数据传送是单向的,一端为发送端,另一端为接收端。这种传输方式中,除了地线之外,只要一根数据线就可以了。有线广播就是单工的。 全双工(Full-duplex):数据传送是双向的,且可以同时接收与发送数据。这种传输方式中,除了地线之外,需要两根数据线,站在任何一端的角度看,一根为发送线,另一根为接收线。一般情况下,MCU的异步串行通信接口均是全双工的。 半双工(Half-duplex):数据传送也是双向的,但是在这种传输方式中,除了地线之外,一般只有一根数据线。任何一个时刻,只能由一方发送数据,另一方接收数据,不能同时收发。在freescale的HC08系列MCU中,监控模式的通信就采用这种方式。

  6. 7.1.2 RS-232C总线标准 MCU引脚一般输入/输出使用TTL电平,而TTL电平的“1”和“0”的特征电压分别为2.4V和0.4V,适用于板内数据传输。为了使信号传输得更远,美国电子工业协会EIA(Electronic Industry Association) 制订了串行物理接口标准RS-232C。RS-232C采用负逻辑,-3V~-15V为逻辑“1”,+3V~+15V为逻辑“0”。RS-232C最大的传输距离是30m,通信速率一般低于20Kbps。

  7. 9芯串行接口排列 9 6 8 7 1 5 4 2 3 7.1.2 RS-232C总线标准 RS-232接口,简称“串口”,它主要用于连接具有同样接口的室内设备。目前几乎所有计算机上的串行口都是9芯接口。右图给出了9芯串行接口的排列位置,相应引脚含义见表7-1。 返回

  8. TTL电平 OUT IN 232电平 OUT IN 51Ω +5V MAX232CPE 16 15 14 13 12 11 10 9 1 2 3 4 5 6 7 8 +5V TTL电平 转为232电平 1μ×4 7.2电平转换电路与SCI通用编程原理 7.2.1 SCI的外围硬件电路 具有SCI接口的MCU,一般具有发送引脚(TxD)与接收引脚(RxD),不同公司或不同系列的MCU,使用的引脚缩写名可能不一致,但含义相同。SCI的外围硬件电路,主要目的是将MCU的发送引脚TxD与接收引脚RxD的TTL电平,通过RS-232电平转换芯片转换为RS-232电平。下图给出一个基本SCI电平转换电路。

  9. 接收引脚RxD 发送引脚TxD 接收移位寄存器 发送移位寄存器 SCI 数据寄存器 MCU 的 内 部 总 线 (Internal Bus) SCI 控制寄存器 SCI状态寄存器 SCI波特率寄存器 SCI编程模型 7.2.2 SCI的基本编程原理 返回

  10. 7.3 GP32 SCI模块寄存器 • SCI的寄存器 MC68HC908GP32的SCI有7个寄存器,地址为$0013~$0019 。 (1)SCI波特率寄存器(SCI Baud Rate Register,SCBR) SCBR的作用是设置串行通信的波特率 ,其地址是$0019。 D7、D6、D3:未定义; D5~D4 — SCP:波特率预分频位(SCI Baud Rate Prescaler Bits) SCP1、SCP0=00 01 10 11 PD= 1 3 4 13

  11. (1)SCI波特率寄存器(SCI Baud Rate Register,SCBR) D2~D0 — SCR:波特率选择位(SCI Baud Rate Select Bits),定义波特率另一分频值,记为:BD,定义如下: SCR2、1、0 =000 001 010 011 100 101 110 111 BD = 1 2 4 8 16 32 64 128 设fSCI为串行通信时钟源频率,fSCI= fBUS或CGMXCLK,取决于CONFIG2的SCIBDSRC,一般设定SCIBDSRC=1,SCI用内部总线时钟,则fSCI= fBUS,则波特率的定义公式为: Bt=fBUS /(64×PD×BD)

  12. 数据位 定义 LOOPS ENSCI TXINV M WAKE ILTY PEN PTY 复位 0 0 0 0 0 0 0 0 SCI允许位 模式-字符长度选择位 空闲线类型位 奇偶校验类型选择位 循环模式选择位 发送反转标志位 奇偶校验允许位 唤醒条件位 (2) SCI控制寄存器1(SCI Control Register 1,SCC1) SCC1的地址是:$0013 ,定义为: D7 D6 D5 D4 D3 D2 D1 D0

  13. 数据位 D7 D6 D5 D4 D3 D2 D1 D0 定义 SCTIE TCIE SCRIE ILIE TE RE RWU SBK 复位 0 0 0 0 0 0 0 0 发送完成中断允许位 空闲线中断允许位 接收器允许位 发送终止位 发送中断允许位 接收中断允许位 接收器唤醒位 发送器允许位 (3) SCI控制寄存器2(SCI Control Register 2,SCC2) SCC2的地址是:$0014 ,定义为:

  14. 数据位 D7 D6 D5 D4 D3 D2 D1 D0 定义 R8 T8 DMARE DMATE ORIE NEIE FEIE PEIE 复位 0 0 0 0 0 0 0 0 发送位8 DMA发送允许位 接收器噪声错误中断允许位 接收器奇偶错误中断允许位 接收位8 DMA接收允许位 接收器帧错误中断允许位 接收器溢出中断允许位 (4) SCI控制寄存器3(SCI Control Register 3,SCC3) SCC3的地址是:$0015 ,定义为:

  15. 数据位 D7 D6 D5 D4 D3 D2 D1 D0 定义(只读) SCTE TC SCRF IDLE OR NF FE PE 复位 1 1 0 0 0 0 0 0 接收器奇偶错误标志位 发送完成标志位 接收器空闲标志位 接收器噪声标志位 发送缓冲区空标志位 接收器满标志位 接收器帧错误标志位 接收器溢出标志位 (5) SCI状态寄存器1(SCI Status Register 1,SCS1 ) SCS1的地址是:$0016 ,定义为:

  16. 数据位 D7 D6 D5 D4 D3 D2 D1 D0 定义(只读) BKF RPF 未定义 复位 0 0 0 0 0 0 0 0 接收进行标志位 终止码标志位 (6) SCI状态寄存器2(SCI Status Register 2,SCS2 ) SCS2的地址是:$0017 ,定义为:

  17. (7) SCI数据寄存器(SCI Data Register ,SCDR ) SCDR为SCI系统最常用的寄存器,它的地址是:$0018。写入时,为要发送的8位数据,记为:T7~T0;读出时,为接收的8位数据,记为:R7~R0。不受复位影响。

  18. 7.4 串行口初始化与收发编程的基本方法 (1)SCI初始化 对SCI进行初始化,最少由以下三步构成: 第一步:定义波特率。 LDA #%00000010 STA SCBR ;总线频率fBUS=2.4576MHz,定义波特率Bt=9600 第二步:写控制字到SCI控制寄存器1(SCC1)。 LDA #%01000000 STA SCC1 ;设置允许SCI,正常码输出、8位数据、无校验 第三步:写控制字到SCI控制寄存器2(SCC2)。 LDA #%00001100 STA SCC2 ;设置允许发送、允许接收,查询方式收发

  19. (2)发送一个数据与接收一个数据 发送数据是通过判断状态寄存器SCS1的第7位(SCTE)进行的,而接收数据是通过判断状态寄存器SCS1的第5位(SCRF)进行的。不论是发送还是接收,均使用SCI数据寄存器SCDR。发送时,将要发送的数据送入SCDR即可,接收时,从SCDR中取出的即是收到的数据。 ;串行发送A中的数 BRCLR 7,SCS1,* ;SCS1.7=0? 为0则等待 STA SCDR ;SCS1.7=1,可以发送数据 ;查询方式接收一个串行数据,接收的数据放入寄存器A中 BRCLR 5,SCS1,* ;SCS1.5=0? 为0则等待 LDA SCDR ;SCS1.5=1,可以取出数据 返回

  20. 7.5 串行通信通用函数与测试实例 7.5.1 串行通信子程序 串行通信头文件 SCI.h 串行通信驱动文件 SCI.c

  21. 串行通信头文件 SCI.h //[SCI.h]串行通信头文件-------------------------- #include "GP32C.h" //GP32 MCU映像寄存器名定义 #include "Type.h" //类型别名定义 #define ReSendStatusR SCS1 //SCI状态寄存器 #define ReTestBit 5 //接收缓冲区满标志位 #define SendTestBit 7 //发送缓冲区空标志位 #define ReSendDataR SCDR //数据寄存器 //串行通信函数声明 void SCIinit(void); //串行口初始化 void SCIsend1(INT8U o); //发送1字节 void SCIsendN(INT8U n, INT8U ch[]); //发送n字节 INT8U SCIre1(INT8U *p); //接收1字节 INT8U SCIreN(INT8U n, INT8U ch[]); //接收n字节 _____________________________________________

  22. 串行通信驱动文件 SCI.c 串行通信驱动文件包括SCI初始化、接收1字节、发送1字节、接收n字节和发送n字节函数。读者可以直接使用这些函数进行MCU的串行通信编程。 //[SCI.c]串行通信----------------------------------------------------------* //本文件包含: * // (1)SCIinit: 串行口初始化 * // (2)SCIsend1:串行发送1个字节 * // (3)SCIsendN:串行发送n字节 * // (4)SCIre1: 串行接收1字节 * // (5)SCIreN: 串行接收n字节 * //硬件连接: * // MCU的串口与PC方的串口相连 * //-------------------------------------------------------------------------*

  23. //头文件 #include "SCI.h" //SCIinit:串行口初始化----------------------------------------* //功能:对串行口进行初始化,默认为允许SCI,正常码输出,8位数 * 据,无校验, * //允许发送器,允许接收器.查询方式收发,波特率为9600(设fBUS * = 2.4576MHz) * //参数:无 * //返回:无 * //说明:该函数与具体的芯片型号(MC68HC908GP32)有关 * //------------------------------------------------------------* void SCIinit(void) { //1.总线频率fBUS = 2.4576MHz,定义波特率Bt = 9600 SCBR = 0b00000010; //2.设置允许SCI,正常码输出,8位数据,无校验 SCC1 = 0b01000000; //3.设置允许发送,允许接收,查询方式收发 SCC2 = 0b00001100; }

  24. //SCIsend1:串行发送1个字节-----------------------------*//SCIsend1:串行发送1个字节-----------------------------* //功能:串行发送1个字节 * //参数:要发送的数据 * //返回:无 * //-----------------------------------------------------* void SCIsend1(INT8U o) { //判断ReStatusR的第SendTestBit位是否为1,是1可以发送 while (1) if ((ReSendStatusR & (1<<SendTestBit)) != 0) { ReSendDataR = o; break; } }

  25. //SCIsendN:串行发送N个字节-----------------------------------*//SCIsendN:串行发送N个字节-----------------------------------* //功能:发送数组中的N个字节数据 * //参数:待发送数据的字节数及存放这些数据的数组首地址 * //返回:无 * //内部调用函数:SCIsend1 * //-----------------------------------------------------------* void SCIsendN(INT8U n, INT8U ch[]) { int i; for(i=0; i<n; i++) SCIsend1(ch[i]); }

  26. //SCIre1:串行收一个字节数据------------------------------------------------*//SCIre1:串行收一个字节数据------------------------------------------------* //功能:从串行口接收1个字节的数据 * //参数:标志指针p * //返回:接收到的数据(若接收失败,返回0xff) * //说明:参数*p带回接收标志.*p = 0,收到数据;*p = 1,未收到数据 * //-------------------------------------------------------------------------* INT8U SCIre1(INT8U *p) { INT16U k; INT8U i; //ReStatusR第ReTestBit位为1表示可接收数据

  27. for(k=0; k < 0xfbbb; k++) if ((ReSendStatusR & (1<<ReTestBit)) != 0) { i = ReSendDataR; *p = 0x00; break; } //接受失败 if (k >= 0xfbbb) { i = 0xff; *p = 0x01; } return i; }

  28. //SCIreN:HC08串行接收N个字节-----------------------------------------*//SCIreN:HC08串行接收N个字节-----------------------------------------* //功能:接收N个字节数据,并存放在ch数组中 * //参数:待接收的数据字节数及其存放的数组首地址 * //返回:接收标志 = 0 收到数据, = 1 未收到数据 * //内部调用函数:SCIre1 * //-------------------------------------------------------------------* INT8U SCIreN(INT8U n, INT8U ch[]) { int m; INT8U fp;

  29. m = 0; while (m < n) { ch[m] = SCIre1(&fp); if (fp == 1) { return 1; } m++; } return 0; }

  30. 7.5.2查询方式工程文件 (1)查询方式工程(08C)文件列表 (2)查询方式08C语言主程序 (3)中断方式MCU方主程序

  31. 7.5.3 中断方式工程文件 • 中断方式08C工程文件列表 • 中断方式08C语言主程序main.c • 串行中断子函数声明EnDisInt.h • 串行中断处理函数 • 串行中断方式矢量表文件 返回

  32. 表7-5 中断方式08C测试工程文件 工程文件名 SCI_INT.prj 所在路径 MC08Ex2007\GP32\GP32C\C03_串行通信中断方式 文件类型 文件名 功能简述 讲解章节 头文件 GP32C.h 芯片头文件 [08C工程文件组织]5.3 Includes.h 总头文件 [08C工程文件组织]5.3 EnDisInt.h 开放或禁止MCU模块中断 [08C工程文件组织]5.3 SCI.h 串行通信头文件 [本章] Type.h 数据类型头文件 [08C工程文件组织]5.3 C语言 子函数文件 MCUinit.c 芯片系统初始化函数定义 [初始化及PLL编程实例]14.2.5 SCI.c CI收发子函数定义 [本章] Vectors.c 中断处理及中断向量表 [08C工程文件组织]5.3 C语言主函数 Main.c 主函数 [本章] 中断方式08C工程文件列表

  33. //-----------------------------------------------------------*//-----------------------------------------------------------* //工 程 名:SCI_Int.prj * //硬件连接: * // (1)MCU的串口与PC方的串口相连 * //程序描述:利用中断方式把收到的数据发送回去 * //目 的:初步掌握利用中断方式进行串行通信的基本知识 * //------------------清华2007版《嵌入式技术基础与实践》实例---* //总头文件 #include "Includes.h" //主函数 void main() { DisableMCUint(); //禁止总中断 //1. 芯片初始化 MCUinit(); //2. 模块初始化 SCIinit(); //(1) 串口初始化 //3. 开放各模块中断 EnableSCIreInt(); //(1)开放SCI接收中断 //4. 开放总中断 EnableMCUint(); //主循环 while (1) { } } 中断方式08C语言主程序main.c

  34. //[EnDisInt.h]开放或禁止MCU各模块中断头文件---------------------------------//[EnDisInt.h]开放或禁止MCU各模块中断头文件--------------------------------- #include "GP32C.h" //GP32 MCU映像寄存器名定义 //开放或禁止中断宏定义 #define EnableMCUint() asm("CLI") //开放总中断 #define DisableMCUint() asm("SEI") //禁止总中断 #define EnableSCIreInt() SCC2 |= (1 << 5) //令SCC2.5=1,开放SCI接收中断 #define DisableSCIreInt() SCC2 &= ~(1 << 5) //令SCC2.5=0,禁止SCI接收中断 串行中断子函数声明EnDisInt.h • 在该头文件中对开关总中断进行了宏定义,并且其他各个模块的中断设置函数在此进行声明。

  35. //[Vectors08.c]中断处理函数与中断向量表-----------------*//[Vectors08.c]中断处理函数与中断向量表-----------------* //功能: * // (1)定义中断处理子程序 * // (2)放置中断向量表 * //本文件包含: // (1)SCI接收中断处理函数 * // (2)未定义的中断处理函数 * //说明:该文件与芯片具体型号有关 * // (1)芯片型号MC68HC908GP32 * //----------------------------------------------------- * #include "Type.h" //类型别名定义 #include "EnDisInt.h" //开放或禁止MCU各模块中断的宏定义 #include "SCI.h" //该头文件包含串行通信函数声明 //isrSCIre:接收中断处理函数--------------------------- -* //功能:接收1个字节数据, 发送接到的数据 * //参数:无 * //返回:无 * //内部调用函数:SCIreN, SCIsendN * //------------------------------------------------------* 串行中断处理函数

  36. #pragma interrupt_handler isrSCIre void isrSCIre(void) { INT8U f; //标志是否接受到数据 INT8U SerialBuff[1]; //存放接收数据的数组 DisableMCUint(); //禁止总中断 //接收1个字节的数据 f = SCIreN(1, SerialBuff); //若收到数据,则发送接到的数据 if (f == 0) SCIsendN(1, SerialBuff); EnableMCUint(); //开放总中断 } //此处为用户中断处理函数的存放处

  37. //未定义的中断处理函数,本函数不能删除 #pragma interrupt_handler isrDummy void isrDummy(void) { } //中断矢量表,需定义中断函数,可修改下表中的相应项目 //(interrupt service routine,isr 中断处理程序) #pragma abs_address:0xffdc //中断向量表起始地址 void (* const _vectab[])(void) = { //…………省略其他未使用的中断向量定义 isrSCIre, //SCI接收中断 //…………省略其他未使用的中断向量定义 }; #pragma end_abs_address

  38. 串行中断方式矢量表文件 • HC08的中断向量表的详细说明在前面章节已经介绍。在使用中断方式时,只要将中断向量表中串行接收中断项的isrDummy该为中断处理函数的函数名isrSCIRe即可,函数内容如上面所描述的。 • 本节仅讲述了串行通信的08C编程实例,用汇编编程的思想与之基本类似,读者可以参见教学资料的“MC08Ex2007\GP32\GP32S\C02_串行通信查询方式”和“MC08Ex2007\GP32\GP32S\C03_串行通信中断方式”下的汇编工程文件。

  39. 7.5.4 串口调试器(SSCOM V3.2) 串口调试工具比较多,SSCOM是其中比较出色的一款软件 。下图是该软件的一个界面。 读者可以从网址 http://www.mcu51.com/ download/sscom.rar 中下载 。

  40. 7.6 串行通信进一步讨论 7.6.1 唤醒功能 • 唤醒:一旦接收器进入睡眠,要响应对它寻址的信息需要一个过程。 • 空闲线唤醒:SCI系统使用空闲线唤醒,就需要建立一个协议。 • 地址标志唤醒:最高位(MSB)为1的一个字符会唤醒所有使能地址标志唤醒的接收器。

  41. 7.6.2 协议和控制流问题 • 从本质上来说,协议是建立连接和传输信息的一套规范。流控制指的是停止数据传输和重新开始数据传输的方法。 • 应答/不应答(Acknowlege/Not Acknowlege,ACK/NAK)流控制 某些协议(如Kermit和Bisynch)使用一个发送者,后者在发送下一组数据前,需要等待接收者对前一组数据的应答。在一组数据发送后,接收者需要检测数据的有效性。 • XON/XOFF协议。

  42. 7.6.3 用普通I/O口模拟SCI接收数据 在实际应用场合中,可能需要多个串行数据通信方式,通常MCU中只有1~2个SCI模块,通过专用芯片扩展可以实现多串口的通讯,但这样会使系统复杂,降低可靠性。此时可以用普通I/O口模拟实现SCI功能。 • 硬件条件 • 算法描述 • 发送一字节子程序 • 接收一字节子程序

More Related