单元训练05:独立按键的基本操作

蓝桥杯 小蜜蜂 单元训练05:独立按键的基本操作

可以正常运行的:

#include "stc15f2k60s2.h"

#define LED(x)                 \
    {                          \
        P0 = x;                \
        P2 = P2 & 0x1f | 0x80; \
        P2 &= 0x1f;            \
    }

void Timer0_Init(void) // 1毫秒@12.000MHz
{
    AUXR |= 0x80; // 定时器时钟1T模式
    TMOD &= 0xF0; // 设置定时器模式
    TL0 = 0x20;   // 设置定时初始值
    TH0 = 0xD1;   // 设置定时初始值
    TF0 = 0;      // 清除TF0标志
    TR0 = 1;      // 定时器0开始计时
    ET0 = 1;      // 使能定时器0中断
    EA = 1;
}

// 定义按键
sbit key7 = P3 ^ 0;
sbit key6 = P3 ^ 1;
sbit key5 = P3 ^ 2;
sbit key4 = P3 ^ 3;

typedef unsigned char uint8_t;
uint8_t keyStatus;     // 按键状态
uint8_t keyValue;      // 按键数值
uint8_t keyCounter;    // 按键计数
uint8_t counterEnable; // 计数器间隔启用

uint8_t ledInfo = 0xff; // 灯初始全灭

void InitCounter() // 初始化计数器
{
    keyCounter = 0;
    counterEnable = 0;
}

void KeyScan()
{
    switch (keyStatus)
    {
    case 0: // 其中一个按下
        if ((key7 == 0) || (key6 == 0) || (key5 == 0) || (key4 == 0))
        {
            keyStatus = 1;
        }
        break;
    case 1: // 判定某个按键
        if (key7 == 0)
            keyValue = 1;
        if (key6 == 0)
            keyValue = 2;
        if (key5 == 0)
            keyValue = 3;
        if (key4 == 0)
            keyValue = 4;
        keyStatus = 2;
        break;
    case 2: // 抬起按键
        if ((key7 == 1) && (key6 == 1) && (key5 == 1) && (key4 == 1))
        {
            keyValue = 255;
            keyStatus = 0;
        }
    }
}
void KeyProc()
{

    if (counterEnable) // 达到计数间隔,即消抖
    {
        KeyScan();
        if (keyValue == 1) // S7对应L1,
            ledInfo = ~1;
        else if (keyValue == 2) // S6对应L2
            ledInfo = ~2;
        else if (keyValue == 3) // S5对应L3
            ledInfo = ~4;
        else if (keyValue == 4) // S4对应L4
            ledInfo = ~8;
        else if (keyValue == 255) // 抬起按键
            ledInfo = ~0;
        LED(ledInfo);
        counterEnable = 0;
    }
}

void main()
{
    InitCounter();
    Timer0_Init();
    while (1)
    {
        KeyProc();
    }
}

void Timer0_Isr(void) interrupt 1
{
    if (keyCounter++ == 20) // 20ms为计数间隔
    {
        counterEnable = 1;
        keyCounter = 0;
    }
}

按下会有LED灯闪烁的:

#include "stc15f2k60s2.h"

#define LED(x)                 \
    {                          \
        P0 = x;                \
        P2 = P2 & 0x1f | 0x80; \
        P2 &= 0x1f;            \
    }

#define keyOn 0
#define keyOff 255

void Timer0_Init(void) // 1毫秒@12.000MHz
{
    AUXR |= 0x80; // 定时器时钟1T模式
    TMOD &= 0xF0; // 设置定时器模式
    TL0 = 0x20;   // 设置定时初始值
    TH0 = 0xD1;   // 设置定时初始值
    TF0 = 0;      // 清除TF0标志
    TR0 = 1;      // 定时器0开始计时
    ET0 = 1;      // 使能定时器0中断
    EA = 1;
}

sbit key7 = P3 ^ 0;
sbit key6 = P3 ^ 1;
sbit key5 = P3 ^ 2;
sbit key4 = P3 ^ 3;

typedef unsigned char uint8_t;
uint8_t keyStatus;
uint8_t keyValue;
uint8_t keyCounter;
uint8_t counterEnable;
uint8_t ledInfo;

void InitCounter()
{
    keyCounter = 0;
    counterEnable = 0;
}

void InitLed()
{
    LED(0xff);
}

void KeyScan()
{
    switch (keyStatus)
    {
    case 0:
        if ((key7 == 0) || (key6 == 0) || (key5 == 0) || (key4 == 0))
        {
            keyValue = keyOn;
            keyStatus = 1;
        }
        break;
    case 1:
        if (key7 == 0)
            keyValue = 1;
        if (key6 == 0)
            keyValue = 2;
        if (key5 == 0)
            keyValue = 3;
        if (key4 == 0)
            keyValue = 4;
        keyStatus = 2;
        break;
    case 2:
        if ((key7 == 1) && (key6 == 1) && (key5 == 1) && (key4 == 1))
        {
            keyValue = keyOff;
            keyStatus = 0;
        }

    default:
        keyStatus = 0;
        keyValue = keyOff;
        break;
    }
}
void KeyProc()
{
    if (counterEnable)
    {
        KeyScan();
        if ((keyValue != keyOff) && (keyValue != keyOn))
            ledInfo = ~(0x01 << (keyValue - 1));
        else
            ledInfo = 0xff;
        LED(ledInfo);
    }
    counterEnable = 0;
}

void main()
{
    InitLed();
    InitCounter();
    Timer0_Init();
    while (1)
    {
        KeyProc();
    }
}

void Timer0_Isr(void) interrupt 1
{
    if (keyCounter++ == 20) // 20ms
    {
        counterEnable = 1;
        keyCounter = 0;
    }
}

或者(也是闪烁):

#include "stc15f2k60s2.h"

#define LED(x)                 \
    {                          \
        P0 = x;                \
        P2 = P2 & 0x1f | 0x80; \
    }

#define keyOn 0
#define keyOff 255

void Timer0_Init(void) // 1毫秒@12.000MHz
{
    AUXR |= 0x80; // 定时器时钟1T模式
    TMOD &= 0xF0; // 设置定时器模式
    TL0 = 0x20;   // 设置定时初始值
    TH0 = 0xD1;   // 设置定时初始值
    TF0 = 0;      // 清除TF0标志
    TR0 = 1;      // 定时器0开始计时
    ET0 = 1;      // 使能定时器0中断
    EA = 1;
}

sbit key7 = P3 ^ 0;
sbit key6 = P3 ^ 1;
sbit key5 = P3 ^ 2;
sbit key4 = P3 ^ 3;

typedef unsigned char uint8_t;
uint8_t keyStatus;
uint8_t keyValue;
uint8_t keyCounter;
uint8_t counterEnable;

void InitCounter()
{
    keyCounter = 0;
    counterEnable = 0;
}

void KeyScan()
{
    switch (keyStatus)
    {
    case 0:
        if ((key7 == 0) || (key6 == 0) || (key5 == 0) || (key4 == 0))
        {
            keyStatus = 1;
        }
        break;
    case 1:
        if (key7 == 0)
            keyValue = 1;
        if (key6 == 0)
            keyValue = 2;
        if (key5 == 0)
            keyValue = 3;
        if (key4 == 0)
            keyValue = 4;
        keyStatus = 2;
        break;
    case 2:
        if ((key7 == 1) && (key6 == 1) && (key5 == 1) && (key4 == 1))
        {
            keyValue = keyOff;
            keyStatus = 0;
        }

    default:
        keyStatus = 0;
        keyValue = keyOff;
        break;
    }
}
void KeyProc()
{
    static uint8_t ledInfo = 0xff;
    if (counterEnable)
    {
        KeyScan();
        // switch (keyValue)
        // {
        // case keyOn:
        //     break;
        // case 1:
        //     ledInfo = ~(0x01 << (keyValue - 1));
        //     break;
        // case 2:
        //     ledInfo = ~(0x01 << (keyValue - 1));
        //     break;
        // case 3:
        //     ledInfo = ~(0x01 << (keyValue - 1));
        //     break;
        // case 4:
        //     ledInfo = ~(0x01 << (keyValue - 1));
        //     break;
        // case keyOff:
        //     ledInfo = 0xff;
        //     break;
        // default:
        //     break;
        // }
        if (keyValue != keyOff)
            ledInfo = ~(0x01 << (keyValue - 1));
        if (keyValue == keyOff)
            ledInfo = 0xff;
        LED(ledInfo);
        counterEnable = 0;
    }
}

void main()
{
    InitCounter();
    Timer0_Init();
    while (1)
    {
        KeyProc();
    }
}

void Timer0_Isr(void) interrupt 1
{
    if (keyCounter++ == 20) // 20ms
    {
        counterEnable = 1;
        keyCounter = 0;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zfdc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值