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 ...
随机推荐
- js打印html中的内容
js打印方法 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www. ...
- 【POI xlsx】使用POI对xlsx的单元格样式进行设置 / 使用POI对xlsx的字体进行设置
涉及到的样式都在代码中有说明: package com.it.poiTest; import java.io.FileNotFoundException; import java.io.FileOut ...
- android上传文件到服务器
package com.spring.sky.image.upload.network; import java.io.DataOutputStream; import java.io.File; i ...
- WPF/Silverlight HierarchicalDataTemplate 模版的使用(转)
上一篇 对Wpf/Silverlight Template 进行了总结,本篇继续上一篇,主要是介绍 HierarchicalDataTemplate 的使用方法.HierarchicalDataTem ...
- 贪心 Codeforces Round #301 (Div. 2) B. School Marks
题目传送门 /* 贪心:首先要注意,y是中位数的要求:先把其他的都设置为1,那么最多有(n-1)/2个比y小的,cnt记录比y小的个数 num1是输出的1的个数,numy是除此之外的数都为y,此时的n ...
- 【转】STL之二分查找 (Binary search in STL)
Section I正确区分不同的查找算法count,find,binary_search,lower_bound,upper_bound,equal_range 本文是对Effective STL第4 ...
- BZOJ3073 : [Pa2011]Journeys
用线段树套链表维护所有边,用set维护未访问过的点 然后BFS,每次在线段树上找边,然后在set中查询点 一条边使用之后就没有用了,所以在链表中将它删去 时间复杂度$O((n+m)\log n+m\l ...
- 【POJ】1556 The Doors(计算几何基础+spfa)
http://poj.org/problem?id=1556 首先路径的每条线段一定是端点之间的连线.证明?这是个坑...反正我是随便画了一下图然后就写了.. 然后re是什么节奏?我记得我开够了啊.. ...
- 【BZOJ】2435: [Noi2011]道路修建(树形dp)
http://www.lydsy.com/JudgeOnline/problem.php?id=2435 我怎么感觉那么水.. 坑的是,dfs会爆...好吧..用bfs.. //upd:我的智商也是醉 ...
- 【BZOJ】1041: [HAOI2008]圆上的整点(几何)
http://www.lydsy.com:808/JudgeOnline/problem.php?id=1041 所谓的神题,我不会,直接题解..看了半天看懂题解了.详见hzwer博客 这题呢,我只能 ...