鱼C论坛

 找回密码
 立即注册
查看: 617|回复: 3

keil 的独立按键

[复制链接]
发表于 2023-10-2 23:04:06 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include <reg52.h>
typedef unsigned int u16;
typedef unsigned char u8;

//三八译码器的三个口(数码管位选)
sbit SMG_C = P2^2;
sbit SMG_B = P2^3;
sbit SMG_A = P2^4;

sbit rCLK = P3^5;
sbit SRCLK = P3^6;
sbit SER= P3^4;

//独立按键
sbit KEY1 = P3^1;
sbit KEY2 = P3^0;
sbit KEY3 = P3^2;
sbit KEY4 = P3^3;

//蜂鸣器管脚
sbit BEEP = P2^5;

u8 LED_state = 0;//用于储存LED状态

//LED点阵显示内容坐标
u8 gled_banana[8] = {0x0C,0x34,0xC9,0xF3,0x7D,0x82,0x8E,0x70};
u8 gled_love[8] = {0x38,0x44,0x82,0x41,0x41,0x82,0x44,0x38};
u8 gled_ball[8] = {0x3C,0x42,0x81,0x81,0x81,0x81,0x42,0x3C};
u8 gled_gpurd[8] = {0x00,0x06,0x69,0x91,0x91,0x69,0x06,0x00};
u8 gled_posion[8] = {0x00,0x3E,0xFB,0xF7,0xEF,0xDF,0x3E,0x00};
u8 gled_welcome[8] = {0x48,0xD7,0x60,0x07,0xBD,0xAF,0xBF,0x05};
u8 gled_pay_money[8] = {0x06,0x61,0x91,0xFF,0x91,0xFF,0x91,0x1E};
u8 gled_lie[8] = {0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
u8 gled_pay_OK[8] = {0x3C,0x42,0x3C,0x00,0xFF,0x18,0x24,0xC3};
u8 gled_no_commodity[8] = {0x12,0x12,0x94,0xF8,0xFE,0x91,0x11,0x13};

u8 gsmg_code_nopoint[10]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                                0x7f,0x6f};   
//数码管上显示的内容:0到9(无小数点)

u8 gsmg_code_ispoint[10] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
0x87,0xff,0xef};
//数码管上显示的内容:0到9(有小数点)

//数码管上的货物价格
u8 commodit_banana[8] = {0x06,0xcf,0x5b,0x6d,0x3f,0x3f,0x3f,0x3f};
u8 commodit_love[8] = {0x6d,0x5b,0x3f,0x06,0x4f,0x06,0xe6,0x3f};
u8 commodit_ball[8] = {0x7f,0xff,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f};
u8 commodit_gpurd[8] = {0x07,0x07,0x66,0x6f,0xbf,0x3f,0x3f,0x3f};
u8 commodit_posion[8] = {0x3f,0x3f,0x3f,0xbf,0x06,0x5b,0x6d,0x7f};


#define        SMG_A_DP_PORT P0
//led显示界面的标志
#define BANANA 0
#define LOVE 1
#define BALL 2
#define GPURD 3
#define POSION 4
#define WELCOME 5
#define PAY_MONEY 6
#define PAY_OK 7
#define NO_COMMODITY 8


void delay(u16 num)
{
        while(num--);
}

// 数码管显示货物价格
void smg_display(u8 commodity)
{
        u8 i = 0;
        for (i = 0; i < 8; i++)
        {
                switch (i)
                {
                        case 0: SMG_A = 1; SMG_B = 1; SMG_C = 1;break;
                        case 1: SMG_A = 1; SMG_B = 1; SMG_C = 0;break;
                        case 2: SMG_A = 1; SMG_B = 0; SMG_C = 1;break;
                        case 3: SMG_A = 1; SMG_B = 0; SMG_C = 0;break;
                        case 4: SMG_A = 0; SMG_B = 1; SMG_C = 1;break;
                        case 5: SMG_A = 0; SMG_B = 1; SMG_C = 0;break;
                        case 6: SMG_A = 0; SMG_B = 0; SMG_C = 1;break;
                        case 7: SMG_A = 0; SMG_B = 0; SMG_C = 0;break;
                }
                switch(commodity)
                {
                        case 0: SMG_A_DP_PORT = commodit_banana[i];delay(100);SMG_A_DP_PORT = 0x00;break;
                    case 1:        SMG_A_DP_PORT = commodit_love[i];delay(100);SMG_A_DP_PORT = 0x00;break;
                        case 2: SMG_A_DP_PORT = commodit_ball[i];delay(100);SMG_A_DP_PORT = 0x00;break;
                        case 3: SMG_A_DP_PORT = commodit_gpurd[i];delay(100);SMG_A_DP_PORT = 0x00;break;
                        case 4: SMG_A_DP_PORT = commodit_posion[i];delay(100);SMG_A_DP_PORT = 0x00;break;
                }       
        }
}

//把信息写入74HC595
void write_hx(u8 dat)
{
        u8 i = 0;
        for (i=0;i<8;i++)
        {
                SER = dat>>7;
                dat <<= 1;
                SRCLK = 0;
                delay(1);
                SRCLK = 1;
                delay(1);
        }
        rCLK = 0;
        delay(1);
        rCLK = 1;
        delay(1);
}

//蜂鸣器函数
void beep(u16 time_continue)
{
        BEEP = 1;
        while(time_continue--)
        {
                BEEP = !BEEP;
                delay(100);
        }
        BEEP = 0;
}       
       
                  
//点击独立按键,K1,K4会切换led点阵显示内容,K2会出现请付款的LED点阵,
//再点K2会出现货物价格,点击K3,LED点阵提示付款成功.
//拔掉插帽可从数字信息转为LED信息                       

//用于在LED上显示内容,并返回LED状态
u8 LED_display(u8 screen_display)
{
        u8 i = 0;       
        for (i=0;i<8;i++)
        {
                SMG_A_DP_PORT = gled_lie[i];
                switch (screen_display)
                {
                        case 0:        write_hx(gled_banana[i]);break;
                        case 1:        write_hx(gled_love[i]);break;
                        case 2:        write_hx(gled_ball[i]);break;
                        case 3:        write_hx(gled_gpurd[i]);break;
                        case 4:        write_hx(gled_posion[i]);break;
                        case 5:        write_hx(gled_welcome[i]);break;
                        case 6:        write_hx(gled_pay_money[i]);break;
                        case 7:        write_hx(gled_pay_OK[i]);break;
                        case 8: write_hx(gled_no_commodity[i]);break;
                }
                delay(100);
                write_hx(0x00);
        }
        return screen_display;
}
//判断按K1和K4后的LED界面呈现情况.返回按键后的LED状态
u8 K1_K4_function(u8 current_LED_state)
{
        u8 LED_state = 0;
        static u8 key = 1;
        if (key ==1 && KEY1 == 0)
        {
                delay(1000);
                if (KEY1 == 0)
                {
                        key = 0;
                        if ((current_LED_state - 1)<0){LED_state = LED_display(NO_COMMODITY);return LED_state;}
                        if ((current_LED_state - 1)>=0){LED_state = LED_display( current_LED_state - 1);return LED_state;}
                }
        if (KEY1 == 1){key = 1;}
        }
        else if (key == 1 && KEY4 == 0)
        {
                delay(1000);
                if (KEY4 == 0)
                {
                        key = 0;
                        if ((current_LED_state + 1) >= 5){LED_state = LED_display(NO_COMMODITY);return LED_state;}
                        if ((current_LED_state +1 )<5){LED_state = LED_display(current_LED_state + 1);return LED_state;}
                }
        if (KEY1 == 1){key = 1;}
        }
}
u8 double_K2 = 1;
//K2一次点击和二次点击后的结果
u8 K2_function(u8 LED_state)
{       
        static u8 key = 1;
        ;
        if ( key && KEY2 == 0 )
        {       
                delay(1000);
                key = 0;
                if (KEY2 == 0 && double_K2){LED_display(PAY_MONEY);double_K2 = 0;return PAY_MONEY;}
                else if(KEY2 == 0&&double_K2 == 0)
                        {smg_display(LED_state);
                        if (KEY3 == 0);{LED_display(PAY_OK);beep(30000);return PAY_OK;}}
        }
        if (KEY2 == 1){key = 1;}
}                       

u8 init_state = BANANA;
void main()
{       

        LED_display(WELCOME);
        delay(300000);
        LED_display(BANANA);
        delay(300000);
       
        while(1)
        {
                init_state = K1_K4_function(init_state);               
                init_state = K2_function(init_state);
                LED_display(init_state);       
                                               
        }
}
       
不知道为什么独立按键按到love时(LED点阵显示love)之后独立按键按了没用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-10-2 23:04:21 | 显示全部楼层
可能是因为在K2_function函数中,当检测到KEY2按下时,只有在double_K2为真的情况下才会执行LED_display(PAY_MONEY),而在执行完这条语句后,double_K2被设置为0,所以之后再按KEY2时,不会再执行LED_display(PAY_MONEY)了。可以将double_K2的初始值设为1,或者在执行完LED_display(PAY_MONEY)后将double_K2重新设置为1。此外,在K2_function函数中,if (KEY3 == 0);后面的分号应该去掉,否则无论KEY3是否按下,都会执行LED_display(PAY_OK)和beep(30000)。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-2 23:04:51 | 显示全部楼层
独立按键控制LED点阵显示程序问题

经过分析,代码的问题在于 K1_K4_function 和 K2_function 函数中没有正确处理键盘按下状态的问题。

具体来说,在 K1_K4_function 函数中,判断 KEY1 和 KEY4 是否按下时,应该先确认按键是按下的状态,然后再等待一段时间后再次检测按键是否松开。在等待时间内,如果按键松开,则表示这次按键操作无效,否则执行相应操作。同时,每次按键操作完成后,应当返回 LED 状态。

在 K2_function 函数中,需要实现单击和双击两种操作。对于单击事件,也需要和 K1_K4_function 一样,先确认按键是否按下,再等待一定时间后再次检测按键是否松开。如果一次确认按键按下并且没有双击标志,就进行第一次操作(显示请付款),并且设置双击标志。如果一次确认按键按下并且有双击标志,就进行第二次操作(显示货物价格),并且清除双击标志。对于双击事件,直接返回当前 LED 状态。

以上是修改后的 K1_K4_function 和 K2_function 函数的代码,供参考:

[/code]
//判断按K1和K4后的LED界面呈现情况.返回按键后的LED状态
u8 K1_K4_function(u8 current_LED_state)
{
    u8 LED_state = 0;
    static u8 key1 = 1; //用于检测 KEY1 是否按下
    static u8 key4 = 1; //用于检测 KEY4 是否按下
    if (key1 && !KEY1) //先确认 KEY1 是否按下
    {
        delay(1000); //等待一段时间
        if (!KEY1) //再次检测 KEY1 是否按下
        {
            key1 = 0; //设置 KEY1 为已按下状态
            if ((current_LED_state - 1) < 0)
                LED_state = LED_display(NO_COMMODITY);
            else
                LED_state = LED_display(current_LED_state - 1);
        }
    }
    if (KEY1)
        key1 = 1; //如果 KEY1 松开,就可以进行下一次按键操作了

    if (key4 && !KEY4) //先确认 KEY4 是否按下
    {
        delay(1000); //等待一段时间
        if (!KEY4) //再次检测 KEY4 是否按下
        {
            key4 = 0; //设置 KEY4 为已按下状态
            if ((current_LED_state + 1) >= 5)
                LED_state = LED_display(NO_COMMODITY);
            else
                LED_state = LED_display(current_LED_state + 1);
        }
    }
    if (KEY4)
        key4 = 1; //如果 KEY4 松开,就可以进行下一次按键操作了

    return LED_state;
}

u8 double_K2 = 0; //用于标志 KEY2 是否已经被双击过
//K2一

球一个最佳答案谢谢啦!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-2 23:05:35 | 显示全部楼层
根据你提供的代码,独立按键按到"love"时,按键失效的问题可能出现在以下几个地方:

1. 检查硬件接线是否正确。确保独立按键与单片机的引脚连接正确,并且按键的连接没有松动。

2. 检查按键的硬件电平。确认按键按下时,对应的引脚是否会被拉低。可以使用示波器或者数字万用表来检测按键按下时的电平变化。

3. 检查按键的软件逻辑。在代码中,函数K1_K4_function()用于判断按键的状态,并根据按键的状态来改变LED显示内容。可能需要检查函数中的逻辑是否正确,确保每次按键按下都会触发相应的操作。

请仔细检查以上几个方面,如果仍然无法解决问题,建议在相关论坛或者嵌入式开发社区寻求帮助,更多人可以帮助你进行排查。
如果问题已经解决,请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-6 01:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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