zoukankan      html  css  js  c++  java
  • 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
    ", 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 
    ");
            }
            else
            {
                GPIO_SetBits(led1_gpio,led1_pin|led2_pin|led3_pin|led4_pin);
                rt_kprintf(" get semaphore ok, led all off 
    ");
            }
        }
    }

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

  • 相关阅读:
    面向对象
    ArrayList 集合
    JAVA 方法
    JAVA数组
    JAVA基础2
    JAVA基础1(语法)
    JAVA基础(jdk安装和环境变量的配置)
    数据结构练习题
    多表查询
    数据约束
  • 原文地址:https://www.cnblogs.com/yygsj/p/5519212.html
Copyright © 2011-2022 走看看