STC89C52通过串口控制流水灯亮灭

2016-05-12来源: eefocus关键字:STC89C52  串口控制  流水灯
本次笔记包含两个方面:

1.只是控制LED的亮灭,不返回数值

2.控制LED的亮灭,并返回数值

看了几讲的视频,都是在讲串口的方式1。其他的还没接触,这里也只用串口的方式1实现这两个功能。串口里面需要计算的地方是根据所要使用的波特率求定时器的初始值。定时器使用的是方式2,可以自动装初始值,避免赋值语句装初始值时出现误差。

以9800bps,定时器使用方式2,串口使用方式1,晶振波特率为 11.0592MHZ,求TH1跟TL1的值。

方式1的波特率 = (2^SMOD/32)xT1溢出率。单片机复位后,电源管理寄存器PCON全部清零,SMOD作为其中一位自然也清零。

波特率已经知道了。这样就剩下T1溢出率了。

假设初值为X,则定时器每次计256-X个数溢出一次(定时器为8位,最大为255 。256时发生溢出)。每计一个数的时间为一个机器周期,机器周期 = T时钟周期 X 12 。于是溢出的时间为 = 个数X 每个时间 = ( 256 - X) * 12/Fosc . 那么基础率就是溢出时间的倒数。

于是结合公式“方式1的波特率 = (2^SMOD/32)xT1溢出率”,式子可以总结为:

9600 = 2^0 /32 * Fosc / (256 - X)*12     带入全部已知数据得到     9600 = 2^0 /32 * 11059200/ (256 - X)*12    =====》》》》  求得的X为: 253  .

在此基础上,如果把SMOD 设为1 ,则 求得波特率为  :

波特率 = (2^1/32) * 11059200 / (256 - 253 )  = 2 * [  1/32 * 11059200 / (256 - 253)] = 2 * 9600 =  19200  。即变为原来的两倍。

如果把晶振换成12MHZ再求初值,求得的X为: 252.744792…… 无穷小数。这样就会产生误差。以前一直感觉整数的晶振挺好,现在才知道为什么会有11.0592MHZ这种晶振的存在了,。

这样计算得到了初值,下面贴代码。

只是控制LED的亮灭,不返回数值

实现这个又分为查询和中断两种方法。

A。先用查询。感觉叫判断更好些,因为是用if判断来实现的

 

#include 

void main()
{  
		//设置参数
		TMOD = 0x20; //设定定时器1的工作方式为方式2
		TH1 = 0xfd;
		TL1 = 0xfd;	 //装载TH1、TL1
		TR1 = 1; //启动定时器1

		REN = 1; //允许串行接收位
		SM0 = 0;
		SM1 = 1; //设定串口工作方式为方式1
/*
*    	       EA = 1; //全局中断允许位
*		ES = 1; //串口中断允许位
*		此处使用的是查询法判断接收中断标志位,所以即便不开启中断允许位,也可以
*
*/
	while(1)
	{	 	
		//查询法检测RI
		if(RI == 1)//RI为接收中断标志位。硬件置为1,必须软件清0
		{
			P1 = SBUF;
			RI = 0;
		} 		
	}

}
B 中断法

 

 

#include  
void main()
{  
		//设置参数
		TMOD = 0x20; //设定定时器1的工作方式为方式2
		TH1 = 0xfd;
		TL1 = 0xfd;	 //装载TH1、TL1
		TR1 = 1; //启动定时器1

		REN = 1; //允许串行接收位
		SM0 = 0;
		SM1 = 1; //设定串口工作方式为方式1

		EA = 1; //全局中断允许位
		ES = 1; //串口中断允许位

		while(1) ;	//等待中断的发生
		
}

//中断检测RI
void ser() interrupt 4
{
	   P1 = SBUF;
	   RI = 0;
}

这两个除了代码,感觉就是是否开启中断允许了。因为RI置为1是硬件自动执行的。即便是不开启中断允许位,照样可以用if进行判断。

 

 

上面这两个是单方向的,再来个双向的。

 

/*
 *通过串口给下位机发送数据,并使之显示在P1口的流水灯上。
 *同时单片机返回接收到的数据,显示在串口助手上
 */
#include 

unsigned char flag;

void main()
{  
		//设置参数
		TMOD = 0x20; //设定定时器1的工作方式为方式2
		TH1 = 0xfd;
		TL1 = 0xfd;	 //装载TH1、TL1
		TR1 = 1; //启动定时器1

		
		SM0 = 0;
		SM1 = 1; //设定串口工作方式为方式1
		REN = 1; //允许串行接收位

    	EA = 1; //全局中断允许位
		ES = 1; //串口中断允许位

	while(1)
	{	
		/* 刚开始单片机缓冲寄存器为空,无数据可以显示
		 * 先从串口接收数据,再返回该数据
		 * 在中断中接收数据,同时将flag标志位置为1.说明接收到了数据
		 * 若接收到数据(flag == 1),说明接收到了;否则说明未接收到数据,不显示。继续判断flag数值
		 */
		
		if(flag == 1) 
		{						
			//发送数据
			ES = 0; //关闭串口中断,发送数据
			SBUF = P1; //数据写入SBUF寄存器
			while(!TI); //等待
			TI = 0;
			ES = 1; 
			flag = 0;
		
		}		
	}

}

void ser() interrupt 4
{
	//接收数据
	P1 = SBUF;
	flag = 1;
	RI = 0;
}

主函数里面那个flag = 0  。 一定不能少了。否则只要一小会儿的功能,串口助手就卡了。。。。

 

这个例子里还有两条语句比较关键:

P1 = SBUF;//把SBUF寄存器中的数值赋给P1

SBUF = P1;//把P1的数值写入到SBUF

SBUF是这么写的:SBUF 串行数据缓冲寄存器,一个发送缓冲寄存器,一个接收缓冲寄存器。两个公用一个地址99H,但在物理上是两个独立的寄存器。那么如何区分是发送还是接收呢?就用语句来区分了。

控制流水灯的话,需要发送十六进制格式的。

比如发送FB(1111,1011)。在我的开发板上是L2灯亮。如果发送字符,就不太好控制了。如果用2中的例程,以字符方式发送“fb”,单片机返回串口助手并用十六进制显示为“62” .这个,嗯,目前不会算 :P

 

没啥值得纪念的图片,还是几个流水灯。不过此时的流水灯,非彼时的流水灯。现在的流水灯,可是我从电脑上就能控制开发板上的了:D

只是不知道下次自己写个上位机是什么时候了,

关键字:STC89C52  串口控制  流水灯 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/article_2016051226326.html

上一篇:基于51单片机的步进电机驱动器
下一篇:单片机之旅——中断之流水灯

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STC89C52RC单片机的NRF24L01无线通信程序,收发一体
本设计由两块STC89C52RC单片机组成,通过NRF24L01实现最廉价的无线通信。每块单片机都是集收发于一体,先初始化会在OLED上显示是否初始化成功,然后通过按键可选择收发模式,并在OLED屏幕上显示出来最后选择串口调试助手,打开串口给单片机发送信息,单片机接收到后再通过NRF24L01向另一块单片机发送接收成功后会将接收到的信息显示在OLED上。OLED显示屏较1602液晶显示屏清楚,可现实的内容丰富,可以建立自己的字库并且占用的引脚较少单片机源程序如下:#include "reg52.h"#include "oled.h"#include "bmp.h"
发表于 2020-11-09
STC89c52+DS1302时钟,数码管显示时间日期,可调节
最近在做数字电子时钟,也总结出来一些资料,在这分享给大家,DS1302时钟芯片。电脑仿真所需要的芯片有AT89C52,74HC138 排阻(因为C52单片机P0的IO口没有上拉电阻),74HC245 ,如果需要做实物,还得根据数码管的型号选择合适的电阻,DS1302芯片,按钮1,工作原理我们先了解我们所用的东西,STC89C52是8051单片机,这里就不多介绍了,然后就是DS1302时钟芯片,这个是DS1302时钟芯片这个是工作原理,我们经常用的DS1302与单片机的连接使用2.实验思路理解DS1302时钟芯片与单片机之间的数据传送,用的单总线的方式,所以会有时序图,还有读写图表三是地址,如果读取某个分钟或者小时,我们读数
发表于 2020-09-18
<font color='red'>STC89c52</font>+DS1302时钟,数码管显示时间日期,可调节
分享一个STC89C52的头文件
.--------------------------------------------------------------------------*/#ifndef __STC89C52_H__#define __STC89C52_H__typedef unsigned char u8;typedef unsigned int u16;/*  BYTE Registers  */sfr P0    = 0x80;sfr P1    = 0x90;sfr P2    = 0xA0;sfr P3    = 0xB0;sfr PSW   = 0xD0;sfr ACC
发表于 2020-09-09
单片机数码管时钟电路图
用STC89c52单片机,12M晶振。计时用T2定时器,16位自动重装模式  基本功能如下: 可以显示年份、月、日、时间,有闹钟功能,有倒计时功能。 上电默认显示时间,可通过按键切换显示年份、日期、闹钟、倒计时,显示一定时间后自动返回到时间显示。 在相应的显示状态下按设置键进行相应的设置。如在时间显示时按设置键可调整时间。其余类推倒计时最多可以倒数99小时59分59秒,设置完倒计时时间后进入倒数状态,闪烁显示倒数时间,中途可按键退出,倒数结束后铃响1分钟返回时间显示。 闹钟可选择开或关,闹铃响1分钟停止。电路原理图如下:制作出来的实物图如下:单片机源程序如下:#include <reg52.h>
发表于 2020-08-26
单片机数码管时钟电路图
电阻、电容和电感测试仪设计
实物图总电路图:电源模块:测量模块:显示模块:摘要近几年来,电子行业的发展速度相当快,电子行业的公司企业数目也不断增多。这个现象带来的直接结果是电子行业方面的人才需求不断增多。所以,现在大多数高校都开设与电子类相关的专业及课程,为社会培养大量的电子行业的人才。做过电路设计的工作人员或者学生大多数使用万用表来测量一些元件参数或者电路中的电压电流。然而万用表有一定的局限性,它只能测量有限种类的元器件的参数,对于电容和电感等一些电抗元件就无能为力了。所以制作一种简便的电容电感测量仪显得尤为重要,方便电路设计人员或者高校电子类专业的学生测量电路中需要用到的电容及电感的具体值。本次设计的思想是基于以上原因提出来的。该系统以STC89C52
发表于 2020-08-24
电阻、电容和电感测试仪设计
NRF24l01无线模块的stc89c52单片机程序
程序24l01无线模块  stc89c52单片机源程序如下:/*******************************************************************************************************************************************************************/#include "reg52.h"        /*包含STC单片机头文件*/#include "QX51/qx51.h" /*包含qx51
发表于 2020-08-03
NRF24l01无线模块的<font color='red'>stc89c52</font>单片机程序
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2021 EEWORLD.com.cn, Inc. All rights reserved