上面是魔笛开发板上 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()
{
key_scan();
rt_thread_delay();
}
} 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 = ; //第一次
s_key_long_count = ;
}
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 = ;
rt_hw_led_init();
/* 无限循环*/
while ()
{
/* 以永久等待方式获取信号量*/
rt_sem_take(&key_sem, RT_WAITING_FOREVER);
/* 当得到信号量以后才有可能执行下面程序*/
led_state ^=;
if (led_state!=)
{
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 灯才会有动作。

RT-Thread信号量实际运用—按键点灯的更多相关文章

  1. RT Thread 通过ENV来配置SFUD,操作SPI Flash

    本实验基于正点原子stm32f4探索者板子 请移步我的RT Thread论坛帖子. https://www.rt-thread.org/qa/forum.php?mod=viewthread& ...

  2. STM32 + RT Thread OS 学习笔记[二]

    串口通讯例程 通过上面的练习,对STM32项目开发有了一个直观印象,接下来尝试对串口RS232进行操作. 1.   目标需求: 开机打开串口1,侦听上位机(使用电脑串口测试软件)发送的信息,然后原样输 ...

  3. STM32 + RT Thread OS 串口通讯

    1.   创建项目 a)   禁用Finsh和console b)   默认情况下,项目文件包含了finsh,它使用COM1来通讯,另外,console输出(rt_kprintf)也使用了COM1.因 ...

  4. STM32 + RT Thread OS 学习笔记[三]

    RTGUI 据说RTGUI是多线程的,因此与RT-Thread OS的耦合度较高,有可能要访问RT-Thread的线程控制块.如果要移植到其它OS,估计难度较大.目前还处于Alpha状态,最终将会包含 ...

  5. STM32 + RT Thread OS 学习笔记[四]

    1.  补注 a)      硬件,打通通讯通道 若学习者购买了学习板,通常可以在学习板提供的示例代码中找到LCD的相关驱动代码,基本上,这里的驱动的所有代码都可以从里面找到. 从上面的示意图可见,M ...

  6. RT thread 设备驱动组件之USART设备

    本文以stm32f4xx平台介绍串口驱动,主要目的是:1.RTT中如何编写中断处理程序:2.如何编写RTT设备驱动接口代码:3.了解串行设备的常见处理机制.所涉及的主要源码文件有:驱动框架文件(usa ...

  7. RT Thread的SPI设备驱动框架的使用以及内部机制分析

    注释:这是19年初的博客,写得很一般,理解不到位也不全面.19年末得空时又重新看了RTThread的SPI和GPIO,这次理解得比较深刻.有时间时再整理上传. -------------------- ...

  8. RT Thread SPI设备 使用

    后记: 之前,我把SPI的片选在Cubemx中配置成了SPI_NSS.现在我给它改为了GPIO_OUTPUT.  同时参考了别人的类似的一个操作无线模块(采用SPI设备驱动)的例子程序(清楚了RTT的 ...

  9. 优先级反转实验,使用信号量实现【RT-Thread学习笔记 5】

    RTOS中很经典的问题.就是在使用共享资源的时候,优先级低的进程在优先级高的进程之前执行的问题.这里模拟这种情况. 下面的实验模拟了优先级反转的情况: 先定义三个线程: //优先级反转实验 rt_se ...

随机推荐

  1. UVa 11524:In-Circle(解析几何)

    Problem EIn-CircleInput: Standard Input Output: Standard Output In-circle of a triangle is the circl ...

  2. Windows 10 下ASP.NET4.0尚未在Web服务器上注册

    系统换成Win10后,打开VS2012出现如下问题: 网上查找了,大部分都是 C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319 并管理员运行aspnet_ ...

  3. Xamarin.Android开发实践(八)

    Xamarin.Android其他类型的服务 一.前言 前面我们已经学了关于服务的很多知识,但是对于真实的开发那些远远不够,通过这节我们将学习其他类型的服务,比如前台服务.IntentService和 ...

  4. Java Hour 15 以写小说的心态

    有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. 突然想到我最近一直在追的小说,作者每天都会更新两章,而且质量挺高.所以从这篇开 ...

  5. oracle 共享池( shared pool )

    Oracle共享池 Oracle共享池(Share Pool)属于SGA,由库高速缓存(library cache)和数据字典高速缓存(data dictionary cache)组成. 库高速缓存 ...

  6. jquery笔记(仅供个人参考)

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...

  7. hdu 4833 离散化+dp ****

    先离散化,然后逆着dp,求出每个点能取到的最大利益,然后看有没有钱,有钱就投 想法好复杂 #include <stdio.h> #include <string.h> #inc ...

  8. [转]notepad++各种插件

    http://www.crifan.com/files/doc/docbook/rec_soft_npp/release/htmls/npp_common_plugins.html

  9. 状态压缩 UVALive 6068 The Little Girl who Picks Mushrooms (12长春C)

    题目传送门 题意:采蘑菇.现在采了n座山,共5座山,最后要求有三个篮子的蘑菇量是1024的整数倍,丢掉后一直减1024直到不超过1024 分析:n <= 3时直接1024,否则状压枚举哪三个篮子 ...

  10. codevs 1507酒厂选址

    #include<cstdio> #include<cstdlib> using namespace std; int n; int dis[10010],a[10010],x ...