51单片机与PC串口通讯_第1页
51单片机与PC串口通讯_第2页
51单片机与PC串口通讯_第3页
51单片机与PC串口通讯_第4页
51单片机与PC串口通讯_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

I 目录 第第 1 章章需求分析需求分析.- 1 - 1.1课题名称 .- 1 - 1.2任务 .- 1 - 1.3要求 .- 1 - 1.4设计思想 .- 1 - 1.5课程设计环境 .- 1 - 1.6设备运行环境 .- 2 - 1.7我在本实验中完成的任务 .- 2 - 第第 2 章章概要设计概要设计.- 2 - 2.1程序流程图 .- 2 - 2.2设计方法及原理 .- 3 - 第第 3 章章详细设计详细设计.- 3 - 3.1电路原理 .- 3 - 3.1.1STC89C52 芯片.- 3 - 3.2串口通信协议 .- 4 - 3.3程序设计 .- 5 - 3.3.1主程序模块.- 5 - 3.3.2串口通讯模块.- 6 - 3.3.3控制部分文件.- 8 - 3.3.4公共部分模块.- 11 - 3.4电路搭建 .- 12 - 3.4.1电路原理图.- 12 - 第第 4 章章上位机关键代码分析上位机关键代码分析.- 12 - 4.1打开串口操作 .- 12 - 4.2后台线程处理串口程序 .- 15 - 4.3 程序运行界面.- 18 - 第第 5 章章课程设计总结与体会课程设计总结与体会.- 19 - 第第 6 章章致谢致谢.- 19 - 参考文献参考文献.- 19 - - 1 - 第第 1 章章 需求分析需求分析 1.1 课题名称课题名称 故障诊断数据采集通信系统设计与制作。 1.2 任务任务 1、进行协议分析,完成单片机硬件电路原理图设计,在面包板上搭建电路。 2、测试上位机与单片机的通讯状态,实现实验要求部分的功能。 1.3 要求要求 1、单片机能接收并识别上位机的查询请求。 2、单片机能够查询对应接口的状态,并返回接口状态给上位机。 3、能够通过按钮来控制单片机相应接口的状态,相应接口的状态通过 LED 灯的亮灭 状态来表示。 1.4 设计思想设计思想 根据实验要求,设计数据采集电路,选择合适的元器件,按照原理图,并根据各个元器件的 特性以及接口电路结构形式,在面包板上搭接实际电路,搭接完毕之后对电路做优化设计,使 电路尽量简洁。 通过与上位机的连接测试,来优化单片机程序的代码,使上位机和下位机能够很协调 的工作。 软件编程:使用 C 语言实现下位机的程序设计。 1.5 课程设计环境课程设计环境 1. Windows XP 的 PC 机。 2. Keil uVision3 集成开发环境。 3. 串口调试助手 3. 单片机最小系统开发板。 4. 面包板和外围器件 5. 万用表等辅助工具 1.6 设备运行环境设备运行环境 由 STC89C52 单片机和面包板搭建的电路板。 1.7 我在本实验中完成的任务我在本实验中完成的任务 在和小组成员讨论之后,我们小组成员分工合作,我完成的工作是单片机串口的设置 及接收上位机的串口数据,并对流数据进行分析。 第第 2 章章 概要设计概要设计 2.1 程序流程图程序流程图 发送接口状态给上位 机 开始 初始化串口设置 初始化控制口 串口数据分析 查询接口状态 是否有控制 按键按下 检查串口中 是否有数据 返回查询要求 确定按下的按钮 改变按钮对应接口状态 Y N N Y 2.2 设计方法及原理设计方法及原理 1、USB 转串口模块将 USB 接口转化为串口后与单片机相连,用来实现单片机与 PC 机通过串口通讯。 2、初始化单片机串口的设置,使之与上位机的设置相符,具体为通信速率 9600B/S, 停止位 1 位,数据位 8 位。 3、本系统串口数据接收是采用的查询方式,单片机每次循环查询串口是否收到了数据。 4、上位机若连续查询接口状态 2 次都收不到回复,上位机可以判断与从机失去联系,所 有接口状态都置为不正常状态 第第 3 章章 详细设计详细设计 3.1 电路原理电路原理 3.1.1 STC89C52 芯片芯片 1、芯片引脚 51 系列的 DIP 封装的单片机共有 40 个外部引脚,其中有 P0,P1,P2,P3 四 组 IO 口,详细如右图。 2、芯片串口工作原理 1、波特率选择 波特率(Boud Rate)就是在串口通 信中每秒能够发送的位数(bits/second) 。 MSC-51 串行端口在四种工作模式下有 不同的波特率计算方法。下面以工作模 式 1 为来说明串口通信波特率的选择。 在串行端口工作于模式 1,其波特 率将由计时/计数器 1 来产生,通常设置 定时器工作于模式 2(自动再加模式) 。 在此模式下波特率计算公式为: 波特率=(1+SMOD)*晶振频率/(384*(256-TH1) ) 其中,SMOD寄存器 PCON 的第 7 位,称为波特率倍增位; TH1定时器的重载值。 2、SBUF 数据缓冲寄存器 这是一个可以直接寻址的串行口专用寄存器。SBUF 包含了两个独立的寄存器,一个 是发送寄存,另一个是接收寄存器,但它们都共同使用同一个寻址地址99H。CPU 在读 SBUF 时会指到接收寄存器,在写时会指到发送寄存器。 3、SCON 串行口控制寄存器 通常在芯片或设备中为了监视或控制接口状态,都会引用到接口控制寄存器。SCON 就是 51 芯片的串行口控制寄存器。它的寻址地址是 98H,是一个可以位寻址的寄存器,作 用就是监视和控制 51 芯片串行口的工作状态。51 芯片的串口可以工作在几个不同的工作 模式下,其工作模式的设置就是使用 SCON 寄存器。它的各个位的具体定义如下: (MSB)(LSB) SM0SM1SM2RENTB8RB8TIRI 串行口控制寄存器 SCON SM0、SM1 为串行口工作模式设置位,这样两位可以对应进行四种模式的设置。 看表串行口工作模式设置。 SM0SM1模 式功 能波特率 000同步移位寄存器fosc/12 0118 位 UART可变 1029 位 UARTfosc/32 或 fosc/64 1139 位 UART可变 3.2 串口通信协议串口通信协议 通信协议是通信设备在通信前的约定。单片机、计算机有了协议这种约定,通信双方 才能明白对方的意图,以进行下一步动作。 主机通过轮询方式访问从机,通过发送从机地址呼叫从机,地址相符合的从机把数据 发送给主机 通信格式: 主机发送数据格式: 起始字节地址字节结束字节 $从机地址# 1 个1 个1 个 主机每隔 5 秒钟查询一遍 从机发送数据格式:校验为和校验 地址字节数据字节校验字节 1 个1 个1 个 备注: 1、上述字节都表示只占一个字节空间,每次发送 3 个字节 从机地址分配:号:0X01; 号:0X02; 号:0 x03; 号: 0X04; 号:0X05 ; 号:0X06; 号:0X07; 号: 0X08: 号:0X09 3、数据字节 表示检测到故障;01 55 56 表示没有检测到故障 3.3 程序设计程序设计 3.3.1 主程序模块主程序模块 1、main.c #include #include #include uart.h #include common.h #include control.h UCHAR rstrTX_PAYLOAD_WIDTH=0; void main() /接收 uchar t; bool sta; uchar key; InitUart();/串口初始化 InitControl();/控制端口初始化 while(1) /主程序不断的对接收到的数据进行分析 if(RI=1)/检查一下串口中有没有数据(每次一个字节) AppendByte(SBUF);/向协议窗口中增加一个数据 RI=0;/清除串口中断 t=ProtocolAnalysis();/进行协议分析 if(t!=0) sta=GetSta(t);/查询接口状态 SendSta(t,sta);/发送接口状态 UartSend(ENA,3); /对按钮状态进行查询, 如果有按钮被按下,将对应接口状态改变,然后将对应 接口状态发给上位机 key=GetKey(); if(key!=0) /有键盘按下 ChangeSta(key); / 使用下面两句话接口状态改变之后会立刻通知上位机, 现在上位机采用查 询方式来了解接口的状态,故不需要这两句话 if(key=3) sta=GetSta(key);/查询接口状态 SendSta(key,sta);/发送接口状态 3.3.2 串口通讯模块串口通讯模块 1、Uart.c #include #include #include uart.h uint m_nEndIndex; /下一个将要插入数据的下标 uchar m_wsBlockWINDOW_SIZE;/定义接收缓存区的大小 uchar m_wsTempWINDOW_SIZE;/这是一个供数据交换的缓存区 void InitUart() /初始化串口工作模式,在使用串口之前必须被调用一次 TMOD = 0 x20; / 定时器 1 工作于 8 位自动重载模式, 用于产生波特率 TH1=(unsigned char)(256 - (XTAL / (32L * 12L * Baudrate); TL1=(unsigned char)(256 - (XTAL / (32L * 12L * Baudrate); / 定时器 1 赋初值 SCON = 0 x50; /mode1 方式,启用接收 PCON = 0 x00; TR1 = 1; /启用定时器 1 IE=0 x00; /接收数据缓存区初始化部分 memset(m_wsBlock,0,WINDOW_SIZE);/将窗口清零 m_nEndIndex=0; /串口接收处理,采用的是中断处理方式,对于发送中断该函数不处理 /串口发送函数 void UartSend(UCHAR *Data, int Len) /Data 为数据指针,len 为要发送的数据长度 UCHAR c; int i; for(i=0;iLen;i+) c=Datai; SBUF = c; / 要发送的字符放入缓冲区 while(TI = 0); TI = 0; /第一个参数为接口编号,第二个参数为接口状态,为真接口状态为 1,为假接口状态为 0 void SendSta(uchar num,bool sta) uchar bufPROT_LEN=0; buf0=num; if(sta) buf1=0 xAA;/没有故障 else buf1=0 x55;/有故障 buf2=buf0buf1;/按位异或 UartSend(buf,3); / 用于向窗口中插入一个字符,只有这一个函数会修改窗口中的数据 void AppendByte(uchar ch) if (WINDOW_SIZE=WINDOW_SIZE) /说明窗口已近满了,需要将顶位最前面的字符溢出,后面的所有字符向前移动一位 memcpy(m_wsTemp,m_wsBlock+1,WINDOW_SIZE-1); memcpy(m_wsBlock,m_wsTemp,WINDOW_SIZE-1); m_nEndIndex=WINDOW_SIZE-1; m_wsBlockm_nEndIndex=ch; m_nEndIndex+; / 用于协议分析, / 返回值为 0 说明协议分析没有分析到有效请求,不需要状态监测 / 为 1 说明要对端口 1 监测 / 为 2 说明要对端口 1 监测 / 为 3 说明要对端口 1 监测 int ProtocolAnalysis() uchar t; if (m_nEndIndex0 x00) return 0; 2.Uart.h #ifndef_UART_H #define _UART_H #include common.h #define XTAL / CUP 晶振频率#define baudrate 9600 #define Baudrate9600L #define WINDOW_SIZE 3/定义窗口数据缓存区大小 #define TX_PAYLOAD_WIDTH 3/定义接受数据缓存区的长度 #define PROT_LEN3/协议长度 void InitUart(); /初始化串口工作模式,在使用串口之前必须被调用一次 void UartSend(char *Data, int Len);/串口发送.Data 为数据指针,len 为要发送的数据长度 void SendSta(uchar num,bool sta); /第一个参数为接口编号,第二个参数为接口状态,为真接口状态为 1,为假接口状态为 0 void AppendByte(uchar ch); / 用于向窗口中插入一个字符,只有这一个函数会修改窗口中的数据 int ProtocolAnalysis();/ 用于协议分析, #endif 3.3.3 控制部分文件控制部分文件 1、Control.c #include #include control.h sbit key1=P20;/按钮状态没有按下时为 1 sbit key2=P21; sbit key3=P22; sbit sta1=P23; /!sta0为 1 表示正常状态,为 0 表示异常状态 sbit sta2=P24; sbit sta3=P25; void InitControl() /初始化控制 key1=1; key2=1; key3=1; /开启三盏灯 sta1=0; sta2=0; sta3=0; int GetSta(int t)/得到 sta 状态 switch (t) case 0 x01: return !sta1; case 0 x02: return !sta2; case 0 x03: return !sta3; default: return -1; int GetKey()/得到按钮的状态 key1=1; if(key1=0) wait(1);/延时 10ms 消抖 if(key1=0)/说明确实被按下 while(key1=0);/等待知道按钮被按下 return 1; key2=1; if(key2=0) wait(1);/延时 10ms 消抖 if(key2=0)/说明确实被按下 while(key2=0);/等待知道按钮被按下 return 2; key3=1; if(key3=0) wait(1);/延时 10ms 消抖 if(key3=0)/说明确实被按下 while(key3=0);/等待知道按钮被按下 return 3; return 0; void ChangeSta(int t)/改变接口的状态 switch (t) case 0 x01: sta1=!sta1; break; case 0 x02: sta2=!sta2; break; case 0 x03: sta3=!sta3; break; default: break; 2.Control.h #ifndef _CONTROL_H #define _CONTROL_H #include common.h void InitControl();/初始化控制 int GetSta(int t);/得到 sta 状态 int GetKey();/得到按钮的状态 void ChangeSta(int t);/改变接口的状态 #endif 3.3.4 公共部分模块公共部分模块 1、Common.c #include #include #include common.h /用于存放一些公共的函数和宏定义 void wait(int n)/延时函数 n*10ms; int i,j; for(i=0;im_hComm)/ check if the port is opened /清空缓冲区 PurgeComm(port-m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT); for (;) bResult = WaitCommEvent(port-m_hComm, /使用 WaitCommEvent if (!bResult) switch (dwError = GetLastError() case ERROR_IO_PENDING: if(haveError)/说明可能会进入死循环 ResetEvent(port-m_hEventArray1); /手动将这个事件置为没有信号,防止死循环发生 TRACE(表示查询操作转到后台运行n); break; case 87: break; default: port-ProcessErrorMessage(WaitCommEvent(); break; else bResult = ClearCommError(port-m_hComm, if (comstat.cbInQue = 0)/确定串口中无数据,重新开始循环 continue; / end if bResult / 主监视函数,该函数将阻塞本线程直至等待的某一事件发生 TRACE(串口线程正在等待n); Event = WaitForMultipleObjects(3, port-m_hEventArray, FALSE, INFINITE);/ 使用这个函数监视 m_hWriteEvent,m_hShutdownEvent,m_ov.hEvent 这三个事件 TRACE(串口线程等待结束n); switch (Event) case 0:/关闭 port-m_bThreadAlive = FALSE; :PostMessage(port-m_pOwner-m_hWnd,WM_COMM_THREADEND,(WPARAM) 0,(LPARAM)port-m_n

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论