第一篇:计算机RS232和C51单片机收发程序
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RS232串口通讯,由计算机或MCU发送C51单片机
通讯程序:发送3A 30 31 ** ** ** **(起始字符3A,地址为01,**代表数据,无结束字符,无和校验)接收超时时间:50ms 波特率:4800bps 接收到的数据用数码管显示出来
管脚定义:P0控制每位数码管显示,P2^2,P2^3,P2^4控制译码器,译码器控制哪一位显示 支持0~F的ASCII码数据接收
例如:发送 3A 30 31 42 43 44 45 后显示数码管显示 BCDE //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/******************************************************************************* * 实验名
: 动态显示数码管实验 * 使用的IO
: 数码管使用P0,P2.2,P2.3,P2.4 * 实验效果
: 数码管显示
******************************************************************************/ #include
/******************************************************************************* * 函数名
: main * 函数功能
: 主函数 * 输入
: 无 * 输出
: 无
*******************************************************************************/ void main(void){ SCON=0X50;//设置为工作方式1 TMOD=0X20;
//设置计数器工作方式2 PCON=0X80;//波特率加倍
TH1=0XF3;
//计数器初始值设置,注意波特率是4800的TL1=0XF3;ES=1;
//打开接收中断
EA=1;
//打开总中断
TR1=1;
//打开计数器
for(n=0;n<8;n++){
DisplayData[n]=DIG_CODE[n];
} while(1){
DigDisplay();}
} /******************************************************************************* * 函数名
: DigDisplay * 函数功能
: 使用数码管显示 * 输入
: 无 * 输出
: 无
*******************************************************************************/ void DigDisplay(){ unsigned char a;unsigned int j;
if(RECEIV_DATA_USART[0]==0x3A&&RECEIV_DATA_USART[1]==0x30&&RECEIV_DATA_USART[2]==0x31)
for(a=0;a<16;a++)
RECEIV_DATA[a]=RECEIV_DATA_USART[a];
p=0x00;//小数点判断
for(a=1;a<=8;a++)
{
if(RECEIV_DATA[a+2+p]==0x2E)
{
GPIO_DIG=0x80|GPIO_DIG;
p++;
j=10;
//扫描间隔时间设定
while(j--);
GPIO_DIG=0x00;//消隐 }
switch(a)//位选,选择点亮的数码管,{ case(1):
LSA=0;LSB=0;LSC=0;break;//显示第0位
case(2):
LSA=1;LSB=0;LSC=0;break;//显示第1位
case(3):
LSA=0;LSB=1;LSC=0;break;//显示第2位
case(4):
LSA=1;LSB=1;LSC=0;break;//显示第3位
case(5):
LSA=0;LSB=0;LSC=1;break;//显示第4位
case(6):
LSA=1;LSB=0;LSC=1;break;//显示第5位
case(7):
LSA=0;LSB=1;LSC=1;break;//显示第6位
case(8):
LSA=1;LSB=1;LSC=1;break;//显示第7位
} for(s=0;s<10;s++)
}
if(RECEIV_DATA[a+2+p]==0x30+s)
GPIO_DIG=DIG_CODE[s];
for(s=0;s<6;s++)
if(RECEIV_DATA[a+2+p]==0x41+s)
GPIO_DIG=DIG_CODE[0x0A+s];
j=10;
//停留时间设定
while(j--);
GPIO_DIG=0x00;//消隐
}
if(i>0)m++;//接收超时计时器
if(m>10&&RECEIV_DATA_USART[0]==0x3A)
{
for(n=i;n<=15;n++)RECEIV_DATA_USART[n]=0x00;
RECEIV_DATA_USART[0]=0x00;
m=0;
i=0;
}
void Usart()interrupt 4 {
if(SBUF==0x3A)//判断起始字符是否为0x3A
{
RECEIV_DATA_USART[0]=SBUF;
}
if(RECEIV_DATA_USART[0]==0x3A)
{
RECEIV_DATA_USART[i]=SBUF;//出去接收到的数据
i++;
}
RI = 0;//清除接收中断标志位 /* 以下代码为将接收到的数据返回给发送方,便于调试
SBUF=RECEIV_DATA[i];
while(!TI);
//等待发送数据完成TI=0;//清除发送完成标志位 */ }
第二篇:C51单片机自学第一课
第一课 了解单片机及单片机的控制原理,控制一个LED 灯的亮和灭
本章学习内容:
单片机基本原理,如何仿真器,如何编程点亮和灭掉一个LED 灯,如何进入KEILC51uV调试环境,如何使用单步,断点,全速,停止的调试方法
单片机现在是越来越普及了,学习单片机的热潮也一阵阵赶来,许多人因为工作需要或者个人兴趣需要学习单片机。可以说,掌握了单片机开发,就多了一个饭碗。
单片机已经有30 多年的历史了,在中国,高校的单片机课程大多数都是51,而51 经过这么多年的发展,也增长了许多的系列,功能上有了许多改进,也扩展出了不少分支。而国内书店的单片机专架上,也大多数都是51 系列。可以预见,51 单片机在市场上只会越来越多,功能只会越来越丰富,在可以预见的数十年内是不可能会消失的。
下面以51 为例来了解一下单片机是什么东西,控制原理又是什么?
在数字电路中,电压信号只有两种情况,高电平和低电平,用数字来记录就是1 和0。单片机内部的CPU,寄存器,总线等等结构都是通过1 和0 两种信号来运作的,数据也是以1 或者0 来保存的。单片机的输入输出管脚,也就是IO 口,也是只输出或识别1 和0 两种信号,也就是高电平和低电平。当单片机输出一个或一组电平信号到IO 口后,外部的设备就可以读到这些信号,并进行相应操作,这就是单片机对外部的控制。当外部一个或一组电平信号送到单片机的IO 口时,单片机也可以读到这些信号,并进行分析操作,这就是单片机对外部设备信号的读取。当然实际的操作中,这些信号可能十分复杂,必须严格地按照规定的时间顺序(时序)输入输出。每种设备也都规定了自己的时序,只要都严格遵守,就可以控制任何设备,做出只要你想象得出的任何事情。
您可能会再问,我如何让单片机去控制和分析外部设备呢?答案是程序,您可以编写相关的程序,并且把他们烧写到单片机内部的程序空间,单片机在上电时,就会一步一步按照您写的程序去执行指令,做您想做的事情。
在51 标准芯片中,有32 个输入输出IO,分为4 组,每组8 个,分别为P0 口,P1 口,P2 口,P3 口。P1 口的8 条脚就用P1.0 至P1.7 表示,其余类似。51 就是用这32 个口来完成所有外部操作的。对于51 的内部结构,如果您已经了解,那是最好;如果不懂,也可以先放下,在完成了本教程开始的几个章节之后,您就会大有兴趣,自己去寻找资料阅读了。当然,如果您希望成为一个优秀的单片机开发程序员,还是必须熟悉单片机的内部结构及工作原理,切不可偷懒!
在这一章,您将用程序去控制一个LED 发光管的亮和灭。你应该知道,LED 发光管在通过一定电流时亮,不通电就灭。为了不让LED 通过太大的电流把它烧坏,我们还要串上限流电阻。51 的IO 是弱上拉的方式,在输出高电平时,只能输出几十微安的电流到地,而在输出低电平时,VCC 电源可以输入几十毫安的电流到IO。一般LED 需要10 毫安左右电流点亮,我们就将LED 接在电源VCC 和IO 口之间,中间串上电阻,当IO 输出低电平时,灯就亮了,反之,灯就灭了。我们在这个程序里要控制的是P1.0。请参考一下我们将要使用的试验板的电路图。
现在可以开始做试验了,我们打开已经建立好的工程和编写好的程序试验。顺便还会学习一下程序调试的技巧。至于如何建立一个新工程,请参考C51 的帮助文件。请双击lessoncode01 目录下的lesson1.uv2,打开后界面如下:
点一下上图第三排第2 或者第3 个按钮(您的编译器按钮位置不一定在那个位置,自己找找),就可以看到编译结果了。上面显示是0errrs,0warnings,这是最佳的编译结果,如果有error,则无法进行下一步仿真,如果有warning,一定要尽量消除,确实无法消除的,也要确认不会对程序造成影响,才进行下一步的仿真。在编译结果中,我们还可以看到有data,xdata,code 等用了多少字节的报告,要注意您的单片机中是否有这么多的资源,如果不够,将来烧片运行时就可能出现问题。比如AT89C51 的程序空间是4K,xdata 如果没有外扩就是0 个,data 是128 个。超出这些范围,程序就不能在AT89c51 中运行。不同的芯片有不同的容量,如SST89E516RD 就有64K 程序,内部768 字节XDATA,还有256 个字节的data。我们的例程中肯定都考虑了这些了,肯定不会超出,将来自己开发时就要注意了。
下面我们故意把第9 行的P10 写成P11,点编译,因为没有预先定义P11,所以就报告错误了,如下图:
双击一下错误报告的那一行,窗口就也会跳到这一行,方便您进行修改。好了,现在请把错误改回去,再编译一次,出现报告正确了以后,下面开始仿真了。点一下第二行第5 个一个放大镜里面一个d 字母的按钮,就可以进入仿真了,仿真器要事先连接好哟。进入仿真后要退出仿真环境也是点这个按钮。注意,等会如果程序在正在全速运行时,仿真环境是不能直接退出的,得先点停止运行后,再点仿真按钮才可以退出。点进入仿真按钮,程序开始装载,PC 自动运行到了main()停下,并指向了main()函数的第一行。
进入仿真窗口后,如果出现的不是前面的源代码窗口,而是夹有反汇编代码的窗口,直接关掉这个窗口就会恢复到代码窗口。下次进入也会直接进入到源代码窗口。
现在先试验单步,点单步(两个单步都可以,一般点单步跨过)。可以看到灯亮了。PC 指针也指向了下一个
程序行。再点一下单步,PC 又走下一步,灯灭了。再点一次,PC 走到挂起的程序行了,继续点仍然在这一行。这句指令其实就是使程序不断地跳到自己这一行,别的什么也不做。一般称作程序挂起。
一般的实际应用中的程序是不会挂起的,一般是在main 函数里做一个大循环,程序如下:
void main(void)// 主程序 { while(1){ P11=0;//亮灯 P10=1;//灭灯 } } 请将main 函数程序改为上面的代码,我们下一步将试验断点的操作。
在第15 行双击一下,可以看到程序行左边出现了一个红方块,这就是设置断点,再双击一次,断点就取消了。如果程序在全速运行的过程中遇到断点,就会自动停下来给你分析。注意在进入仿真后,并且程序是停止状态时,才可以设置或者取消断点。
现在点全速运行,可以看到程序在断点处停了下来,并且由于前一句指令刚刚执行了点灯,所以这时灯是亮着的。
现在在第14 行设置断点,并且取消上一个断点。
现在点全速运行,可以看到程序在断点处停了下来,并且由于刚刚执行了灭灯,灯是灭着的。好,现在试验全速运行和停止。把断点取消,再点全速运行,可以看到灯是亮着的,但是不是很亮,这是由于程序是循环的,亮灭交替进行,亮的时间并不是全部的时间。现在点停止,可以看到程序停止了,重复几次进行全速和停止,可以发现每次停止的地方不一定是同一位置。
演讲稿
尊敬的老师们,同学们下午好:
我是来自10级经济学(2)班的学习委,我叫张盼盼,很荣幸有这次机会和大家一起交流担任学习委员这一职务的经验。
转眼间大学生活已经过了一年多,在这一年多的时间里,我一直担任着学习委员这一职务。回望这一年多,自己走过的路,留下的或深或浅的足迹,不仅充满了欢愉,也充满了淡淡的苦涩。一年多的工作,让我学到了很多很多,下面将自己的工作经验和大家一起分享。
学习委员是班上的一个重要职位,在我当初当上它的时候,我就在想一定不要辜负老师及同学们我的信任和支持,一定要把工作做好。要认真负责,态度踏实,要有一定的组织,领导,执行能力,并且做事情要公平,公正,公开,积极落实学校学院的具体工作。作为一名合格的学习委员,要收集学生对老师的意见和老师的教学动态。在很多情况下,老师无法和那么多学生直接打交道,很多老师也无暇顾及那么多的学生,特别是大家刚进入大学,很多人一时还不适应老师的教学模式。学习委员是老师与学生之间沟通的一个桥梁,学习委员要及时地向老师提出同学们的建议和疑问,熟悉老师对学生的基本要求。再次,学习委员在学习上要做好模范带头作用,要有优异的成绩,当同学们向我提出问题时,基本上给同学一个正确的回复。
总之,在一学年的工作之中,我懂得如何落实各项工作,如何和班委有效地分工合作,如何和同学沟通交流并且提高大家的学习积极性。当然,我的工作还存在着很多不足之处。比日:有的时候得不到同学们的响应,同学们不积极主动支持我的工作;在收集同学们对自己工作意见方面做得不够,有些事情做错了,没有周围同学的提醒,自己也没有发觉等等。最严重的一次是,我没有把英语四六级报名的时间,地点通知到位,导致我们班有4名同学错过报名的时间。这次事使我懂得了做事要脚踏实地,不能马虎。
在这次的交流会中,我希望大家可以从中吸取一些好的经验,带动本班级的学习风气,同时也相信大家在大学毕业后找到好的工作。谢谢大家!
第三篇:c51单片机实习报告
基于单片机实现短距离无线通信设计 引言
短距离无线传输具有抗干扰性能强、可靠性高、安全性好、受地理条件限制少、安装灵活等优点,在许多领域有着广泛的应用前景。低功耗、微型化是用户对当前无线通信产品尤其是便携产品的实际需求,短距离无线通信逐渐引起广泛关注。常见的短距离无线通信有基于802.11的无线局域网WLAN、蓝牙(blueTooth)、HomeRF及欧洲的HiperLAN(高性能无线局域网),但其硬件设计、接口方式、通信协议及软件堆栈复杂,需专门的开发系统,开发成本高、周期长,最终产品成本也高。因此这些技术在嵌入式系统中并未得到广泛应用。普通RF产品不存在这些问题,且短距离无线数据传输技术成熟,功能简单、携带方便,使其在嵌入式短程无线产品中得到了广泛应用。
PTR2000引脚简介及设计
2.1 PTR2000器件引脚功能
PTR2000是基于nRF401器件的无线数据传输模块,采用低发射频率、高灵敏度设计。该器件使用433 MHz频段,是真正的单片UHF无线收发一体器件,其工作模式包括工作频道的设置和发送、接收、待机状态,由TXEN、CS、PWM 3个引脚共同决定,其工作模式设置如表1所示。
2.2 PrR2000模块设计
该器件外围的主要电路有以下两个:
(1)与单片机的连接电路单片机AT89C52的RXD和TXD引脚与PTR2000模块的DO和DI引脚直接相连。PTR2000的模式控制引脚与单片机的控制引脚相连。
(2)与PC机的连接电路采用MAX202器件对PTR2000模块和计算机串口进行RS-232和TTL电平转换,将PTR2000与MAX202的输入和输出信号连接,转换后的信号与计算机的串口连接。
硬件设计
在无法使用有线传输的场合,采用无线数据传输模块和单片机相结合进行数据传输是较合理的方案。PTR2000利用串口进行数据传输,而单片机和PC机均带有串口,因此,可利用PTR2000作为单片机和PC机之间数据传输的无线接口,其硬件结构框图如图1所示。
该采集系统主要以AT89C52单片机为控制处理核心。由它完成对数据的采集处理以及控制数据的无线传输。AT89C52单片机具有快速8051内核、8 KB Flash E2PROM、256字节RAM。为实现无线数据传输,采用无限收发一体数据传送MODEM模块PTR2000器件,该器件内部集成高频接收、PLL合成、PSK调制/解调、参量放大、功率放大、频道切换等功能,完全符合无线数据通信的硬件要求。为降低成本,在最小硬件设计的基础上,利用C51高级C语言编程,系统的功能尽可能用软件程序实现。
3.1 单片机的时钟电路和复位电路设计
单片机时钟电路设计中,选择晶振频率11.059 2 MHz,约定PC机和单片机的通信速率为9 600 b/s,并选择相应电容与单片机的时钟引脚相连构成时钟回路。在复位电路设计中,采用复位引脚和相应的电容、电阻构成复位电路。单片机与PTR2000接口原理电路如图2所示。
3.2 单片机与PTR2000接口电路的设计
在图2中,AT89C52单片机主要完成数据的采集和处理,向PTR2000模块发送数据,并接收由PC机通过PTR2000传送的数据。和单片机相连的PTR2000模块主要将单片机的待传数据调制成射频信号,再发送到PC机端的PTR2000模块,同时接收PC机端的PTR2000模块传送的射频信号,并调制成单片机可识别的TTL信号送至单片机。单片机的RXD和TXD引脚分别和PTR2000的DO和DI引脚连接,实现串行数据传输;决定PTR2000模块工作模式的TXEN、CS、PWR 3个引脚分别和单片机I/O控制口的P2.0~P2.2相连,PTR2000工作时,由单片机中的运行控制程序实时控制其工作模式。
3.3 PC机与PTR2000接口电路的设计
该接口电路设计首先需进行电平转换。PC机的串口支持RS-232标准,而PTR2000模块支持TTL电平,选择MAX232器件进行两者间的电平转换,接口电路如图3所示。PTR2000模块进行串行输入、输出,引脚DI、DO通过电平转换器件和PC机串口相连;PTR2000的低功耗控制引脚。PWR接高电平VCC,即PTR2000固定工作在正常工作状态;频道选择引脚CS接GND低电平,即采用固定通信频道1,固定工作在433.92 MHz;PC机串口的RTS信号控制TXEN引脚,以决定PTR2000模块何时为接收和发射状态。PC机和串口的传输速率设定为9 600 b/s,和单片机保持一致。软件设计
无线通信系统的软件设计包括单片机端和PC机端两部分,两部分软件相互配合,设置各自的PTR2000模块的工作状态。
4.1 PTR2000模块程序设计
单片机和PC机端软件配合设置PTR2000的状态(发射或接收),选择固定的通信频道1(CS=0),并让PTR2000模块一直处于正常工作状态(PWM=1)。无线通信实现过程如下:
(1)发送在发送数据之前,应将PTR2000模块置于发射模式,即TXEN=1。然后等待至少5 ms后(接收到发射的切换时间)才可发射数据。发送结束后,应将模块置于接收状态,即TXEN=0。
(2)接收应将PTR2000置于接收模式,即TXEN=0。单片机不发送的绝大部分时间都处于接收状态。当单片机端发送时,PC机端应为接收;当PC机端发送时,单片机端应为接收。
4.2 串行无线通信协议设计
无线通信中,由于外部环境的干扰,通常误码率较高,因此通信协议的设计对保证通信的可靠性十分重要。协议的设计主要是帧结构的设计,在该无线通信系统中,存在指令帧和数据帧。数据帧的内容包括起始字节、数据长度字节、数据字节、结束字节和校验和字节,如表2所示。
起始字节定义为“$”字符,其数值为0x24;结束字节定义为“*”字符,其数值为0x2A。
采用校验和的方法进行帧的校验,将所有字节相加,然后将结果截短到所需的位长。发送端对待发送的数据进行校验和计算,将校验和值放在数据后一起发送;在接收端,对接收到的数据进行校验和计算,然后与收到的校验和字节比较,进行误码判断。
对于单片机,指令帧主要有3种:PC机发送给单片机的请求发送指令、错误/超时重发指令、单片机发给PC机的发送完毕指令。在该系统设计中指令帧采用数据帧的格式,将其中的。数据字节固定为一个字节,根据定义的字节判断数据状态。
4.3 程序流程
单片机开始需将无线数据传输模块PTR2000设置处于接收状态,通过串口中断识别由PC机通过无线信道传输来的指令,根据接收指令的内容采集数据并启动发送。发送前需将PTR2000模块设置为发射状态,且等待5 ms才可发送,发送完毕后,向PC机端发送“发送结束指令”,并将PTR2000模块重设为接收状态。图4为系统软件设计流程图。结束语
单片机无线通信系统设计基于PTR2000无线数据传输解决方案,可实现小于300 m的短距离通信,通过实验验证该无线数据传输系统运行良好,单片机控制得相当准确。在应用时将系统作为一个模块可方便地移植,以便构建更为复杂的无线通信网络,可应用于小型无线网络、无线抄表、小区传呼、工业数据采集系统、安全防火系统等领域,具有一定实用价值。
第四篇:C51单片机实训论文
上海第二工业大学
实训课程
课 程: 二级项目(电子设计)
学生姓名:
许奇峰
学 号:
104827477
学院名称:
电子与电气工程学院
专业班级:
10测控C1
摘要
近年来随着科技的飞速发展,单片机的应用正在不断深入,同时带动传统控制检测技术日益更新。在实时检测和自动控制的单片机应用系统中,单片机往往作为一个核心部件来使用,仅单片机方面知识是不够的,还应根据具体硬件结构软硬件结合,加以完善。
本实验采用的单片机为C51,以C语言为程序设计的基础,通过4*4的矩阵键盘上的特定的按键来控制1602液晶显示屏,以显示设计人的姓名、学号,还有时钟来显示时、分、秒、日期,并且显示当时的温度,PWM和A/D转换等功能。
一. 实验目的
通过此次实训,让我们掌握了单片机基本原理的基础、单片机的编程知识以及初步掌握单片机应用系统开发实用技术,了解单总线的读/写控制方法。同时培养学生理论与实践相结合的能力,提高分析问题和解决问题的能力,增强学生独立工作能力;培养了我们团结合作、共同探讨、共同前进的精神与严谨的科学作风。本次实验的目的主要有以下几点:
1、熟悉51单片机的基本构造和原理基础;
2、能运用51单片机进行简单的单片机应用系统的硬件设计;
3、掌握单片机应用系统的硬件、软件调试方法; 4、4*4矩阵键盘的应用,1602液晶显示屏幕的应用等;
5、运用C51单片机来设计显示时钟、温度、PWM、A/D转换。
二.硬件组成
·51单片机最小系统
1、震荡器
单片机系统正常工作的保证,如果振荡器不起振,系统将会不能工作;假如振荡器运行不规律,系统执行程序的时候就会出现时间上的误差,这在通信中会体现的很明显:电路将无法通信。他是由一个晶振和两个瓷片电容组成的,x1和x2分别接单片机的x1和x2,晶振的瓷片电容是没有正负的,注意两个瓷片电容相连的那端一定要接地。
2、复位端 复位电路
给单片机一个复位信号(一个一定时间的低电平)使程序从头开始执行;一般有两中复位方式:上电复位,在系统一上电时利用电容两端电压不能突变的原理给系统一个短时的低电平;手动复位,同过按钮接通低电平给系统复位,时如果手按着一直不放,系统将一直复位,不能正常
·AT89C51 1)简介
A89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—Flash Programmable and Erasable Read Only Memory)的低电压,高性能CMOS 8位微处理器,俗称单片机。单片机的可擦除只读存储器可以反复擦除100次。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器。AT89C51单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。外形及引脚排列如图所示。2)功能特性 ·与MCS-51 兼容
·4K字节可编程闪烁存储器
·寿命:1000写/擦循环
·数据保留时间:10年
·全静态工作:0Hz-24MHz
·三级程序存储器锁定
·128×8位内部RAM
·32可编程I/O线
·两个16位定时器/计数器
·5个中断源
·可编程串行通道
·低功耗的闲置和掉电模式
·片内振荡器和时钟电路
·矩阵键盘(如附录2,图2)
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。
矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,上图中,列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。这样,当按键没有按下时,所有的输出端都是高电平,代表无键按下。行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。
·蜂鸣器
通过加一个低电压,大电流,小信号的PNP型硅三极管Q8550来放大电流达到驱动蜂鸣器的作用,蜂鸣器的正极接到Q的集电极C上,蜂鸣器的负极接地,三极管的发射极E接电源VCC,基极B经过限流电阻R9后与单片机P1.3的引脚相连,当单片机P1.3引脚输出高电平时,三极管截止,没有电流通过线圈,蜂鸣器不发声;当单片机P1.3引脚输出低电平时,三极管导通,电流形成回路,蜂鸣器发声。
·LED1602液晶屏
1602液晶也叫1602字符型液晶它是一种专门用来显示字母、数字、符号等的点阵型液晶模块它有若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符。每位之间有一个点距的间隔每行之间也有间隔起到了字符间距和行间距的作用,正因为如此所以他不能显示图形。引脚定义:
1脚:VSS为电源地;
2脚:VDD接5V电源正极;
LED1602引脚图
3脚:V0为对比度调整端,接正电源时对比度最弱,接地电源时最高;
4脚:RS为寄存器选择,高电平时数据寄存器、低电平时指令寄存器;
5脚:RW为读写信号线,高电平时进行读操作,低电平时进行写操作;
6脚:E(或EN)端为使能(enable)端;
7~14脚:D0~D7为8位双向数据端;
15~16脚:空脚或背灯电源;15脚背光正极,16脚背光负极。
二.实验过程
1.启动KEIL,使用自己做的含C51芯片的单片机电路板。2.在main.c中编写主程序代码
3.选用build target 生成目标,然后编译连接工程
4.打开STC-ISP-V4.86-NOT-SETUP-CHINESE,选择com口,将编译的文件下载到电路板上
5.按键操作,显示,观察。。
开始初始化While 1NN有键盘按下Y再次从新扫描延时一段时间真的有键盘按下吗Y键盘扫描处理根据不同的扫描值赋值于Key根据Key值做相应程序处理结束
实验流程图
四. 实验总结
随着电子技术的日益进步,微型计算机取得了突飞猛进的发展。作为微型计算机的一个重要分支,单片机以其体积小、功能齐全、价格低廉、可靠性高等特殊优点,在工业测控、智能仪表器、机电一体化产品、家电等领域取得了快速的发展。
通过几天的实习,深有体会,学习单片机只有对着电脑,反复敲打键盘,不断编写、修改、做记录,才能很好了解单片机、学好单片机。相信捉住这条思维,在以后学习中,能给予很大的帮助。几天下来,在我个人方面,学到的东西还是挺多的。
经过一个学期的单片机学习,使我们收获不少,在这个设计中,也学到了不少东西,从找设计开始,各种元件的选择,和同学一起分享画图,敲程序,学到了制作的过程,对数字电子钟也有了一定的认识。十分感谢老师和同学们一学期以来的帮助。这次实验,不仅学会了电子钟的制作,也对单片机的知道有了更加深入的了解,对自己帮助非常大,扩展了自己的视野。一.实验附录
附录一(效果图)
图一.菜单显示 图二.菜单显示
图三.菜单显示 图四.时间显示
图五.A/D转换显示 图四.温度显示
附录二(参考程序):
#include
//延时程序 { uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);} void wr_com(unsigned char com)
//写命令 { delay1ms(5);EN=0;
//使能端给一个高脉冲,因为初始化函数中已经将lcden置为0 RS=0;
//选择写命令模式
RW=0;
//P0=com;
//将要写的命令送到数据总线上
EN=1;
//将使能端置0以完成高脉冲
} void wr_dat(unsigned char dat)
//写数据 { delay1ms(5);EN=0;RS=1;RW=0;
P0=dat;EN=1;} void init()
//清屏
{wr_com(0x38);
//设置16*2,显示5*7点阵,8位数据接口
wr_com(0x0C);
//设置开显示,不显示光标
wr_com(0x06);
//写一个符号地址指针自动加一
wr_com(0x01);
//显示清0,数据指针清0} void MoveKey(uchar Num){ lcd_clr();
wirte_str(0,0,Anum[Num]);
wirte_str(1,0,Anum[Num+1]);
lcd_wcmd(0x0f);} void keypress(uchar key)
//显示
keypress
功能
{ if(key==12)
//下
{ MoveKey(num);
keyboard=num+1;
num--;if(num<0)num=5;delay(10);}
if(key==16)
//上
{
MoveKey(num);
keyboard=num+1;
num++;
if(num>5)num=0;delay(10);}
if(key==11)
//退出
{ lcd_clr();
wirte_str(0,0,“Xu Qifeng”);
wirte_str(1,0,“104827477”);}} void getKey(){ uchar temp,readRow;P2=0xFE;
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{ delay(10);
readRow=~temp>>4;switch(readRow){case 1:key=10;break;
//enter 进入
case 2:key=11;break;
//esc
退出
case 4:key=12;break;
//下
case 8:key=16;break;
//上
default:break;}
while(temp!=0xf0)
{temp=P2;
temp=temp&0xf0;} delay(10);
keypress(key);} P2=0xFD;
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{ delay(10);
readRow=~temp>>4;switch(readRow){case 1:{key=14;m++;if(m==10)m=0;};break;//右
case 2:key=3;break;case 4:key=6;break;
case 8:key=9;break;}
while(temp!=0xf0)
{temp=P2;
temp=temp&0xf0;}
delay(10);
keypress(key);} P2=0xFB;
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{ delay(10);
readRow=~temp>>4;switch(readRow){case 1:{key=13;m--;if(m==0)m=10;};break;//左
case 2:key=2;break;case 4:key=5;break;case 8:key=8;break;}
while(temp!=0xf0)
{temp=P2;
temp=temp&0xf0;}
delay(10);
keypress(key);} P2=0xF7;
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{delay(10);
readRow=~temp>>4;switch(readRow){case 1:key=0;break;case 2:key=1;break;case 4:key=4;break;case 8:key=7;break;}
while(temp!=0xf0)
{temp=P2;temp=temp&0xf0;} delay(10);keypress(key);}} voidtime1()interrupt3
//显示
Time
功能
{ TH1=0xdc;TL1=0x00;
count_10ms++;}
void time1_init(){ TMOD=0x10;TH1=0xdc;TL1=0x00;EA=1;ET1=1;TR1=1} uchar disp_buf[6]={0x00,0x00,0x00,0x00,0x00,0x00};void lcd_dat(uchar h,m,s)
//读取时间
{disp_buf[0]=h/10+0x30;disp_buf[1]=h%10+0x30;
disp_buf[2]=m/10+0x30;disp_buf[3]=m%10+0x30;
disp_buf[4]=s/10+0x30;disp_buf[5]=s%10+0x30;} void lcd_display()
//显示时间 { lcd_wcmd(0x44|0x80);lcd_wdat(disp_buf[0]);lcd_wdat(disp_buf[1]);
lcd_wdat(0x3a);lcd_wdat(disp_buf[2]);lcd_wdat(disp_buf[3]);
lcd_wdat(0x3a);lcd_wdat(disp_buf[4]);lcd_wdat(disp_buf[5]);} void Time()
{keyboard=0;
time1_init();
lcd_init();
wirte_str(0,0,“Time”);
while(1)
{ if(count_10ms>=100)
{ count_10ms=0;
sec++;} if(sec>=60)
{sec=0;min++;
if(min>=60)
{ min=0;hour++;
if(hour>=24)
{ hour=0;min=0;sec=0;} } } lcd_dat(hour,min,sec);
lcd_display();
getKey();
if(key==11)break;}}} voidTempture()
//显示
Temp
功能
{ void display()
{ unsigned long temp;
temp=Temp*100;
disdata[0]=temp/1000+0x30;//十位数
disdata[1]=temp%1000/100+0x30;// 个位数
disdata[2]=temp%100/10+0x30;//小数
disdata[3]=temp%10+0x30;
if(disdata[0]==0x30)
{ disdata[0]=0x20;//如果十位为 0,不显示
if(disdata[1]==0x30)
//如果十位为 0,个位为 0 也不显示
{ disdata[1]=0x20;} }
lcd_wcmd(0xc1);
lcd_wdat(disdata[0]);//显示十位
lcd_wdat(disdata[1]);//显示个位
lcd_wdat(0x2e);//显示小数点
lcd_wdat(disdata[2]);//显示小数
lcd_wdat(disdata[3]);} uchar disdata[5];float Temp;
void delayms(uint xms){ uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);}} voidAD_Init()
// 显示
A/D
功能
{ P1M0=0x0f;
//设置P1口低4位为开漏模式,AD采集
P1M1=0x0f;
P1ASF=0x0f;
//P1口模拟功能控制位,ADC_CONTR=0xe0;
//开启AD转换并选择最高转换速度
AUXR1=0x00;
//数据格式设置
高八位在ADC_RES 低二位在ADC_RESL
delayms(100);} int GetAD(uchar channel)//选择通道号
并获取数据 {uchar AD_finished=0;
int result;
ADC_CONTR|=channel;
//选择通道号
ADC_CONTR|=0x08;
//启动AD转换
while(AD_finished=0)
{ AD_finished=(ADC_CONTR&0x10);//查询ADC_FLAG是否置1} result=ADC_RES*4+ADC_RESL;ADC_CONTR&=0xef;//清除转换结束标志
return(result);} float Ad_Av(uchar channel)//对获取的数据进行处理 {float Val_Av=0;
uchar num;
for(num=100;num>0;num--)
{Val_Av+=GetAD(channel);}
Val_Av/=100.0;
Val_Av=Val_Av*5/1024;
return(Val_Av);} void AD()
{ keyboard=0;
AD_Init();
lcd_init();
lcd_wcmd(0x80);//显示字符
AD
lcd_wdat(0x41);
lcd_wdat(0x44);
while(1)
{delayms(500);
Temp=Ad_Av(0);
//通道0进行数据采集
display();getKey();if(key==11)break;}} sbitPwm=P1^0;
//显示
PWM
功能 uchar n=0,m=0;void delayms(uint xms);void Timer0_init();void PWM(){ keyboard=0;
time1_init();
lcd_init();
lcd_clr();
wirte_str(0,0,“PWM”);
while(1)
{ if(count_10ms>=10){ count_10ms=0;
if(n<=m)
Pwm=1;
else
Pwm=0;
n++;
if(n==10)n=0;}
getKey();
if(key==11)break;}} voidElse()
{lcd_clr();wirte_str(0,0,“That's all”);wirte_str(1,0,“Thank you”);delay(100);keyboard=0;} void main()
{ lcd_init();
wirte_str(0,0,“Xu Qifeng”);
wirte_str(1,0,“104827277”);
while(1)
{getKey();
if(key==10)
//enter
{switch(keyboard)
{ case 1:Time()break;
case 2:Tempture();break;
case 3:AD();break;
case 4:PWM();break;
case 5:Else();break;
default:break;}}}
//显示
Else 功能
//主函数
第五篇:基于C51单片机的交通灯控制系统
基于C51单片机的交通灯控制系统
1、实验方案论证:
进行十字路口的交通信号灯控制电路设计,画出电路原理图及实验电路图,进行软件编程、以及使用说明文档的建立等一整套工作任务。进行十字路口的交通信号灯控制程序设计,提交一个符合上述功能要求的十字路口的交通信号灯控制系统设计。
2、控制流程分析:
对设计要求进行分析后可得出以下交通工作状态表:
3、硬件设计概要:
根据设计要求,可用6个LED灯分别模拟东西、南北的交通灯。具体接法如下: AT89C51的P1口接LED灯,P1.0、P1.1、P1.2分别接东西方向红、绿、黄交通灯,P1.3、P1.4、P1.5分别接南北方向的红、绿、黄交通灯。P1口和LED灯之间要接限流保护电阻。两位数码管段选接P2口,位选接P0口低两位,P0口低两位接上拉电阻使其可以输出高电平。紧急情况按钮一端接地,另一端与外中断1引脚相连;恢复正常按钮一端接地,另一端与外中断0引脚相连。
三、原理图设计
1、LED显示部分电路设计:
把单片机AT89C51的P1口作为红黄绿灯显示部分,用6个LED灯分别模拟东西、南北的交通灯。P1.0、P1.1、P1.2各通过一个300Ω的限流保护电阻接东西方向的红、绿、黄LED灯;P1.3、P1.4、P1.5各通过一个300Ω的限流保护电阻接南北方向的红、绿、黄LED灯。LED灯的一端接电源,另一端经电阻接P1口,因此当P1口引脚输出低电平时LED灯发光,即此方案采取低电平驱动方式。具体电路如下:
2、紧急情况处理电路设计:
紧急情况按钮一端接地,另一端与外中断1引脚相连;恢复正常按钮一端接地,另一端与外中断0引脚相连。在程序设计时,我会将其设置为下降沿触发方式。具体电路如下:
3、数字显示电路设计: 选用共阴极两位数码管。两位数码管A~G引脚各通过一个300Ω的限流保护电阻分别接P2.0~P2.6,位选1引脚和2引脚分别接P0.0口低两位,P0口低两位接5kΩ的上拉电阻使其可以输出高电平。
4、其他部分电路:
XTAL1端和XTAL2端之间接一个12M Hz的晶振,再各接一个30pF的普通电容后接地;RST复位端一端经10uF的电解电容接+5V电源,一端经一个10K的电阻接地。具体电路如下:
4、系统电路总图:
四、程序设计:
1、定时器初值的计算:
由于要求定时时间相当精确,我用定时器T0进行定时。根据公式可知若已知要求的定时时间为t,则定时器的初值为x(其中fosc=12M Hz)
: 需要定时器的定时时间为50ms,根据公式计算得出X=15536,因此定时器初值的低位TL0=(0B0H),高位TH0=(3CH)。
2、程序流程图: 2.1主程序流程
主程序主要是对单片机进行初始化。初始化首先要开放总中断、定时器T0中断以及外部中断0和外部中断1。其次是设置中断优先级,把外中断0设置为高优先级,外中断1设置为低优先级。再次是给定时器T0装顶初值,然后后是启动定时器,是使定时器开始定时。最后是等待中断。
2.2紧急情况中断处理流程
紧急情况中断处理包括两部分,第一部分是出现紧急情况可以手动使东西、南北方向红灯全亮,而且直到紧急状况解除后才能恢复正常通车。这就要求紧急状况解除前不能退出外中断1处理程序,因此要在外中断1处理程序处设置一无限循环。第二部分是紧急状况解除。为了使外中断1处理程序退出无限循环,可用中断嵌套使机器转去执行外中断0处理程序,而外中断0处理程序修改了寄存器R2的值,中断返回后由于寄存器R2的值的改变使外中断1处理程序跳循环。2.2.1外中断1处理程序(低优先级)2.2.2外中断0处理程序(高优先级)
1.3定时器中断处理流程
Y Y
3、程序源代码: ORG 0000H AJMP START ORG 0003H;外中断0入口 AJMP SERV0 ORG 000BH AJMP SERV1 ORG 0013H AJMP SERV2 ORG 0030H START:MOV IE,#87H MOV IP,#01H MOV TMOD,#01H MOV TCON,#05H MOV TH0,#3CH MOV TL0,#0B0H MOV DPTR,#TAB MOV P1,#0F6H MOV R0,#20 MOV R5,#00H MOV R6,#00H SETB TR0 LOOP1:MOV P0,#02H MOV A,R6 MOVC A,@A+DPTR MOV P2,A ACALL D10MS MOV P0,#01H MOV A,R5 MOVC A,@A+DPTR MOV P2,A ACALL D10MS AJMP LOOP1;外中断1入口;定时器中断入口 设置中断优先级;装定时器初值;装表首地址;启动定时器;循环动态显示,由10秒开始倒计时
SERV0:MOV R2,#0FFH;正常状态恢复程序,使R0的值不为0 RETI SERV1:DJNZ R0,NEXT;未到1秒,则转到NEXT CJNE R5,#01,DHE0 AJMP DHE3 DHE0: CJNE R5,#00H,DHE1 CJNE R6,#00H,DHE2 MOV R5,#00H MOV R6,#01H MOV P1,#0F5H AJMP OUT0 DHE1: DEC R5 AJMP OUT0 DHE2: MOV R6,#00H MOV R5,#09H OUT0: MOV R0,#20 RETI DHE3: MOV P0,#00H MOV P2,#3FH MOV A,P1 MOV R1,#05H JNB ACC.0,CHE0 YELL0:SETB P1.0 SETB P1.1 CLR P1.2 ACALL DMS SETB P1.2 ACALL DMS DJNZ R1,YELL0 MOV P1,#0EEH SJMP NEXT1 CHE0: JNB ACC.3,CHE1 YELL1:SETB P1.3 SETB P1.4 CLR P1.5;减1秒;显示为0;东西方向红灯亮,则转到CHE0;东西方向绿灯灭;东西方向黄灯闪烁5次;东西方向红灯亮,南北方向绿灯亮;南北方向绿灯灭 ACALL DMS SETB P1.5 ACALL DMS DJNZ R1,YELL1;南北方向黄灯闪烁5次 CHE1: MOV P1,#0F5H;南北方向红灯亮,东西方向绿灯亮 NEXT1:MOV R0,#20 MOV R5,#00H MOV R6,#01H;重置显示为10秒 NEXT: MOV TH0,#3CH;重装定时器初值 MOV TL0,#0B0H RETI SERV2:MOV P0,#00H MOV P2,#3FH;显示为0 MOV R5,#00H MOV R6,#00H MOV R2,#00H;紧急状况服务程序,使R2的值为0 MOV P1,#0F6H LOOP3:CJNE R2,#00H,OUT1;R2的值为0,则无限循环,直到执行SERV0状 MOV R3,#02H;态恢复程序,使R0的值不为0才返回 DJNZ R3,LOOP3 OUT1: RETI DMS: MOV 32H,#4;延时子程序,延时0.4秒 DL0: MOV 31H,#200 DL1: MOV 30H,#250 DL2: DJNZ 30H,DL2 DJNZ 31H,DL1 DJNZ 32H,DL0 RET D10MS:MOV 33H,#50;延时子程序,延时10毫秒 DL3: MOV 34H,#100 DL4: DJNZ 34H,DL4 DJNZ 33H,DL3 RET TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH END
五、仿真结果与分析
在PROTEUS软件仿真中的结果如下:
1、初始状态
2、东西路口的绿灯亮,南北路口的红灯亮
3、东西路口绿灯灭,黄灯闪烁
4、东西路口红灯亮,南北路口的绿灯亮
5、南北路口绿灯灭,黄灯闪烁
由以上仿真结果可以看出,电路图和源程序设计完全满足设计要求。
六、课程设计总结与体会
通过这次课程设计我巩固和加深课堂所学知识;掌握一般软硬件的设计方法和查询、运用资料的能力;掌握通过定时器进行定时的基本方法、中断控制的原理和方法以及LED控制的方法。
这次课程设计,我将课本上的理论知识和实际的应用有机的结合起来,提高分析和解决问题的实际能力,通过对汇编语言程序代码的设计、编写、修改以提高自己实际编程能力。
总的来说,这次课程设计的难度不算大,整个设计、调试任务都有我独立完成。而在PROTEUS软件仿真中的结果可以看到我的设计完全符合要求。在设计过程中我还认识到,遇到问题时应回到书本,查找实际问题所需的理论知识,将理论和实际结合起来。这样,在解决问题的同时还能提高我对理论知识的理解。