51单片机定时器控制呼吸灯+数码管30秒倒数

头文件

delay.h

#define uchar unsigned char
#define uint  unsigned int
#include <intrins.h>

void delay_10us(uint i)	  //i=1,10us
{
	while(i--);	
}

void delay_ms(uint n)
{
    unsigned int i=0,j=0;
    for(i=0;i<n;i++)
        for(j=0;j<123;j++);
}

void delay_s(uint n)
{
    unsigned int i=0,j=0;
    for(i=0;i<n;i++)
        for(j=0;j<21738;j++);
}

主函数

main.c

#include <reg51.h>
#include <delay.h>
#define GPIO P0	   //数码管显示数字
sbit led=P2^0;
sbit k1=P1^0;
sbit k2=P1^1;
sbit k3=P1^2;
sbit k4=P1^3;   //按键

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;    //138位选

uchar key,keyflag,s,direct,flag;
uint speed,dutyfactor;	  //闪烁速度 ,占空比
uchar code smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00}; //显示0~F、负号‘-’¡¯
uchar wei[8]={0};    //用来存放每一位数码管数字的数组
void Timer0Init()
{
	
 TMOD|=0X01; //选择为定时器0模式,工作方式1,仅用TR0打开启动。
 TL0 = 0x38; //设置定时初值 200us
 TH0 = 0xFF; //设置定时初值
 ET0=1;//打开定时器0中断允许
 EA=1;//打开总中断
 TR0=1;//打开定时器
	
}

void keydown()	    //独立按键检测
{
   if(k1==0)
	{
	  delay_ms(10);	 //消抖
	  if(k1==0)
		{key=1;}
	  while(!k1);	//判断是否松下
	}
	if(k2==0)
	{
	  delay_ms(10);
	  if(k2==0)
		{ key=2;}
	  while(!k2);
	}
	if(k3==0)
	{
	  delay_ms(10);
	  if(k3==0)
		{ key=3;}
	  while(!k3);
	}
	if(k4==0)
	{
	  delay_ms(10);
	  if(k4==0)
		{key=4;}
	  while(!k4);
	}
	if(key==1||key==2||key==3||key==4)
	{	keyflag=1;  }			   //有按键按下标志keyflag
}  
void display()    //扫描显示动态数码管
{    								      
     LSA=0; LSB=0; LSC=0; GPIO=smgduan[wei[7]];delay_10us(50); GPIO=0x00; //消隐
     LSA=1; LSB=0; LSC=0; GPIO=smgduan[wei[6]];delay_10us(50); GPIO=0x00;
     LSA=0; LSB=1; LSC=0; GPIO=smgduan[wei[5]];delay_10us(50); GPIO=0x00; 
     LSA=1; LSB=1; LSC=0; GPIO=smgduan[wei[4]];delay_10us(50); GPIO=0x00; 
     LSA=0; LSB=0; LSC=1; GPIO=smgduan[wei[3]];delay_10us(50); GPIO=0x00; 
     LSA=1; LSB=0; LSC=1; GPIO=smgduan[wei[2]];delay_10us(50); GPIO=0x00; 
     LSA=0; LSB=1; LSC=1; GPIO=smgduan[wei[1]];delay_10us(50); GPIO=0x00; 
     LSA=1; LSB=1; LSC=1; GPIO=smgduan[wei[0]];delay_10us(50); GPIO=0x00; 
}

void main()
{
  
   Timer0Init();	   //定时器初始化
   while(1)
   {
      display();	  //数码管显示
   }
   		
}
void Timer0() interrupt 1
{
	static uint i,j;
    TL0 = 0x38;		//设置定时初值 200us
	TH0 = 0xFF;		//设置定时初值
	i++; j++;
	keydown();		//扫描按键
    if(key==1)		//k1按下 更改呼吸速度
     {					   
       speed=1;
     }
    if(key==2)		 //k2按下 更改呼吸速度
     {
       speed=10;
     }  
    
	if(i==5000)	  //i=5000 计时满1秒
	 { 
	   s++;		  //s计秒
	   i=0;
	   wei[0]=s%10;
	   wei[1]=s/10%10;
	   if(s==30)
	     {s=0;}
	 }  
	if(j >= 100) //一个PWM周期(100次*200us)
     {
      j= 0; //下一个PWM周期内,重新计数
      if(direct == 0) //根据方向判断占空比增加或减少
       { //正方向,占空比增加
         dutyfactor+=speed; //下一个PWM周期,占空比增加speed
       } else if(direct == 1) //负方向,占空比减少
       {
         dutyfactor--; //下一个PWM周期,占空比减少1
       }
     }
   //根据占空比值判断方向是否需要改变
     if(dutyfactor <= 0) //占空比减少到0
      {
       direct = 0; //正方向,占空比开始增加
      }
      else if(dutyfactor >= 100) //占空比增加到100
      {
       direct = 1; //负方向,占空比开始减少
      }

//占空比:通电时间相对于总时间所占的比例(此程序中:低电平时间相对于PWM周期所占的比例)
//一个PWM周期计数100次,占空比相当于低电平的计数周期次数。即:0~占空比:低电平,灯亮;占空比~100:高电平,灯灭
//在一个PWM周期内,根据周期计数是否小于占空比,判断LED灯的亮灭
      if(j < dutyfactor) //周期计数值<占空比
      {
        led = 0; //当前PWM周期的当前计数周期内灯亮
      }
      else
      {
        led = 1; //当前PWM周期的当前计数周期内灯灭
      }
      /* for(on=0;on<=speed;on++) //含延时呼吸灯方法
		   {  
		     off=speed-on;
	         led=0;
		     delay_10us(off);
		     led=1;
		     delay_10us(on);
	 	   }
		   for(off=0;off<=speed;off++)
		   {  
		     on=speed-off;
	         led=1;
		     delay_10us(on);
		     led=0;
		     delay_10us(off);
	      	} */	  	 	   
}
  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值