ImageVerifierCode 换一换
格式:DOCX , 页数:16 ,大小:514.21KB ,
资源ID:19411889      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/19411889.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(51单片机的串行通讯程序Word文件下载.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

51单片机的串行通讯程序Word文件下载.docx

1、第一, 初始化串口的波特率中颖 8051 中,波特率可以设置为系统时钟的分频或定时器的分频。设置注意事项及规则如下:A. 波特率不能等于系统时钟频率或定时器溢出率,只能为其分频值。B. 当为串口方式1 或3 时,波特率发生器通过T2CON 的TCLK 和RCLK 来选择。TCLK和RCLK 为1 时,选Timer2;TCLK 和RCLK 为0 时,选Timer1。C. 当使用EUART1 时,不能使用Timer1 产生波特率。不管TCLK 和RCLK 为1或 0,波特率发生器都为定时器 2。但是当TCLK 或RCLK 为1 时,波特率为TCLK 或RCLK为0 时的波特率的二分频。D. UAR

2、T 工作在不同的工作方式下,波特率发生器有所不同,具体内容如下:方式 0 时,波特率固定,波特率发生器为系统时钟的分频。当SM2=1时,波特率为系统时钟的4 分频;当SM2=0 时,波特率为系统时钟的12 分频。当使用32.768K 并PLL倍频后,系统时钟为8.192MHZ当为方式 1 时,波特率可变,通过设置TCLK 和RCLK 来选择Timer1 或Timer2作为波特率发生器。通过SMOD 位(二倍频控制位)来选择分频值。当SMOD=1 时,波特率为定时器1 或2 溢出率/ 32 的二倍频,即16 分频;当SMOD=0 时,波特率为定时器1 或2 溢出率的32 分频。当为方式 2 时,

3、波特率固定,波特率发生器为系统时钟的分频。通过SMOD 位(二倍频控制位)来选择分频值。当 SMOD=1 时, 波特率为系统时钟/ 64 的二倍频, 即 32 分频;当 SMOD=0时,波特率为系统时钟的64 分频。当为方式 3 时,波特率可变,通过设置TCLK 和RCLK 来选择Timer1 或Timer2作为波小结一下:1串口方式0 和方式2 为不可变波特率,方式1 和方式3 为可变波特率,可变值由T1 或T2 控制2中颖单片机只用一个串口0 时,可选T1 或T2 作为波特率发生器。3中颖单片机使用两个串口时,T1 为串口0 波特率发生器,T2 为串口1的波特率发生器。第二, 初始化串口的

4、控制器 SCON和其它部分(比如中断和波特率加倍位等)串口0 的控制寄存器为SCON,串口1 的控制寄存器为SCON1,其内容与51 的相同,但要注意中颖51 的串口为与其它功能复用,因而要将管脚配置好方向,输入引脚配置好上拉电阻,而输出引脚全部输出为高电平1,这样才能可靠的发送,发送完成后,状态符合串行通讯的要求。Demo 程序如下,采用定时器1作波特率发生器,也适用于普通51单片机使用。串口初始化示例程如下,以中颖 79F32平台验证,在8.192M系统时钟时,波特率为9600/*void InitSys(void)功能说明: 系统寄存器初始化其他说明: Bit7 Bit6 Bit5 Bi

5、t4 Bit3 Bit2 Bit1 Bit0IEN0 EA EADC ET2 ES0 ET1 EX1 ET0 EX0IEN1 EFCOF EI2C EPWM ESCM EHSEC ES1 EX2 ESPI输入: 无输出:*/P0SS = Bin(00000000); /P0 as ioP1SS = Bin(00000000); /P1 as ioP0CR = Bin(00000000);P0PCR = Bin(00000000);P0 = Bin(00000000);P1CR = Bin(00000000);P1PCR = Bin(00000000);P1 = Bin(00000000);P2

6、CR = Bin(00000000);P2PCR = Bin(00000000);P2 = Bin(00000000);/将P30,P31 初始化为串行通讯口P3CR = Bin(00000010);P3PCR = Bin(00000001);P3 = Bin(00000011);P4CR = Bin(00000000);P4PCR = Bin(00000000);P4 = Bin(00000000);/*-EUART初始化-*/TR0 = 0;TR1 = 0; /stop timer1TR2 = 0; /stop timer2/-TF0 = 0;TF1 = 0;/ TMOD = Bin(00

7、010001); /设置Timer1 为定时模式,工作方式一(16bit,用于)/定时器1 为8 位自装载,波特率发生器功能TMOD = Bin(00100001);TL0 = LOBYTE(CLOCK_1MS);TH0 = HIBYTE(CLOCK_1MS);/ TL1 = LOBYTE(CLOCK_1MS);/ TH1 = HIBYTE(CLOCK_1MS);TH1 = 0xe5;TL1 = 0xe5;TF2 = 0;/ T2MOD = Bin(00000000); /设置Timer2 用于产生波特率(baudrategenerator)/ T2CON = Bin(00110000);/设

8、置串口通讯方式为8位异步通讯,波特率可变。SCON = Bin(01010000);/ RCAP2L = LOBYTE(UART_BAUDRATE);/ TL2 = LOBYTE(UART_BAUDRATE);/ RCAP2H= HIBYTE(UART_BAUDRATE);/ TH2 = HIBYTE(UART_BAUDRATE);TR0 = 1;TR1 = 1; /start timer1/ TR2 = 1; /start timer2/开启EUART和Timer0中断IEN0 = Bin(00010010);/ IEN0 = Bin(00000010); /禁止串行中断IEN1 = Bin

9、(00000000);TI = 1;三、如何将程序中的变量内容输出到串行口在程序调试过程中,出现了问题,用仿真器跟踪当然是最直接和高效的方法,但如果没有仿真器,较好的方法是将相关的变量全部输出到串口,然后通过PC 机上的串口调试助手软件来查看相关内容。通过对关键变量的查看结合源程序分析,很快能找到BUG所在。软件中的变量常用的有好几种类型。那是否有通用的函数能完成将此变量的信息通过串口送PC 来监视呢?C-51 有这样的现成函供供您调用。它就是我要隆重向您推荐的printf()库函数,学过PC 机上的C 语言的同学对此应该比较熟悉。使用printf前要做以下几个工作1. 初始化串口波特率和模式

10、,并置TI 为1;2. 在源程序中包含头文件。3. 如果是定时器1 作为波特率发生器,还可通过Keil-C51 软件仿真先在IDE 的虚拟设备串口上看看printf()的工作情况做好前面的工作后就可输出变量内容了。字符型变量的输出用如下语句printf(“字符变量X 的值为:%dn”,(unsigned int )ucTemp);其中ucTemp 为一个字节型的变量整型变量的输出用如下语句printf(“整形变量X 的值为:%dn”,uiTemp); 其中uiTemp 为一个整形变量长整型变量(4 字节)的输出用如下语句printf(“长整形变量X 的值为:%ldn”,ulTemp); 其中u

11、lTemp 为一个长整形变量串口输出程序中的变量的 Demo程序如下(在中颖79F32 评估板上测试通过)#define uchar unsigned char#define uint unsigned int#define ulong unsigned longvoid main(void)uchar ucCount;uint uiCount;ulong ulCount;EA =0;RSTSTAT = 0x00; /feed watchdogInitSys();EA =1;ucCount =0;uiCount = 0;ulCount = 0;while(1)printf(HolleWorld

12、!n);ucCount Value is %dn,(uint)ucCount);uiCount Value is %dn,uiCount);ulCount Value is %ldnn,ulCount);ucCount Value is %02xnuiCount Value is %04XnulCount Value is %l08XnnucCount+;uiCount+;ulCount+;测试过程中的电脑屏幕截图如下:可在中颖79F32评估版上直接调试和验证的完整工程项目详见压缩包。四、如何编程实现串口数据包的接收与发送l 串口数据通讯,比较实用的模式有两种4 1 发送和接收都采用中断模式发

13、送和接收操作都要设数据缓冲区,占用内存较大,但CPU 的利用效率最高,无空耗情况发生。42 发送采用查询,接收采用中断当设备要向外发送数据时,由于发送的数据的数量是已知的,因而在特定的波特率下,完成发送操作的时间也是可以预测的。因而采用查询操作发送可简化发送数据过程,减小内存的占用。数据接收只有采用中断方式才能高效可靠,应用中CPU 通常要完成基本功能的运转,只有在收到串口命令时才临时解析命令,完成相应的功能,完成后还有基本功能要做。l 串口数据通讯时常采用的封包技术串口通讯时,通常将数据内容组织成一个数据包,才能完成应用层相关协议的功能。通常的包包括“包头+数据内容+校验内容+包尾”构成。例

14、如,我们在产品中常用的联机命令如下1B 10 00 01 88 /其中1B 10为包头,00 为约定的命令号01 为后续数据的长度,88 为包尾字符。l 接收和解析数据包采用状态机较易实现针对以上介绍的数据包,我们可以定义以下几种状态#define c_UART_RCV_Status_Idle 0 /空闲态#define c_UART_RCV_Status_Head0 1 /接收到包头字符0 后进入的状态#define c_UART_RCV_Status_Head1 2 /接收到包头字符1 后进入的状态#define c_UART_RCV_Status_CMD 3 /接收到命令字符后进入的状态

15、#define c_UART_RCV_Status_DataLength 4 /接收到数据长度后进入的状态#define c_UART_RCV_Status_DataContent 5 /接收指定长度的数据内容的状态/#define c_UART_RCV_Status_PackageTail 6 /接收包尾数据#define c_UART_RCV_Status_ReceiveEnd 7 /数据接收完成的状态为了保存接收到的数据和控制状态机的切换,还要定义如下几个数据结构变量uchar ucRCV_StatusMachineValue; /定义串口接收状态机的当前状态值uchar ucRCV_C

16、ommandValue; /定义无符号字符型的串口数据命令字uchar ucRCV_DataLength; /定义附加数据体的长度。#define c_MaxDataLength 16 /定义串口数据的最大长度uchar ucRCV_DataBuffc_MaxDataLength; /定义用于保存串口接收数据的缓冲区uchar *pucDataBuff; /定义用于操纵串口缓冲区的指针bool bCOM_ReceivePackageEndFlag; /串口接收数据完成时的标志位其它常量定义如下#define c_PackageHead0 0x1B#define c_PackageHead1 0

17、x10#define true 1#define false 0建立在上述数据结构上的功能实现/*void EUART0_ISP(void) interrupt 4 串口通讯中断响应程序 TI1-发送完一个字节RI1-接收完一个字节*/EA = 0;UartInterface();EA = 1;串口数据中断处理函数如下,实现状态的跳转与数据的保存void UartInterface(void) 串口通讯接收、发送处理程序uchar ucReceiveData; /临时存储串口接收到的数据内容/*-数据发送-*/if(TI) /发送完一个数据/是发送数据完成后的中断,不做处理,采用查询方式发送/

18、*-数据接收-*/if(RI) /接收完一个数据ucReceiveData = SBUF;RI = 0;switch(ucRCV_StatusMachineValue)case c_UART_RCV_Status_Idle:if(ucReceiveData = c_PackageHead0)ucRCV_StatusMachineValue = c_UART_RCV_Status_Head0;break;case c_UART_RCV_Status_Head0:if(ucReceiveData = c_PackageHead1)ucRCV_StatusMachineValue = c_UART_

19、RCV_Status_CMD;pucDataBuff = ucRCV_DataBuff;/将指针指向串口数据缓冲区的首端case c_UART_RCV_Status_CMD:/合法性检查及数据的保存操作ucRCV_CommandValue = ucReceiveData;*pucDataBuff+ = ucReceiveData;/跳转到下一状态ucRCV_StatusMachineValue = c_UART_RCV_Status_DataLength;case c_UART_RCV_Status_DataLength:ucRCV_DataLength = ucReceiveData;/避免

20、指针越界的冗余设计if(ucRCV_DataLength c_MaxDataLength-2)ucRCV_DataLength = c_MaxDataLength-2;ucRCV_StatusMachineValue = c_UART_RCV_Status_DataContent;case c_UART_RCV_Status_DataContent:/数据包中的附加变长数据体内容存入缓冲区 0)ucRCV_DataLength-;if(ucRCV_DataLength = 0)/串口接收数据包完成的标芯位置位/通知主进程进行串口数据包的处理bCOM_ReceivePackageEndFlag

21、= true;/接收完最后一个字符.ucRCV_StatusMachineValue =c_UART_RCV_Status_ReceiveEnd;case c_UART_RCV_Status_ReceiveEnd:/接收数据溢出时的处理,可报警或点灯default:/默认的处理,防错ucRCV_StatusMachineValue = c_UART_RCV_Status_Idle;/主进程循环监测数据包接收是否完成,并执行喂狗操作。void UARTProcess(void) 数据接收完成处理 当数据接收完成,进行接收完成处理/process of uartbCOM_ReceivePackageEndFlag = false;if(_testbit_(bCOM_ReceivePackageEndFlag) ) /是否接收完一个数据包UartDecode();下面再讲一下查询方式发送数据到串口的相关代码/通过串口发送一字

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1