找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1220|回复: 8
打印 上一主题 下一主题
收起左侧

刚接触单片机,如何编写这个led控制小程序?头好大

[复制链接]
跳转到指定楼层
楼主
ID:496512 发表于 2019-3-23 05:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
现在已经会通过一或两个按键实现点亮关闭LED了,也就是改变端口高低电平状态。
然后现在想实现这么个东西,在程序里加入延时处理,具体内容如下:
按住按钮K(K1=0),3秒后,LED点亮(LED=0)5秒然后灭掉(LED=1)不再亮。任何时候一但松开K(K1=1),LED则一直是灭的(LED=1)
重点就是以上动作只有在K按住时才会执行动作,一但松开则程序复位。而且延时我也不会写。。。


头好大
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:496512 发表于 2019-3-23 05:15 | 只看该作者
51单片机
回复

使用道具 举报

板凳
ID:496512 发表于 2019-3-23 05:21 | 只看该作者
已经实现了按住开灯,松开灭灯了,只剩下那个万恶的延时程序了

#include "reg52.h"               

typedef unsigned int u16;
typedef unsigned char u8;

sbit k1=P3^4;
sbit led=P1^5;

/*******************************************************************************
* 函 数 名         : delay
* 函数功能                   : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
        while(i--);       
}
void keypros()
{
        if(k1==0)       
        {       
                delay(1000);
                if(k1==0
                {
                        delay(300000);
                        led=0
                }
                while(!k1)
                {
                        led=1;
                }
        }               
}
void main()
{       
        while(1)
        {       
                keypros();
        }               
}


回复

使用道具 举报

地板
ID:496512 发表于 2019-3-23 05:37 | 只看该作者
已经实现了,按住三秒后亮五秒后灭,只剩下一下问题了:

不能实现松开按键LED瞬间灭!!
现在是一但点亮必须要等五秒才灭

#include "reg52.h"       
#define uint unsigned int

typedef unsigned int u16;          
typedef unsigned char u8;

sbit k1=P3^4;
sbit led=P1^5;
uint i,j;
                                                                                  
void delay(u16 i)
{
        while(i--);       
}

void keypros()
{
        if(k1==0)               
        {       
                delay(1000);  
                if(k1==0)
                {
                        for(i=3000;i>0;i--)
                                for(j=110;j>0;j--);
                        led=0;         
                        for(i=5000;i>0;i--)
                                for(j=110;j>0;j--);
                        led=1;
                }
                while(!k1);         
                {
                        led=1;
                }
        }               
}

void main()
{       
        while(1)
        {       
                keypros();
        }               
}


回复

使用道具 举报

5#
ID:496512 发表于 2019-3-23 05:39 | 只看该作者
不对,刚又试了下,现在是只要按一下键,就执行
for(i=3000;i>0;i--)
                                for(j=110;j>0;j--);
                        led=0;         
                        for(i=5000;i>0;i--)
                                for(j=110;j>0;j--);
                        led=1;
回复

使用道具 举报

6#
ID:451718 发表于 2019-3-23 10:26 | 只看该作者
#include "reg52.h"        
#define uint unsigned int         

typedef unsigned int u16;         
typedef unsigned char u8;

sbit k1=P3^4;
sbit led=P1^5;
uint i,j;
                                                                                 
void delay(u16 i)
{
        while(i--);        
}

void keypros()
{
        if(k1==0)               
        {        
                delay(1000);                  //软延时,消除按键抖动
                if(k1==0)                     
                {
                        for(i=3000;i>0;i--)              
                                for(j=110;j>0;j--);
                        led=0;                       
                        for(i=5000;i>0;i--)       //这行的执行没有加判断,每次循环都会执行这个5秒延时后,再改变led的状态
                                for(j=110;j>0;j--);
                        led=1;
                }
                while(!k1);         
                {
                        led=1;
                }
        }               
}

void main()
{        
        while(1)
        {        
                keypros();
        }               
}



比较欣赏你的学习态度,敢于实践,从小实验开始,找乐趣,找动力。 你这个办法是可以简单实现你想要的功能,但是问题很多,单片机的功能远不止如此。 延时和程序结构也不是你这样弄的。 试着用定时器去实现主功能延时,慢慢实践,加油。
回复

使用道具 举报

7#
ID:213173 发表于 2019-3-23 11:28 | 只看该作者
shyydy 发表于 2019-3-23 05:39
不对,刚又试了下,现在是只要按一下键,就执行
for(i=3000;i>0;i--)
                                for(j=110;j>0;j--);

你用delay延时再怎么折腾都是枉费心机,要用定时器!给你改好了,根据晶振频率选择定时器重载值。
  1. #include "reg52.h"        
  2. //#define uint unsigned int
  3. typedef unsigned int u16;         
  4. typedef unsigned char u8;

  5. sbit k1=P3^4;
  6. sbit led=P1^5;
  7. u8  count=0;//消抖计数变量
  8. u16 num=0;        //定时计数变量
  9. bit sign=0; //启动标志

  10. /*
  11. void delay(u16 i)
  12. {
  13.         while(i--);        
  14. }
  15. */
  16. void Timer0Init()        //250微秒自动重载
  17. {
  18.         TMOD= 0x02;                //设置定时器模式
  19.         TL0 = 0x06;                //设置定时初值12.000MHz
  20.         TH0 = 0x06;                //设置定时重载值12.000MHz
  21. //        TL0 = 0x1A;                //设置定时初值11.0592MHz
  22. //        TH0 = 0x1A;                //设置定时重载值11.0592MHz
  23.         TF0 = 0;                        //清除TF0标志
  24.         TR0 = 1;                        //定时器0开始计时
  25. }

  26. void main()
  27. {        
  28.         Timer0Init();
  29.         while(1)
  30.         {        
  31.                 if(TF0==1)
  32.                 {
  33.                         TF0=0;                        //清除TF0标志
  34.                         if(k1==0)      //键按下
  35.                         {        
  36.                                 if(++count>=50 && sign==0)
  37.                                         sign=1;
  38.                         }
  39.                         else                      //键抬起
  40.                         {
  41.                                 count=0;
  42.                                 sign=0;
  43.                                 num=0;
  44.                                 led=1;
  45.                         }         
  46.                         if(sign==1)
  47.                         {
  48.                                 num++;
  49.                                 if(num>12000 && num<32000)
  50.                                         led=0;
  51.                                 else led=1;
  52.                                 if(num>32000)
  53.                                         num=32000;
  54.                         }
  55.                 }       
  56.         }               
  57. }
复制代码
回复

使用道具 举报

8#
ID:451718 发表于 2019-3-23 11:35 | 只看该作者
#include "reg52.h"        
#define uint unsigned int         

typedef unsigned int u16;         
typedef unsigned char u8;

sbit k1=P3^4;
sbit led=P1^5;
uint i,j;
                                                                                 
void delay(u16 i)
{
        while(i--);        
}

void keypros()
{
        if(k1==0)               
        {        
                delay(1000);                  //软延时,消除按键抖动
                if(k1==0)                     
                {
                        for(i=3000;i>0;i--)              
                                for(j=110;j>0;j--);
                        led=0;                       
                        for(i=5000;i>0;i--)       //这行的执行没有加判断,每次大循环都会执行这个5秒延时
                                for(j=110;j>0;j--);
                        led=1;
                }
                while(!k1);         
                {
                        led=1;
                }
        }               
}

void main()
{        
        while(1)
        {        
                keypros();
        }               
}


看起来你的c语言功底还可以,只是对51不太了解。  在小实验中找乐趣找动力,值得赞赏。  不过单片机的延时不是你这样做的,你需要再深度了解一下定时器的使用。 按键的扫描,最好也用中断来处理。
回复

使用道具 举报

9#
ID:18297 发表于 2019-3-23 12:11 | 只看该作者
  1. #include "reg52.h"        
  2. #define uint unsigned int

  3. typedef unsigned int u16;         
  4. typedef unsigned char u8;

  5. sbit k1=P3^4;
  6. sbit led=P1^5;
  7. uint i,j;      
  8. u8 time_count=0;         //定时累加计数
  9. u8 flag=0;               //3s的延时开和5s延时关闭标志
  10. u8 start_flag=0;         //开始定时的标志,0是允许定时输出,1表示已经定时输出。
  11. void delay(u16 i)        //键盘防止抖动延时标志
  12. {
  13.         while(i--);        
  14. }
  15. void time0_on()
  16. {
  17.                 TMOD=0x01;            //定时器0 16位定时模式
  18.           TH0=(65536-50000)/256; //定时器0定时时间为50000us=50ms
  19.           TL0=(65536-50000)%256; //
  20.           EA=1;                  //总中断允许
  21.           ET0=1;                                                                 //定时器0中断允许
  22.                 TR0=1;                 //启动定时器0
  23. }
  24. void led_output()   
  25. {
  26.           if(start_flag==0)      //判断是否允许输出
  27.           {       
  28.                         start_flag=1;        //start_flag=1,下次不能允许输出
  29.                         time_count=60;       //60*50ms=3000S的延时打开LED
  30.                         flag=0;              //当前是延时打开
  31.                         time0_on();          //定时器开。
  32.                 }
  33. }
  34. void led_off()             //按键释放处理程序
  35. {
  36.                 led=1;                 //LED关闭
  37.           TR0=0;                                                                 //定时器关闭
  38.           start_flag=0;          //允许输出复位
  39. }
  40. void keypros()             //按键处理程序
  41. {
  42.         if(k1==0)               
  43.         {        
  44.                 delay(1000);  //去抖动延时
  45.                 if(k1==0)
  46.                 {
  47.                        led_output();  //LED输出处理
  48.                 }               
  49.         }  
  50.         else
  51.         {
  52.                                                 led_off();               //按键释放处理程序
  53.                                           
  54.                                 }                                       
  55.                                
  56. }
  57. void t0_time(void)interrupt 1 using 0  //定时器0中断处理程序
  58. {
  59.                 TH0=(65536-50000)/256;
  60.           TL0=(65536-50000)%256;              //重装初值50000us=50ms
  61.           time_count--;                       //计数器自减
  62.           if(time_count==0)                   //计数器3s或5S到
  63.                 {
  64.                         switch(flag)                     
  65.                         {
  66.                                         case 0:                       //3S延时到
  67.                                                 flag=1;                     //切换到5S
  68.                                                 time_count=100;             //100*50ms=5s
  69.                                                 led=0;                      //led亮
  70.                                         break;
  71.                                         case 1:                       //5S延时到
  72.                                                 flag=0;                     //切换到3S
  73.                                           TR0=0;                      //延时完成关闭定时器0
  74.                                           led=1;                      //led灭
  75.                                         break;
  76.                                                
  77.                         }
  78.                 }          
  79. }
  80. void main()
  81. {        
  82.                 while(1)
  83.     {        
  84.         keypros();                       //按键处理
  85.     }               
  86. }
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表