打印
[国产单片机]

怎么让单片机按一下按键执行一个程序,再按一下马上执行另一个程序

[复制链接]
14710|23
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kilmty|  楼主 | 2013-4-23 10:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用外部中断的话要等到一个子程序执行完,才会执行下一个程序
程序如下:
void main()
{
         
           EA=1;          //全局中断开
           EX0=1;         //外部中断0开
           IT0=1;         //边沿触发
           EX1=1;         //外部中断1开
           IT1=1;         //边沿触发
        while(1)  
        {         
                    play_num(list_num);
        }
void ISR_INT1(void) interrupt 2  
{
    if(!INT1)
   {
   delay(600);//在此处可以添加去抖动程序,防止按键抖动造成错误
   if(!INT1)
   while(!INT1);//等待按键释放
     {
       list_num++;
           if(list_num==4)list_num=0;

                 
                }
   }
}  

相关帖子

沙发
zd420325| | 2013-4-24 10:47 | 只看该作者
switch(keyValue)
{
case 0:。。。
............
default :。。。
}//再不懂打PP。

使用特权

评论回复
板凳
kilmty|  楼主 | 2013-4-24 14:50 | 只看该作者
zd420325 发表于 2013-4-24 10:47
switch(keyValue)
{
case 0:。。。

我用外部中断改变keyValue(keyValue++)的值,但是每次都要等到当前case后面的程序执行完以后才能进入下一个case后面的程序,现在我case后面的程序很长,有没有办法实现,当我按键后,立即跳出当前程序,进入下一个case

使用特权

评论回复
地板
weihualong| | 2013-4-24 18:15 | 只看该作者
这就是所谓的典型的学校教学导致的使用delay,多任务系统用单任务思维去实现,很难。程序架构不对。

使用特权

评论回复
5
kilmty|  楼主 | 2013-4-24 18:30 | 只看该作者
weihualong 发表于 2013-4-24 18:15
这就是所谓的典型的学校教学导致的使用delay,多任务系统用单任务思维去实现,很难。程序架构不对。 ...

该用怎么样的架构,指点一下啦,在此谢谢!

使用特权

评论回复
6
eydj2008| | 2013-4-24 19:50 | 只看该作者
void ISR_INT1(void) interrupt 2  
{
    if(!INT1)
   {
   delay(600);//在此处可以添加去抖动程序,防止按键抖动造成错误
   if(!INT1)
   while(!INT1);//等待按键释放
     {
       list_num++;
           if(list_num==4)list_num=0;

                 
                }
   }
}

你这个中断 占用CPU太多时间

使用特权

评论回复
7
kilmty|  楼主 | 2013-4-24 20:45 | 只看该作者
eydj2008 发表于 2013-4-24 19:50
void ISR_INT1(void) interrupt 2  
{
    if(!INT1)

要实现不同的按键执行不同的子程序,该怎么做?子程序都很长,用中断不能立即跳到下一个程序

使用特权

评论回复
8
eydj2008| | 2013-4-24 20:53 | 只看该作者
谁说的 你看我的
简单的例子
u8 KEY_Func(void)                //1ms
{
   static u16 iKEY2 = 0;
   static u16 iKEY3 = 0;

   static u8 KEY1Flag = 0;
   static u8 KEY2Flag = 0;
   static u8 KEY3Flag = 0;
   static u8 KEY4Flag = 0;
   //1---------------------------------------------
   if (!KEY1)
   {
      KEY1Flag |= 0x01;      
   }
   else
   {
      if (KEY1Flag)
      {
          KEY1Flag = 0;
          KEY1_Func();
      }
   }
   //2---------------------------------------------
   if (!KEY2)
   {
      KEY2Flag |= 0x01;
      if (iKEY2 >= 50)
      {        
         KEY2Flag |= 0x02;
      }
      else
      {
         iKEY2++;
      }
      if (KEY2Flag==0x03)
      {
          KEY2_Func();
      }
   }
   else
   {
      if (KEY2Flag)
      {
          KEY2Flag = 0;
          iKEY2 = 0;
          KEY2_Func();
      }
   }
   //3---------------------------------------------
   if (!KEY3)
   {
      KEY3Flag |= 0x01;
      if (iKEY3 >= 50)
      {        
         KEY3Flag |= 0x02;
      }
      else
      {
         iKEY3++;
      }
      if (KEY3Flag==0x03)
      {
          KEY3_Func();
      }
   }
   else
   {
      if (KEY3Flag)
      {
          KEY3Flag = 0;
          iKEY3 = 0;
          KEY3_Func();
      }
   }
   //4---------------------------------------------
   if (!KEY4)
   {
      KEY4Flag |= 0x01;
   }
   else
   {
      if (KEY4Flag)
      {
          KEY4Flag = 0;
          KEY4_Func();
      }
   }

   return (KEY1Flag | KEY2Flag | KEY3Flag | KEY4Flag);
}

使用特权

评论回复
9
eydj2008| | 2013-4-24 20:54 | 只看该作者
只要不用FOR 和WHILE 还有GOTO 回去的程序 都可以用

使用特权

评论回复
10
hzvivid| | 2013-4-24 22:37 | 只看该作者
eydj2008说的很棒!

使用特权

评论回复
11
McuPlayer| | 2013-4-25 09:08 | 只看该作者
请楼主参考eydj2008的代码

避免使用Delay函数的方法,来消除抖动,要用Timer的方式
另外按键的处理,用状态机的方式来处理,也会得到简化

使用特权

评论回复
12
490911995| | 2013-4-27 00:36 | 只看该作者
KEY2 KEY3和KEY1 KEY4中间不同的那部分是什么情况呢,希望能解惑。谢谢。。

使用特权

评论回复
13
gxs64| | 2013-4-28 12:55 | 只看该作者
你这样也没错,只不过key的功能程序不能放在中断中,在中断设置标志后立马出来。特别是释放key程序最好不放在中断中。

使用特权

评论回复
14
kilmty|  楼主 | 2013-4-29 19:59 | 只看该作者
发现状态机的思想很棒,正在学习中

使用特权

评论回复
15
在路上的旁观者| | 2013-4-30 00:50 | 只看该作者
前后台程序,状态机建模

使用特权

评论回复
16
logokfu| | 2013-7-27 23:53 | 只看该作者
McuPlayer 发表于 2013-4-25 09:08  请楼主参考eydj2008的代码   避免使用Delay函数的方法,来消除抖动,要用Timer的方式

我都是用定时器做延时,可移植性好,但是最近我遇到了一个ds18b20,看了网上的程序,都是用的直接delay的方法,显然对于多任务的系统来说实时性就不能保证了,比如我还需要扫矩阵键盘,刷数码管,甚至还要做红外解码。不知道这个程序该怎么架构了。因为18b20的时序,如果用定时器来做的话会很麻烦的。

使用特权

评论回复
17
yyhao20| | 2013-7-30 11:06 | 只看该作者
**kfu 发表于 2013-7-27 23:53
我都是用定时器做延时,可移植性好,但是最近我遇到了一个ds18b20,看了网上的程序,都是用的直接delay的 ...

18b20对时序要求很严格的,还是建议用delay来做,毕竟这个delay的时间不算长,而且最好在操作18b20的时候先将中断关掉

使用特权

评论回复
18
zezy371| | 2013-7-30 11:22 | 只看该作者
中断是会影响DS18B20的时序的,如果不先关闭中断,就会返回错误的温度值

使用特权

评论回复
19
McuPlayer| | 2013-7-31 20:02 | 只看该作者
如果使用18B20,建议临时屏蔽中断,通讯完尽快打开,中断Flag可以保持,只要屏蔽中断的时间别太久就好

使用特权

评论回复
20
john_lee| | 2013-7-31 20:23 | 只看该作者
如果有未用的 UART,拿来接 1-wire (DS18B20) 是非常爽的。

使用特权

评论回复
评分
参与人数 2威望 +10 收起 理由
shujie418 + 2
McuPlayer + 8 UART做1-wire是个好主意
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:承接中小功率LED驱动器设计以及打样。PCB layout,51单片机程序开发,硬件设计

21

主题

92

帖子

2

粉丝