打印
[AVR单片机]

四个按键如何实现以下功能?

[复制链接]
1270|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
紫℡憶星宸|  楼主 | 2017-4-11 20:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
紫℡憶星宸|  楼主 | 2017-4-11 20:12 | 只看该作者
本帖最后由 紫℡憶星宸 于 2017-4-11 20:14 编辑

程序是自己编的,现在是功能实现不了
#define K1  (((~PINB)&0x01)==0x01)  //K1按键按下,等待输入设定值
#define K2  (((~PINB)&0x02)==0x02)  //K2按键按下,输入结束
#define K3  (((~PINB)&0X04)==0X04)  //K3按键按下,设定值加一
#define K4  (((~PINB)&0X08)==0X08)  //K4按键按下,设定值减一
#define K_up  ((!K1)|(!K2)|(!K3)|(!K4))//没有按键按下

unsigned char adc0_set = 0;
unsigned char adc2_set = 0;
unsigned char key_count = 1;//用于通道选择

float pwm1_duty = 0.0;
float pwm2_duty = 0.0;

float set1_value = 0.0;
float set2_value = 0.0;


//LCD1602显示标志
unsigned char key0_view[17]={"  CH1 L:  000R  "};
unsigned char key1_view[17]={"      I:0.000A  "};
unsigned char key2_view[17]={"  CH2 L:  000R  "};
unsigned char key3_view[17]={"      I:0.000A  "};

#define Ch1 (key_count%2==0)   
#define Ch2 (key_count%2==1)   


//键盘扫描
void key_scan(void)
{  
   unsigned char i;
   unsigned int key_num;

   i = 0;
   key_num = 0;

  if(K1)//SW1按下
  {
    delay_ms(10);//延时去抖
        if(K1)
        {
         key_count++;
         while(!K1)//等待K1按键弹起
            continue;
         while(!K2)
         {
           if(K1)
            {
             delay_ms(10);
             if(K1)   
             key_count++;
             while(!(K1))
                   continue;
            }
           if(K3)
            {
              delay_ms(10);
              if((K3)&(Ch1))
                   {
                     if(adc0_set==250) //越界保护,使设定值在0-250
                       adc0_set = 250;
                     else
                      adc0_set++;
            }
                  if((K3)&(Ch2))
           {
                     if(adc2_set==250)
                       adc2_set = 250;
                     else
                       adc2_set++;
           }
                  i = 20;
                  while((!K3)|(i>0))
                   {
                     i--;
                     delay_ms(10);//按键连续按下时,每200ms加一
                   }
             }
           if(K4)
            {
              delay_ms(10);
                     if((K4)&(Ch1))
                    {
                     if(adc0_set == 0)
                       adc0_set = 0;
             else
                       adc0_set--;
                     }
                   if((K4)&(Ch2))
            {
                       if(adc2_set == 0)
                         adc2_set = 0;
               else
                         adc2_set--;
                     }
           i = 20;
                  while((!K4)|(i>0))
                   {
                      i--;
                      delay_ms(10);
                   }
             }
       if((Ch1)&(K_up))
            {
               pwm1_duty = (float)adc0_set/250.0;//计算占空比
                   set1_value = pwm1_duty*1.0;//24V1A的设定值
               key_num = (unsigned int)(set1_value*1000);
   
               key0_view[12] = adc0_set%10+0x30;//级数显示
           key0_view[11] = adc0_set/10%10+0x30;
                   key0_view[10] = adc0_set%100+0x30;
                 
                   key1_view[12] = (unsigned char)(key_num%10)+0x30;//设定电流值显示
                   key1_view[11] = (unsigned char)(key_num/10%10)+0x30;
                   key1_view[10] = (unsigned char)(key_num/100%10)+0x30;
                   key1_view[8] =  (unsigned char)(key_num%1000)+0x30;      

               writechar(1,0,16,key0_view);//lcd1602显示数值
               writechar(2,0,16,key1_view);
                   delay_ms(500);//防止刷新频繁
             }
           if((Ch2)&(K_up))
            {
               pwm2_duty = (float)adc2_set/250.0;
                   set2_value = pwm2_duty*2.0;
                   key_num = (unsigned int)(set2_value*1000);

                   key2_view[12] = adc2_set%10+0x30;
                   key2_view[11] = adc2_set/10%10+0x30;
                   key2_view[10] = adc2_set%100+0x30;
                 
                   key3_view[12] = (unsigned char)(key_num%10)+0x30;
                   key3_view[11] = (unsigned char)(key_num/10%10)+0x30;
                   key3_view[10] = (unsigned char)(key_num/100%10)+0x30;
                   key3_view[8] =  (unsigned char)(key_num%1000)+0x30;      

               writechar(1,0,16,key2_view);//显示数值
               writechar(2,0,16,key3_view);
               delay_ms(500);
             }
           }
          key_count = 1;
        }
  }   
}

使用特权

评论回复
板凳
紫℡憶星宸|  楼主 | 2017-4-11 20:17 | 只看该作者
大神指点一二,小弟感激不尽

使用特权

评论回复
地板
xiaozhuzhuzhj| | 2017-4-12 10:02 | 只看该作者
按键扫描程序感觉有问题,K1 K2 K3 K4应该是并联的吧,怎么镶嵌在一起了

使用特权

评论回复
5
令界剑| | 2017-4-12 11:11 | 只看该作者
你这个按键函数有延时去抖,你把扫描函数放定时器中断中,都还没扫完中断又来了。

使用特权

评论回复
6
XIAO肖| | 2017-4-12 11:15 | 只看该作者
用的是哪个系列的?

使用特权

评论回复
7
huarana| | 2017-4-12 12:56 | 只看该作者

使用特权

评论回复
8
gaochy1126| | 2017-4-12 20:10 | 只看该作者
紫℡憶星宸 发表于 2017-4-11 20:12
程序是自己编的,现在是功能实现不了
#define K1  (((~PINB)&0x01)==0x01)  //K1按键按下,等待输入 ...

可以设置四个中断执行。

使用特权

评论回复
9
紫℡憶星宸|  楼主 | 2017-4-13 14:02 | 只看该作者
XIAO肖 发表于 2017-4-12 11:15
用的是哪个系列的?

atmega128

使用特权

评论回复
10
紫℡憶星宸|  楼主 | 2017-4-13 14:04 | 只看该作者
xiaozhuzhuzhj 发表于 2017-4-12 10:02
按键扫描程序感觉有问题,K1 K2 K3 K4应该是并联的吧,怎么镶嵌在一起了

功能设计的原因,,,,

使用特权

评论回复
11
紫℡憶星宸|  楼主 | 2017-4-13 14:05 | 只看该作者
令界剑 发表于 2017-4-12 11:11
你这个按键函数有延时去抖,你把扫描函数放定时器中断中,都还没扫完中断又来了。 ...

是不是应该在中断函数里面,添加cli(),和sei()???

使用特权

评论回复
12
XIAO肖| | 2017-4-13 17:24 | 只看该作者

ATMEGA128A-AU?怎么会选这个,干嘛不选硬件集成的ATSAMD系列呢?可以QQ交流下503276777

使用特权

评论回复
13
yxkt134| | 2017-4-14 11:14 | 只看该作者
还是用状态机的形式写按键代码吧,while(!(K1))的时候MCU什么也干不了

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
cuya + 1
14
紫℡憶星宸|  楼主 | 2017-4-14 19:16 | 只看该作者
yxkt134 发表于 2017-4-14 11:14
还是用状态机的形式写按键代码吧,while(!(K1))的时候MCU什么也干不了

长知识了

使用特权

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

本版积分规则

5

主题

23

帖子

1

粉丝