RT-Thread信号量实际运用—按键点灯

上面是魔笛开发板上 LED 和按键的 IO 分布,我们通过信号量的方法来同步按键线程和LED 线程,实现当 enter 键按下后,点亮或关闭 LED 的动作。

复制代码
/**********************************************************************************************************
*
*    模块名称 : 按键检测模块
*    文件名称 : key.c
*    版    本 : V1.0
*    说    明 :
*    修改记录 :
*        版本号  日期        作者           说明
*
*        v1.0    2013-4-20   jiezhi320(UP MCU 工作室)
*
*    Copyright (C), 2012-2013,
*   淘宝店:   http://shop73275611.taobao.com
*   QQ交流群: 258043068
*
**********************************************************************************************************/
#include <rtthread.h>
#include "stm32f10x.h"
#include "key.h"


//#define KEY_DEBUG

#ifdef KEY_DEBUG
#define printf               rt_kprintf /*使用rt_kprintf来输出*/
#else
#define printf(...)                     /*无输出*/
#endif

#define KEY_RCC              RCC_APB2Periph_GPIOB
#define KEY_PORT          GPIOB
#define KEY_UP_PIN          GPIO_Pin_5
#define KEY_DOWN_PIN      GPIO_Pin_9
#define KEY_LEFT_PIN      GPIO_Pin_8
#define KEY_RIGHT_PIN      GPIO_Pin_0
#define KEY_SET_PIN          GPIO_Pin_1

#define KEY_ALL_NSET        (0x0000|KEY_UP_PIN|KEY_DOWN_PIN|KEY_LEFT_PIN|KEY_RIGHT_PIN|KEY_SET_PIN)

extern struct rt_semaphore key_sem;
static void key_scan(void);
static void rt_hw_key_init(void);

void key_thread_entry(void* parameter)
{
    rt_hw_key_init();

    while(1)
    {
        key_scan();
        rt_thread_delay(5);
    }
}

void rt_hw_key_init(void)
{

    GPIO_InitTypeDef  GPIO_InitStructure;
    /* Enable the GPIO_LED Clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);

    /* Configure the GPIO_LED pin */
    GPIO_InitStructure.GPIO_Pin = KEY_UP_PIN|KEY_DOWN_PIN|KEY_LEFT_PIN|KEY_RIGHT_PIN|KEY_SET_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(KEY_PORT, &GPIO_InitStructure);
}


void key_scan(void)
{
    static vu16 s_KeyCode;//内部检查按键使用
    static vu8 s_key_debounce_count, s_key_long_count;
    vu16    t_key_code;

    t_key_code = GPIO_ReadInputData(KEY_PORT) & KEY_ALL_NSET;

    if((t_key_code == KEY_ALL_NSET)||(t_key_code != s_KeyCode))
    {
        s_key_debounce_count = 0;    //第一次
        s_key_long_count = 0;
    }
    else
    {
        if(++s_key_debounce_count == DEBOUNCE_SHORT_TIME)
        {   //短按键
            switch(s_KeyCode)
            {
            case   KEY_ALL_NSET & (~KEY_UP_PIN):       //up


                break;

            case   KEY_ALL_NSET & (~KEY_DOWN_PIN):      //down

                break;

            case  KEY_ALL_NSET & (~KEY_LEFT_PIN):          //left

                break;

            case   KEY_ALL_NSET & (~KEY_RIGHT_PIN):    //right


                break;

            case   KEY_ALL_NSET & (~KEY_SET_PIN):     //set

                /* 释放一次信号量 */
                rt_sem_release(&key_sem);
                break;

            default:                  //其他组合不做处理
                break;

            }
#ifdef KEY_DEBUG
            printf("key %d is set\n", s_KeyCode);
#endif
        }
        if(s_key_debounce_count == DEBOUNCE_COUT_FIRST + DEBOUNCE_COUT_INTERVAL)
        {   //连按键
            s_key_debounce_count = DEBOUNCE_COUT_FIRST;
            ++s_key_long_count;
            /*
            switch(s_KeyCode)
            {
            case   KEY_ALL_NSET & (~KEY_UP_PIN):       //up


                break;

            case   KEY_ALL_NSET & (~KEY_DOWN_PIN):      //down


                break;
            }    */
        }

        if(s_key_long_count == DEBOUNCE_LONG_TIME)
        {   //长按键

            s_key_long_count = DEBOUNCE_LONG_TIME;
        }
    }
    s_KeyCode = t_key_code;                // 保存本次键值

}
复制代码

 

 

复制代码
/**********************************************************************************************************
*
*    模块名称 : LED驱动模块
*    文件名称 : led.c
*    版    本 : V1.1
*    说    明 :
*    修改记录 :
*        版本号  日期        作者                        说明
*
*        v1.0    2013-4-20   jiezhi320(UP MCU 工作室)
*
*    Copyright (C), 2012-2013,
*   淘宝店:   http://shop73275611.taobao.com
*   QQ交流群: 258043068
*
**********************************************************************************************************/
#include <rtthread.h>
#include <stm32f10x.h>
#include "led.h"

// led define

#define led1_rcc                    RCC_APB2Periph_GPIOF
#define led1_gpio                   GPIOF
#define led1_pin                    (GPIO_Pin_6)

#define led2_rcc                    RCC_APB2Periph_GPIOF
#define led2_gpio                   GPIOF
#define led2_pin                    (GPIO_Pin_7)

#define led3_rcc                    RCC_APB2Periph_GPIOF
#define led3_gpio                   GPIOF
#define led3_pin                    (GPIO_Pin_8)

#define led4_rcc                    RCC_APB2Periph_GPIOF
#define led4_gpio                   GPIOF
#define led4_pin                    (GPIO_Pin_9)


extern struct rt_semaphore key_sem;

static void rt_hw_led_init(void);

void rt_hw_led_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(led1_rcc|led2_rcc|led3_rcc|led4_rcc,ENABLE);

    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Pin   = led1_pin;
    GPIO_Init(led1_gpio, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = led2_pin;
    GPIO_Init(led2_gpio, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = led3_pin;
    GPIO_Init(led1_gpio, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = led4_pin;
    GPIO_Init(led2_gpio, &GPIO_InitStructure);

}



void led_thread_entry(void* paramete)
{
    vu8 led_state = 0;
    rt_hw_led_init();
    /* 无限循环*/
    while (1)
    {
        /* 以永久等待方式获取信号量*/
        rt_sem_take(&key_sem, RT_WAITING_FOREVER);
        /* 当得到信号量以后才有可能执行下面程序*/
        led_state ^=1;
        if (led_state!=0)
        {
            GPIO_ResetBits(led1_gpio,led1_pin|led2_pin|led3_pin|led4_pin);
            rt_kprintf(" get semaphore ok, led all on \r\n");
        }
        else
        {
            GPIO_SetBits(led1_gpio,led1_pin|led2_pin|led3_pin|led4_pin);
            rt_kprintf(" get semaphore ok, led all off \r\n");
        }
    }
}
复制代码

在开发板上实际运行程序后,我们看到,信号量确实起到了按键线程和 led 线程之间的同步作用:只有当按键按下后, led 灯才会有动作。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值