51呼吸灯、51时钟

一、51呼吸灯

1.先在proteus中绘制原理图

a.51单片机最小系统包含电源电路、晶振电路、复位电路

b.使用的器件:AT89C51  、 BUTTONCAP、CAP-POL、CRYSTAL、LED-RED、LED-YELLOW、RES、RESPACK-8  

c.注意:R2为限流电阻,将它的阻值调低一点,灯会亮的更明显,但不能低于一定值,否则会烧坏单片机

2、在keil中写程序
#include <REG51.h>//此文件中定义了有关51单片机的一些特殊功能寄存器
sbit LED1=P2^0;//位地址的声明。LED1接的I/O口的引脚是P2.0;P要大写,sbit小写
void delay(unsigned int i)//延时函数
{
	unsigned int time;
	for(;i>0;i--);//i的初始值在传参过来时,就知道了
}                               
void main(void)
{
	while(1)
	{
		unsigned int t,j;
		for(t=0;t<100;t++)//每经过一次循环,小灯的亮度程度就会发生改变。
		{//暗到亮。每一次循环,通过改变灯亮和灯灭的延时时间,使灯处于不同状态(不同亮度)
			for(j=0;j<20;j++)//让每一个状态(灯所处亮度)停留久一点
			{
				LED1=0;//发光
			    delay(t);
			    LED1=1;//灯灭
			    delay(100-t);
			}
	     }
		for(t=100;t>0;t--)
	  {//灯由亮到暗
		for(j=0;j<20;j++)
		{
			LED1=0;
		    delay(t);
		    LED1=1;
		    delay(100-t);
		}
      }
	}
}

 注意:为了保证周期是恒定的,不随占空比的变化而变化,所以一般会保证亮的delay中的数值(第18行)和灭的delay中的数值(第20行)加起来是一个固定值(100),那么它的PWM的周期就是一个固定值。

 3、将程序烧录到proteus,运行得到效果

二、51时钟

1、先在proteus中绘制原理图 

2、在keil中写程序
#include<reg51.h>
//单独控制某个引脚的电平不能直接写P3^0=1,必须先定义引脚
sbit key0 = P3^0 ;		 
sbit key1 = P3^1 ;
sbit key2 = P3^2 ;
unsigned char s[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};	   //共阴数码管0~9(此处作时钟用,只需显示0~9)
unsigned char a = 0 , hour = 0, min = 0 , sec = 0 ;					   
unsigned char b = 0 , c = 0 , d = 0;//用于key函数中的条件判断
//定时器0中断服务函数
void time0() interrupt 1      // interrupt是中断特有的关键字,后面接1表示定时器中断0 
{//晶振为11.0592MHZ,则时钟周期为1/11059200,机器周期为12/11059200,给T0赋初值0x4c00,定时50ms
	TH0 = 0x4c ;   //TH0:存储定时器0的计数值的高字节(65536-50000)/256
	TL0 = 0x00 ;  //存储定时器0的计数值的低字节(65536-50000)%256
	a++;          //中断次数计数值加1
	if(a == 20)						//20 * 50 = 1000ms = 1s 即每隔1s“秒”加1
	{
		a = 0 ;
		sec = sec + 1 ;
	}
	if(sec == 60)				   //sec=60时清空,“分”加1
	{
		min = min + 1 ;
		sec = 0 ;
	} 
	if(min == 60)				  //min=60时清空,“时”加1
	{
		hour = hour + 1 ;
		min = 0 ;
	}
	if(hour == 24)				 //hour=24时清空
	{
		hour = 0 ;
	}
}
void init_t0()  //初始化    
{
	TMOD = 0x01 ;	   //TMOD控制定时器的工作模式,此刻采用TH0和TL0组成的16位定时器
	TH0 = 0x4C ;      //定时,0.05s,要经过x个机器周期的到0.05s ,计算的x=46080,16位定时器的溢出值为65536.
	TL0 = 0x00 ;	     // 先给TH0、TL0赋初值,让它们经过46080个机器周期后刚好溢出
	EA = 1 ;		   //总中断开关,相当于电闸
	ET0 = 1 ;          //使能定时器0中断	, 
	TR0 = 1 ;		   //定时器0启动控制		  
}
void delay(unsigned int n)			   //延时函数(运行空项目以达到延迟时间的效果)
{
	unsigned int i;
	while(n--)
	{
		for(i = 0 ; i < 120 ; i ++);
	}	
}
void display1()						   //在数码管上显示
{
	unsigned char t0 = 0 ,t1 = 0 , t2 = 0 , t3 = 0 , t4 = 0 , t5 = 0 ;
	t0 = hour / 10 ;		  //t0表示"时"的十位
	t1 = hour % 10 ;		  //t1表示"时"的个位
	t2 = min / 10 ;			  //t2表示"分"的十位
	t3 = min % 10 ;			  //t3表示"分"的个位
	t4 = sec / 10 ;			  //t4表示"秒"的十位
	t5 = sec % 10 ;			  //t5表示"秒"的个位
	P2 = 0x7f ;				  //P2^7低电平	 0111 1111	 控制第一个数码管 。因为是共阴的接法,所以低电平有效
	P0 = s[t0] ;			  //用来显示“时”的十位
	delay(1) ;				  //延时大约1ms
	P2 = 0xbf ;				  //P2^6低电平	 1011 1111	 控制第二个数码管 
	P0 = s[t1] ;			  //用来显示“时”的个位
	delay(1) ;
	P2 = 0xdf ;				  //P2^5低电平	 1101 1111	 控制第三个数码管 
	P0 = 0x40 ;				  //显示“—”来分割“时”与“分”
	delay(1) ;
	P2 = 0xef ;				  //P2^4低电平	 1110 1111	 控制第四个数码管 
	P0 = s[t2] ;			  //用来显示“分”的十位
	delay(1) ;
	P2 = 0xf7 ;				  //P2^3低电平	 1111 0111	 控制第五个数码管 
	P0 = s[t3] ;			  //用来显示“分”的个位
	delay(1) ;
	P2 = 0xfb ;				  //P2^2低电平	 1111 1011	 控制第六个数码管 
	P0 = 0x40 ;				  //显示“—”来分割“分”与“秒”
	delay(1) ;
	P2 = 0xfd ;				  //P2^1低电平	 1111 1101	 控制第七个数码管 
	P0 = s[t4] ;			  //用来显示“秒”的十位
	delay(1) ;
	P2 = 0xfe ;				  //P2^0低电平	 1111 1110	 控制第八个数码管 
	P0 = s[t5] ;			  //用来显示“秒”的个位
	delay(1) ;	
}
void KEY0()	 //此处KEY函数的作用:手动(按按键)改变hour、min、sec的值。开关0控制“时”加1。
{
	if(key0 == 0 && c == 0)
	{
		c = 1 ;
	}
	if(key0 == 1 && c == 1)
	{
		c = 0 ;
		hour = hour + 1 ;
	}
}
void KEY1()						 //开关1控制“分”加1
{
	if(key1 == 0 && d == 0)
	{
		d = 1 ;
	}
	if(key1 == 1 && d == 1)
	{
		d = 0 ;
		min = min + 1 ;
	}
}
void KEY2()						 //开关2控制“秒”加1
{
	if(key2 == 0 && b == 0)
	{
		b = 1 ;
	}
	if(key2 == 1 && b == 1)//按下按键后key2就等于1了,松开后key2就是0了
	{
		b = 0 ;
		sec = sec + 1 ;
	}
}
void main()		//主函数			  
{
	init_t0();
	while(1)
	{
		KEY0();
		KEY1();
		KEY2();
		display1();
    }
}

 3、烧录、运行

a.时钟周期T是最小的时间单位,是晶振频率的倒数。 

b.机器周期是单片机完成一个操作的最短时间。51单片机中,一个机器周期等于12个时钟周期。

c.此处用到了定时器中断,其程序有固定格式

感想:在通过视频学习后,我对这两个软件稍微了解了些。以我现在的水平还无法完全独立写出程序,所以上述代码都参考了很多别人的代码,在稍微理解后,做了些修改使其更满足自己的需要。多看、多练、多查资料。如果有理解错的地方请指教。现在我还有很多不足,但也算迈出了第一步。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值