串口通信的计算器_第1页
串口通信的计算器_第2页
串口通信的计算器_第3页
串口通信的计算器_第4页
串口通信的计算器_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

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

文档简介

1、信息工程课程设计报告书课 程 名 称 单片微机原理与接口技术 课 程 设 计 题目 串口通信的计算器 学生姓名、学 号 学 生 专 业 班级 指 导 教 师 姓名 课程设计起止日期 2017年6月19日-6月30日 一、课程设计项目名称串口通信的计算器二、项目设计目的及技术要求2.1 项目设计目的通过单片微型计算机与接口技术课程设计,使学生能够掌握单片机的开发过程、设计方法和单片机应用电路的特点,使学生能够综合应用单片机原理及应用、模拟电子技术基础、数字电子技术基础等课程的知识。要求学生经过课程设计的教学环节进一步理解智能电子系统的结构和组成原理,掌握智能电子系统的基本设计方法,完成系统电路和

2、应用程序的实践,从而使学生的电子线路设计能力、单片机机应用能力有较大提高。1)学会单片机的应用方法,开发环境;2)结合任务要求,完成系统设计和调试,功能扩展和创新;3)熟悉汇编或C51语言,用C51完成系统的软件编程;2.2 项目的主要任务1)上位机串口助手发送字符串,单片机接受到后,进行字符的分解,计算出结果,显示在数码管上,并将结果发送到串口助手上显示。2)计算的+,-,X,/都可以。在除法运算中,如果除数为0,则在数码管显示0H,表示不能运算。计算出来的结果不能超过999超过,则在数码管上显示0H。3)矩阵按键的0-4四个按键分别代表+,-,X,/运算。按下按键编号为运算的键,则表示确定

3、开始计算结果,并把结果显示在数码管上面,通过串口发送到上位机显示。同样的在第2步的要求也能实现。三、项目设计方案论证3.1实现串口通信的计算器的整体方案PC可通过串口助手软件将数据发送至单片机,单片机接收数据,通过按键立进行相应的运算,将计算结果在数码管上显示,并且将计算结果发送回PC。单片机STC89C52上位机串口助手按键运算串口助手数码管显示结果图3-1串口通信的计算器的整体思路3.2硬件原理图串口通信计算器主要涉及到按键、数码管、单片机的电路图。 3.3程序设计思路主函数,串口函数、拆分函数、按键函数、计算函数、数码管函数等五部分组成。下面就是对具体函数思路的解析:串口助手字符串的输入

4、字符串的读取输出结果字符串拆分成num1、num2数码管显示按键扫描按键驱动操作计算结果串口助手显示图3-3程序中函数的思路图(1)串口函数:PC通过串口向单片机发送的算式是以字符串的形式发送的,故单片机程序可使用数组存放接收到的字符串。由于每次发送的算式均以“#”结尾,所以在程序中可对每次接收到的字符进行检测,若检测到“#”则接收结束,程序开始执行下一步操作。/* 串口数据写入,即串口发送函数,buf-待发送数据的指针,len-指定的发送长度 */void UartWrite(unsigned char *buf, unsigned char len) while (len-) /循环发送所

5、有字节 flagTxd = 0; /清零发送标志 SBUF = *buf+; /发送一个字节数据 while (!flagTxd); /等待该字节发送完成 /* 串口中断服务函数 */void InterruptUART() interrupt 4 if (RI) /接收到新字节 RI = 0; /清零接收中断标志位 if(SBUF!='#') if (cntRxd < sizeof(bufRxd) /接收缓冲区尚未用完时, /保存接收字节,并递增计数器 bufRxdcntRxd+ = SBUF;/if(bufRxd0='1')LED1=0;/if(buf

6、Rxd2='2')LED2=0; else cntRxd =0;restopflag=1; if (TI) /字节发送完毕 TI = 0; /清零发送中断标志位 flagTxd = 1; /设置字节发送完成标志 2.拆分函数:单片机将接收到的bufRxd数组用strtok()函数拆分成两个字符串,再通过atoi()函数将字符串转化为整型赋值给num1、num2。/分离所接收到字符串,赋值给num1、num2 void ApartUart(char*strin,int*num1,int*num2) char *ps3; char *t=NULL; int i=0; t=strto

7、k(strin,""); while(t!=NULL) psi+=t; t=strtok(NULL,""); *num1=atoi(ps0); *num2=atoi(ps1);3.按键函数:矩阵按键的驱动、1ms扫描一次矩阵按键。循环检测按键的动作。 for (i=0; i<4; i+) /循环检测4*4的矩阵按键 for (j=0; j<4; j+) if (backupij != KeyStaij) /检测按键动作 if (backupij != 0) /按键按下时执行动作 / KeyAction(KeyCodeMapij); /调用按键

8、动作函数 GetResult(); backupij = KeyStaij; /刷新前一次的备份值 4.计算函数:按下按键编号为运算的键,计算的+,-,X,/都可以。在除法运算中,如果除数为0;在减法运算中,num1<num2 等情况无法显示计算结果。将计算结果在数码管上显示,无法显示计算的显示“0H”;并将计算结果发送发到串口助手上显示。void GetResult() if(KeySta00=0)result = num1 + num2;SBUF=result; else if(KeySta01=0) if(num1>num2)result = num1 - num2;SBUF

9、=result; elseLedBuff0 =0x76;LedBuff1 =0x3f;LedBuff2 =0x00; else if(KeySta02=0)result = num1 * num2;SBUF=result; else if(KeySta03=0) if( num2!=0)result = num1 / num2;SBUF=result; elseLedBuff0 =0x76;LedBuff1 =0x3f;LedBuff2 =0x00; else if(KeySta10=0)result = 0; else if(KeySta11=0)result = num1 * num1;

10、else if(KeySta12=0)result = num2 * num2;5.数码管函数:1ms中刷新一次数码管,将计算结果处理结果按十进制从高到低依次提取并转为数码管显示字符。当计算结果大于999时,无法显示计算结果,数码管显示“0H”。if(flag1s = 1) flag1s = 0;if(result<999) LedBuff0 = LedCharresult%10; LedBuff1 = LedCharresult/10%10; LedBuff2 = LedCharresult/100%10; elseLedBuff0 =0x76;LedBuff1 =0x3f;LedBu

11、ff2 =0x00;扩展应用: 增加清零,num1的平方运算、num2的平方运算的操作 else if(KeySta10=0)result = 0; else if(KeySta11=0)result = num1 * num1; else if(KeySta12=0)result = num2 * num2;3.4软件程序#include <reg52.h>#include<stdio.h>#include<string.h>#include<stdlib.h>bit flagTxd = 0; /单字节发送完成标志,用来替代TXD中断标志位un

12、signed char cntRxd = 0; /接收字节计数器unsigned char pdata bufRxd20; /接收字节缓冲区sbit KEY_IN_1 = P17;sbit KEY_IN_2 = P16;sbit KEY_IN_3 = P15;sbit KEY_IN_4 = P14;sbit KEY_OUT_1 = P13;sbit KEY_OUT_2 = P12;sbit KEY_OUT_3 = P11;sbit KEY_OUT_4 = P10;/sbit LED1=P20;/sbit LED2=P21;unsigned char pdata KeySta44 = /全部矩阵

13、按键的当前状态 1, 1, 1, 1,1, 1, 1, 1,1, 1, 1, 1,1, 1, 1, 1;signed int num1 = 0;signed int num2 = 0;signed int result = 0;sbit ADDR0=P22;sbit ADDR1=P23;sbit ADDR2=P24;unsigned char LedChar=0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f;unsigned char LedBuff=0x00, 0x00, 0x00, 0x00, 0x00, 0x00;uns

14、igned char flag1s = 0;unsigned long sec = 0;unsigned char restopflag = 0;void ConfigTimer0(); void ConfigUART(unsigned int baud);void UartWrite();void ApartUart(char*strin,int*num1,int*num2);void KeyDriver();void KeyScan();void GetResult();void main()TMOD = 0x01;TH0 = 0xFC;TL0 = 0x67;TR0 = 1;EA = 1;

15、ET0 = 1;ConfigUART(2400); while (1) if(restopflag=1) ApartUart(bufRxd,&num1,&num2);/*if(num1=1)&(num2=2) result=num1+num2; LED1=0; LED2=0; */KeyDriver(); /调用按键驱动 /*GetResult(); if(result>999)LcdShowStr(0,0,result); elseLcdShowStr(0,1,"0H")*/if(flag1s = 1) flag1s = 0;if(resul

16、t<999) LedBuff0 = LedCharresult%10; LedBuff1 = LedCharresult/10%10; LedBuff2 = LedCharresult/100%10; elseLedBuff0 =0x76;LedBuff1 =0x3f;LedBuff2 =0x00; /分离所接收到字符串,赋值给num1、num2 void ApartUart(char*strin,int*num1,int*num2) char *ps3; char *t=NULL; int i=0; t=strtok(strin,""); while(t!=NULL

17、) psi+=t; t=strtok(NULL,""); *num1=atoi(ps0); *num2=atoi(ps1);/* 串口配置函数,baud-通信波特率 */void ConfigUART(unsigned int baud) SCON = 0x50; /配置串口为模式1 TMOD &= 0x0F; /清零T1的控制位 TMOD |= 0x20; /配置T1为模式2 TH1 = 256 - (12000000/12/32)/baud; /计算T1重载值 TL1 = TH1; /初值等于重载值 ET1 = 0; /禁止T1中断 ES = 1; /使能串口中

18、断 TR1 = 1; /启动T1/* 串口数据写入,即串口发送函数,buf-待发送数据的指针,len-指定的发送长度 */void UartWrite(unsigned char *buf, unsigned char len) while (len-) /循环发送所有字节 flagTxd = 0; /清零发送标志 SBUF = *buf+; /发送一个字节数据 while (!flagTxd); /等待该字节发送完成 /* 串口中断服务函数 */void InterruptUART() interrupt 4 if (RI) /接收到新字节 RI = 0; /清零接收中断标志位 if(SBU

19、F!='#') if (cntRxd < sizeof(bufRxd) /接收缓冲区尚未用完时, /保存接收字节,并递增计数器 bufRxdcntRxd+ = SBUF;/if(bufRxd0='1')LED1=0;/if(bufRxd2='2')LED2=0; else cntRxd =0;restopflag=1; if (TI) /字节发送完毕 TI = 0; /清零发送中断标志位 flagTxd = 1; /设置字节发送完成标志 /* 按键驱动函数,检测按键动作,调度相应动作函数,需在主循环中调用 */void KeyDriver(

20、) unsigned char i, j; static unsigned char pdata backup44 = /按键值备份,保存前一次的值 1, 1, 1, 1, 1, 1, 1, 1,1, 1, 1, 1, 1, 1, 1, 1; for (i=0; i<4; i+) /循环检测4*4的矩阵按键 for (j=0; j<4; j+) if (backupij != KeyStaij) /检测按键动作 if (backupij != 0) /按键按下时执行动作 / KeyAction(KeyCodeMapij); /调用按键动作函数 GetResult(); backup

21、ij = KeyStaij; /刷新前一次的备份值 /* 按键扫描函数,需在定时中断中调用,推荐调用间隔1ms */void KeyScan() unsigned char i; static unsigned char keyout = 0; /矩阵按键扫描输出索引 static unsigned char keybuf44 = /矩阵按键扫描缓冲区 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF; /将一行的4个按键值移入缓冲区 keybufkeyo

22、ut0 = (keybufkeyout0 << 1) | KEY_IN_1; keybufkeyout1 = (keybufkeyout1 << 1) | KEY_IN_2; keybufkeyout2 = (keybufkeyout2 << 1) | KEY_IN_3; keybufkeyout3 = (keybufkeyout3 << 1) | KEY_IN_4; /消抖后更新按键状态 for (i=0; i<4; i+) /每行4个按键,所以循环4次 if (keybufkeyouti & 0x0F) = 0x00) /连续4

23、次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下 KeyStakeyouti = 0; else if (keybufkeyouti & 0x0F) = 0x0F) /连续4次扫描值为1,即4*4ms内都是弹起状态时,可认为按键已稳定的弹起 KeyStakeyouti = 1; /执行下一次的扫描输出 keyout+; /输出索引递增 keyout &= 0x03; /索引值加到4即归零 switch (keyout) /根据索引,释放当前输出引脚,拉低下次的输出引脚 case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break; c

24、ase 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break; case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break; case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break; default: break; void GetResult() if(KeySta00=0)result = num1 + num2;SBUF=result; else if(KeySta01=0) if(num1>num2)result = num1 - num2;SBUF=result; elseLedBuff0 =0

25、x76;LedBuff1 =0x3f;LedBuff2 =0x00; else if(KeySta02=0)result = num1 * num2;SBUF=result; else if(KeySta03=0) if( num2!=0)result = num1 / num2;SBUF=result; elseLedBuff0 =0x76;LedBuff1 =0x3f;LedBuff2 =0x00; else if(KeySta10=0)result = 0; else if(KeySta11=0)result = num1 * num1; else if(KeySta12=0)resul

26、t = num2 * num2;void InterruptTime0() interrupt 1 static unsigned char i = 0; static unsigned int cnt = 0; TH0 = 0xFC; TL0 = 0x67; KeyScan(); /按键扫描 cnt+; if(cnt >= 1000) cnt = 0;flag1s = 1; P0 = 0x00; switch(i) case 0: ADDR2=0; ADDR1=0; ADDR0=0; i+; P0=LedBuff0;break; case 1: ADDR2=0; ADDR1=0; AD

27、DR0=1; i+; P0=LedBuff1;break; case 2: ADDR2=0; ADDR1=1; ADDR0=0; i=0; P0=LedBuff2;break; default:break; 四、项目设计结果分析4.1实验结果(1)通过串口发送字符串4;2;#,按下第一行第一列的按钮,进行加法操作,数码管上显示“6”,串口助手上显示“6”;按下第一行第二列按钮,进行清零操作,数码管上显示“00”;按下第二行第二列按钮,进行num1的平方操作,数码管上显示“16”。实验结果及现象如图所示: (2)通过串口发送字符串4;7;#,按下第一行第二列的按钮,进行减法操作,数码管上显示“0

28、H”。实验结果及现象如图所示: 4.2遇到的问题及解决方法(1)串口发送数据、单片机接收数据时,拆分数组的问题。 解决:通过网上查找学习拆分函数strtok()、头文件的写法,通过调试找到数据处理出现问题的地方,例如串口发送字符串“1;2;#”,单片机接收字符串后点亮第一个小灯 ,判断数据接收是否出现问题;拆分数组时,当num1=1、num2=2时进行加法操作时,点亮第二个小灯,判断数组拆分是否正确。 (2) 数码管显示0H的问题。开始的时候,没考虑到数组运算中遇到除数为0且大于999时的问题。 解决:查看书本经过一番思索后,在按键操作和数码管显示时,根据计算情况将其异常处理,显示在数码管上。

29、 (3) 按键驱动、扫描的问题解决:查看书上的关于独立按键、矩阵按键的代码,与同学讨论了下后解决了这个问题。先将行置零,处理列,再将列置零,处理行。五、参考文摘1惠仇:手把手教你学51单片机,电子工业出版社,2009年。内容摘要:本书概括地论述了单片机的基础知识,包括单片机的基本结构和工作原理;并就实际单片机项目开发中会遇到的各种问题进行了阐述,列举了单片机开发的流程和必须遵守的一些规范,说明了仿真器和编程器在开发中的作用以及基本的使用方法。具体内容如下。首先论述了单片机的基础知识,包括单片机的基本结构和工作原理,阐述了目前单片机的发展情况,列举了最新流行的单片机种类,总结了单片机的选择方法。2 张毅刚等, MCS-51单片机应用设计,哈工大出版社,2004年第2版内容摘要:本书从应用的角度,详细地介绍了MCS-51单片机的硬件结构、指令系统、各种硬件接口设计、各种常用的数据运算和处理程序及接口驱动程序的设计以及MCS-51单片机应用系统的设计,并对MCS-51单片机应用系统设计中的抗干扰技术以及各种新器件也作了详细的介绍。本书突出了选取内容的实用性、典型性。书中的应用实例

温馨提示

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

评论

0/150

提交评论