打印

求一个C语言的算法

[复制链接]
2564|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ylsiw|  楼主 | 2010-7-19 13:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
有64个输入按钮,64个输出灯,输入按钮按一下,输出灯亮,在灯亮的情形下,连按两下输入按钮(1.5S内),输出灯灭。
求C的算法,单片机是COTEX-M3的核

相关帖子

沙发
466576266| | 2010-7-19 13:42 | 只看该作者
这个有算法吗?

使用特权

评论回复
板凳
seabada| | 2010-7-19 14:01 | 只看该作者
没做过这么多的按键,帮你顶下

使用特权

评论回复
地板
ylsiw|  楼主 | 2010-7-19 14:39 | 只看该作者
自己顶下

使用特权

评论回复
5
hob| | 2010-7-19 15:13 | 只看该作者
常规8*8按键扫描及指示灯驱动,具体的代码还是自己写吧。C语言的程序与什么处理器有关吗?

使用特权

评论回复
6
ylsiw|  楼主 | 2010-7-19 15:50 | 只看该作者
与常规稍有不同,主要是灯亮之后,按两下灯灭

使用特权

评论回复
7
ylsiw|  楼主 | 2010-7-20 14:14 | 只看该作者
自己再顶下

使用特权

评论回复
8
acute1110| | 2010-7-20 14:16 | 只看该作者
自己顶也蛮辛苦的,我劝还是自己想吧

使用特权

评论回复
9
欧阳青云| | 2010-7-20 14:45 | 只看该作者
提供一个按钮实现的思路,不知道对不:
if(flag==1)        //有键按下标志位
{
        if(灯灭)
        {
                灯亮;
        }
        else
        {
                if(count_key==1&&count_time<=count_15s)/*count_15s是1.5s的中断次数*/
                {
                        灯灭;
                        count_key=0;
                        count_time=0; //中断计数
                }
                else
                count_key++;        //键按下的次数
        }
}

使用特权

评论回复
10
ylsiw|  楼主 | 2010-7-21 10:02 | 只看该作者
LS 是介绍一个按键的方法
有没有不用FOR循环64次就能解决的算法呢

使用特权

评论回复
11
欧阳青云| | 2010-7-23 14:05 | 只看该作者
/*以下是64个按键时的参考,单按钮时我已经测试过了可以,但这个没测试过。不过中断中有一个64次的for循环,想不出更好的了。顺便提下,上次的那个单个程序有错。你想进行单按钮测试时只要把以下程序中的那些数组变成单个变量再写个按键扫描程序就可以测试了。*/
#define uchar unsigned char
#define uint unsigned int
#define count_15s 150 //由中断时间决定
uchar state_led[64]={0};//用于保存64盏灯的状态
uchar count_time[64]={0};//用于保存64个中断计数的个数
uchar count_key[64]={0};//用于保存64个按键按下的次数
key_scan() //按键扫描函数
{
       .........
       return(键号);//有键按下时返回键号1 2 3 4...64,没键按下时返回0
}
main()
{
       uchar k=0;
       EA=1;
       ET0=1;
       TR0=1;
       TMOD=0x11;
       TH0=-10000/256;     //定时10ms
       TL0=-10000%256;
       while(1)
       {
               k=key_scan();
               if(k!=0) //有键按下
               {
                      if(state_led[k]==1)    //灯灭
                      {
                              state_led[k]=0;    //灯亮
                              count_time[k]=0;
                              count_key[k]=0;
                      }
                      else
                     {
                             if(count_key[k]==0)
                             {
                                   count_key[k]=1;
                                   count_time[k]=0; //中断计数
                             }
                             else if(count_time<=count_15s)/*count_15s是1.5s的中断次数*/
                            {
                                  state_led[k]=1;
                                  count_key[k]=0;
                                  count_time[k]=0; //中断计数
                            }
                            else
                           {
                                  count_key[k]=1;  //键按下的次数保持不变
                                  count_time[k]=0; //中断计数
                           }
                     }
                     k=0;
                }
         }
}
void timer0() interrupt 1
{
       TH0=-10000/256;
       TL0=-10000%256;
       for(k=64;k>0;k--)
       count_time[k]=(count_time[k]>150)?151:count_time[k]+1;
}


}

使用特权

评论回复
12
ylsiw|  楼主 | 2010-7-27 10:02 | 只看该作者
谢谢楼上,我也贴一个我的算法,和你的大同小异

使用特权

评论回复
13
ylsiw|  楼主 | 2010-7-27 10:09 | 只看该作者
#define TOTAL_FLOOR_MAX     64      //最大数为64
//DisTractor
INT8U   DisTractorFlag      = 0U;               
INT8U   DisTractorTimer[TOTAL_FLOOR_MAX] = {0};     
INT8U   DisTractorCnt[TOTAL_FLOOR_MAX]   = {0};   
INT8U   DisTractorToMB[8]            = {0};      
/*********************************************************************************************************
** Function name:           ManageDisTractorCnt()
** Descriptions:            
** input parameters:        无  
** output parameters:       无
** Returned value:          无
** Created By:              siw
** Created date:           2010.07.22
********************************************************************************************************/
void ManageDisTractorCnt(void)
{
    INT8U   index = 0U;
   
    for(index = 0; index < TOTAL_FLOOR_MAX; index++)
    {
        if(GetBitFlrButRe(index) == TRUE )      //按钮信号上升沿
        {
            DisTractorCnt[index]++;
            if (DisTractorCnt[index] == 1)      //第一次按下
            {
                continue;
            }
            
            if (DisTractorCnt[index] == 2)      //第二次按下
            {
                DisTractorTimer[index] = DIS_TRACTOR_TIME;  //定时器重载值              
            }

            if (DisTractorTimer[index] == 0)    //定时器到期
            {
                DisTractorCnt[index] = 0;       //重置计数器
                continue;
            }
            
            if (DisTractorCnt[index] == 3)      //第三次按下
            {
                SetBitDisTractorToMB(index);    //设置按键对应的信号
                DisTractorTimer[index] = 0;     //清除定时器值
                DisTractorCnt[index] = 0;       //清除计数值
                //DisTractorFlag = 1;             //置位误选信号标志位
            }   
        }
    }
   
    return;
}

使用特权

评论回复
14
ylsiw|  楼主 | 2010-7-27 10:17 | 只看该作者
/*********************************************************************************************************
** Function name:           UpdataButtonCallIn()
** Descriptions:            更新输入按钮值
** input parameters:        无  
** output parameters:       无
** Returned value:          无
** Created By:              siw
** Created date:           2010.07.20
********************************************************************************************************/
void UpdataButtonCallIn(void)
{
    INT8U index;
   
    //更新输入按钮当前值
    for(index = 0; index < CALL_SIZE; index++)
    {
        inButtonCur[index] = inFloorBitArr[0][index];
    }

    //更新输入按钮上升沿值
    for(index = 0; index < CALL_SIZE; index++)
    {
        inButtonRe[index] = inButtonLast[index] ^ inButtonCur[index]; //异或
        inButtonRe[index] &= inButtonCur[index]; //与当前状态
    }

    //更新输入按钮下降沿值
    for(index = 0; index < CALL_SIZE; index++)
    {
        inButtonFe[index] = inButtonLast[index] ^ inButtonCur[index]; //异或
        inButtonFe[index] &= inButtonLast[index];       //与上一状态
    }

    //更新输入按钮传给主机值 本信号在CAN通讯中清零
    for(index = 0; index < CALL_SIZE; index++)
    {
        inputInsideCall[index] |= inButtonRe[index];    //相或
    }

    //更新输入按钮上一状态值
    for(index = 0; index < CALL_SIZE; index++)
    {
        inButtonLast[index] = inButtonCur[index];
    }
   
    return;  
}

使用特权

评论回复
15
ylsiw|  楼主 | 2010-7-27 10:50 | 只看该作者
/*********************************************************************************************************
** Function name:           SetBitDisTractorToMB()
** Descriptions:            置位按键信号
** input parameters:        position  
** output parameters:       无
** Returned value:          无
** Created By:              siw
** Created date:           2010.07.22
********************************************************************************************************/
void SetBitDisTractorToMB(INT8U position)
{
    SetBit(position, DisTractorToMB);

    return;   
}

/*********************************************************************************************************
** Function name:           SetBit()
** Descriptions:            根据position设置位值
** input parameters:        无  
** output parameters:       无
** Returned value:          无
** Created By:              siw
** Created date:           2010.07.22
********************************************************************************************************/
void SetBit(INT8U position, INT8U *group)
{   
    group[position >> 3] |= (BIT0 << (position & 0x07));
    //除以8 找到行, 左移 0 ~ 7位找到列
   
    return;   
}

使用特权

评论回复
16
ylsiw|  楼主 | 2010-7-27 10:56 | 只看该作者
#define CALL_SIZE        10

/*********************************************************************************************************
** Function name:           UpdataButtonCallOut()
** Descriptions:            更新输出按钮灯状态
** input parameters:        无  
** output parameters:       无
** Returned value:          无
** Created By:              siw
** Created date:           2010.07.20
********************************************************************************************************/
void UpdataButtonCallOut(void)
{
    INT8U index;
   
    for(index = 0; index < CALL_SIZE; index++)
    {
        curInsideCall[index] |= inputInsideCall[index]; // 与输入状态相或,点亮灯

        if(DisTractorFlag == 1)
        {           
                 curInsideCall[index] &= (~DisTractorOUT[index]);//熄灭信号灯            
        }  
    }
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:http://blog.csdn.net/ylsiw

0

主题

82

帖子

1

粉丝