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 ...
随机推荐
- win8 鼠标失灵解决办法
前几天 也没更新,却不知道突然win8 pro 失灵了,是不是ms 后台运行的也不确定,不过更新之后就可以用了. 经供参考: 更新前: 更新后: 我的主板是华硕的,有时候需要重启几次鼠标才显示出来
- linux socket 编程(C语言)
转自:http://blog.csdn.net/piaojun_pj/article/details/5920888 最近看了一些网络编程的书籍,一直以来总感觉网络编程神秘莫测,其实网络编程入门还是很 ...
- 前端调试效率低?试试这10个“Chrome开发者工具”使用技巧
摘要:今天给大家分享一些使用“Chrome开发者工具”的小技巧.包括调试,优化页面渲染速度等.希望能提升Web开发人员的工作效率. 今天给大家分享一些使用“Chrome开发者工具”的小技巧.包括调试, ...
- cocos2dx学习笔记——demo学习(一)——ActionTest
在此我会将一步步看到的小白我认为疑难和重点记下,并自解,若是在无法解答,便以红色标记出来,希望各位大神帮忙解惑. 一.onEnter()还有OnExit()是什么 因为小白在使用cocos2dx这款的 ...
- JeeWx 微信管家平台
.平台简介 Jeewx是一款开源.免费的微信管家系统(多触点管理平台),2014年荣获CSDN开发商大会第一名.采用JAVA语言,支持微信公众号.微信企业号.支付宝服务窗等多触点管理.Jeewx实现了 ...
- Sql Server REPLACE函数的使用
REPLACE用第三个表达式替换第一个字符串表达式中出现的所有第二个给定字符串表达式. 语法REPLACE ( ''string_replace1'' , ''string_replace2'' , ...
- 【Log4j2 配置详解】log4j2的资源文件具体怎么配置
可以先附上一个log4j2的资源文件详细内容,对照着看 ### set log levels ### log4j.rootLogger = INFO , C , D , E ### console # ...
- [MySQL]命令行工具和基本操作
[MySQL]命令行工具和基本操作 一 MySQL命令行工具 (查看帮助 ---help,或 -?) 1)MySQL MySQL是一个简单的SQL外壳(有GNU readline功能).它支持交互式 ...
- HDU2296 Ring(AC自动机+DP)
题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...
- BZOJ1175 : [Balkan2007]The stairways of Saharna
杨氏图表,维护若干个单调不下降队列. 每次新加入一个数时,先考虑第一个队列: 如果可以放在最后,则放在最后. 否则找到最小的可以替换的替换掉,再将替换的数放入第二个队列,以此类推. 最后$ans_i= ...