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()
{
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信号量实际运用—按键点灯的更多相关文章
- RT Thread 通过ENV来配置SFUD,操作SPI Flash
本实验基于正点原子stm32f4探索者板子 请移步我的RT Thread论坛帖子. https://www.rt-thread.org/qa/forum.php?mod=viewthread& ...
- STM32 + RT Thread OS 学习笔记[二]
串口通讯例程 通过上面的练习,对STM32项目开发有了一个直观印象,接下来尝试对串口RS232进行操作. 1. 目标需求: 开机打开串口1,侦听上位机(使用电脑串口测试软件)发送的信息,然后原样输 ...
- STM32 + RT Thread OS 串口通讯
1. 创建项目 a) 禁用Finsh和console b) 默认情况下,项目文件包含了finsh,它使用COM1来通讯,另外,console输出(rt_kprintf)也使用了COM1.因 ...
- STM32 + RT Thread OS 学习笔记[三]
RTGUI 据说RTGUI是多线程的,因此与RT-Thread OS的耦合度较高,有可能要访问RT-Thread的线程控制块.如果要移植到其它OS,估计难度较大.目前还处于Alpha状态,最终将会包含 ...
- STM32 + RT Thread OS 学习笔记[四]
1. 补注 a) 硬件,打通通讯通道 若学习者购买了学习板,通常可以在学习板提供的示例代码中找到LCD的相关驱动代码,基本上,这里的驱动的所有代码都可以从里面找到. 从上面的示意图可见,M ...
- RT thread 设备驱动组件之USART设备
本文以stm32f4xx平台介绍串口驱动,主要目的是:1.RTT中如何编写中断处理程序:2.如何编写RTT设备驱动接口代码:3.了解串行设备的常见处理机制.所涉及的主要源码文件有:驱动框架文件(usa ...
- RT Thread的SPI设备驱动框架的使用以及内部机制分析
注释:这是19年初的博客,写得很一般,理解不到位也不全面.19年末得空时又重新看了RTThread的SPI和GPIO,这次理解得比较深刻.有时间时再整理上传. -------------------- ...
- RT Thread SPI设备 使用
后记: 之前,我把SPI的片选在Cubemx中配置成了SPI_NSS.现在我给它改为了GPIO_OUTPUT. 同时参考了别人的类似的一个操作无线模块(采用SPI设备驱动)的例子程序(清楚了RTT的 ...
- 优先级反转实验,使用信号量实现【RT-Thread学习笔记 5】
RTOS中很经典的问题.就是在使用共享资源的时候,优先级低的进程在优先级高的进程之前执行的问题.这里模拟这种情况. 下面的实验模拟了优先级反转的情况: 先定义三个线程: //优先级反转实验 rt_se ...
随机推荐
- Redis笔记(三)Redis的数据类型
前面说过,Redis的一大特性是支持丰富的数据类型, 这为更多的应用场景提供了可能. Redis有五种数据类型,包括string,list,set,sorted set和hash,注意,Redis的数 ...
- WPF中的常用类汇总:
1.FrameworkElement: WPF中大部分的控件都可以转化成FrameworkElement,利用FrameworkElement属性获取相应的值: 2.WPF获取当前工作区域的宽度和高度 ...
- C#(去、过滤)掉字符中的换行符
本文介绍的方法需要先导入命名空间:usingSystem.Text.RegularExpressions; 字符串里所有的的换行符都去掉:textStr = Regex.Replace(textStr ...
- GitHub在Visual Studio 2015中获得TFS/VSO同等地位
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 在Visual Studio 2015中微软为GitHub提供了扩展插件,从而让GitHub ...
- WebRTC源码分析三:视频处理流程
转自:http://blog.csdn.net/neustar1/article/details/19480863 文本介绍视频的处理流程.图1中显示了两路视频会话视频信号流过程. 图1 视频流程示意 ...
- HDU2841 Visible Trees(容斥原理)
题目..大概就是有个m*n个点的矩形从(1,1)到(m,n),问从(0,0)出发直线看过去最多能看到几个点. 如果(0,0)->(x,y)和(0,0)->(x',y')两个向量平行,那后面 ...
- HDU4057 Rescue the Rabbit(AC自动机+状压DP)
题目大概是给几个DNA片段以及它们各自的权值,如果一个DNA包含某个片段那么它的价值就加上这个片段的权值,同时包含多个相同DNA片段也只加一次,问长度l的DNA可能的最大价值. 与HDU2825大同小 ...
- strerror
#include<stdio.h> #include<string.h> #include<errno.h> void main(void ) { printf(& ...
- BZOJ3648 : 寝室管理
求环套外向树上节点数不小于K的路径数. 首先树的话直接点分治+树状数组$O(n\log^2n)$搞定 环套树的话,先删掉多余的边(a,b) 然后变成了一棵树,直接点分治 然后在树上找到a到b的路径,将 ...
- BZOJ1099 : [POI2007]树Drz
首先1与i交换,n与i交换,i与i+1交换的可以$O(n)$算出. 然后只需要考虑i与x交换(1<i,x<n且|i-x|>1). 设 a[i]=h[i-1] b[i]=h[i+1] ...