Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
[第三期 空气质量分析仪]第3周作业
发布于 2019-11-01 23:15:23 浏览:959
订阅该版
* 本帖最后由 尤一农 于 2019-11-1 23:22 编辑 * 这个星期最大的收获是:使用邮箱实现线程间的通信,使用事件集实现线程的同步。写在前面: 由于本人是小白,因此力争每个模块独立模拟测试,如文末截图所示。 一、邮箱的使用(详细代码附后) 1.关键点: struct mailbox_msg { char *tag; //数据对象标识 rt_uint32_t data; //接收数据的指针成员变量 }; 这个结构体作用强大,官方文档也有说明。 2.是静态内存池还是动态申请?看其他学员,有的是静态,有的是动态。在单个模块测试时,本人两种方法都使用。 二、事件集的使用(详细代码附后) 1.现在做法是:led定义一个事件集,主要接收传感器模块发来的事件信息;传感器顶一个事件集,接收来自按键发来的事件信息;各自创建一个读取事件的线程。 2.我这样处理,妥吗? 三、按键检测(详细代码附后) 1.按PIN管理相关文档资料介绍哦,PIN可以挂载中断,可以边沿触发、电平触发中断,但看了其他人的资料,如是开放中断则只是简单下降沿触发。 2.我一直一直一直纳闷:机械按键的抖动,不是会引起按一次,触发多次中断吗?如是:怎么实现按奇数次工作,偶数次关闭呢?请老师指点。 3.时间紧迫,干脆照搬了裸机的按键检测办法,使用switch语句,每隔20ms,读取按键状态,并适当处理——并未使用中断功能。 四、指示灯闪烁 1.按指导文档,分别实现ON、OFF、BLINK,且都带有输入参数。 2.闪烁功能独立出一个线程,避免受到事件集读取的影响(WAITING_FOREVER)。 五、温湿度的读取(详细代码附后) 1.在第二周线程的基础上,增加一个事件集,并创建一个新的线程,随时根据按键按下次数,判断是否继续读取或关闭读取 2.在原温湿度线程入口函数中,增加判断,如果打开,则每隔1s读取,并根据温度情况,是闪两下还是持续点亮(这里模拟以30度为界),发送LED相应事件信息,如果关闭则发送LED相应事件信息。 ![TIM截图20191101231343.jpg](https://oss-club.rt-thread.org/uploads/201911/01/231405u0rx2b2obys22bhx.jpg)
查看更多
5
个回答
默认排序
按发布时间排序
尤一农
2019-11-01
这家伙很懒,什么也没写!
``` #include "mylog.h" /* 异步日志结构体 */ struct mailbox_msg { char *tag; //数据对象标识 rt_uint32_t data; //接收数据的指针成员变量 }; /* 邮箱控制块 */ static rt_mailbox_t My_mb; /* mylog入口函数 */ static void mylog_entry(void *para) { struct mailbox_msg *mb_msg; while(1) { /* 从邮箱中收取邮件 */ if (rt_mb_recv(My_mb, (rt_ubase_t *)&mb_msg, RT_WAITING_FOREVER) == RT_EOK) { rt_kprintf("[%s] data is:%d\n",mb_msg->tag , mb_msg->data); } } } /*创建mylog动态线程*/ rt_int8_t mylog_init(void) { rt_thread_t mylog_th; My_mb = rt_mb_create("mbt", /* 名称是 mbt */ 128, /* 邮箱 容量*/ RT_IPC_FLAG_FIFO); /* 采用 FIFO 方式进行线程等待 */ if (RT_NULL == My_mb) { rt_kprintf("init mailbox failed.\n"); return -1; } mylog_th = rt_thread_create("mylog",mylog_entry,RT_NULL,1024, RT_THREAD_PRIORITY_MAX / 2,20); rt_thread_startup(mylog_th); return 0; } /*发送邮箱内容*/ void mylog(char * tag, rt_uint32_t data) { struct mailbox_msg *data_send; //定义结构体 data_send = (struct mailbox_msg*)rt_malloc(sizeof(data_send)); //申请内存 data_send ->tag = tag; //数据类型 data_send ->data = data; //数据大小 rt_mb_send(My_mb,(rt_ubase_t)data_send); //发送邮件 rt_free(data_send); //释放内存 } ```
尤一农
2019-11-01
这家伙很懒,什么也没写!
``` #include "led.h" #define LED0 GET_PIN(C, 0) #define LED1 GET_PIN(C, 1) #define LED2 GET_PIN(C, 2) static rt_uint8_t Flash_Flag0 = 0,Flash_Flag1 = 0;//定义led闪烁标志 struct rt_event Led_Event;//报警事件集句柄 void Led_ON(rt_uint8_t Led_Num) { switch(Led_Num) { case 0:rt_pin_write(LED0, PIN_LOW); break; case 1:rt_pin_write(LED1, PIN_LOW); break; case 2:rt_pin_write(LED2, PIN_LOW); break; default:break; } } void Led_OFF(rt_uint8_t Led_Num) { switch(Led_Num) { case 0:rt_pin_write(LED0, PIN_HIGH); break; case 1:rt_pin_write(LED1, PIN_HIGH); break; case 2:rt_pin_write(LED2, PIN_HIGH); break; default:break; } } void Led_Blink(rt_uint8_t Led_Num) { rt_uint8_t i = 0; while(i < 3) { Led_ON(Led_Num); rt_thread_mdelay(250); Led_OFF(Led_Num); rt_thread_mdelay(250); i ++; } } /*创建事件线程,考虑到RT_WAITING_FOREVER,避免闪烁受影响,将闪烁功能独立出来*/ static void Event_Entry(void *param) { rt_uint32_t event_msg; while(1) { if(rt_event_recv(&Led_Event,(EVENT_TEMP_HUMI_ON|EVENT_TEMP_HUMI_OFF|EVENT_TEMP_HUMI_ALERT| EVENT_ADC_ON|EVENT_ADC_OFF|EVENT_ADC_ALERT),RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,RT_WAITING_FOREVER,&event_msg) == RT_EOK) { if(event_msg & EVENT_TEMP_HUMI_ON) { Flash_Flag0 = 0; Led_ON(0); } if(event_msg & EVENT_TEMP_HUMI_OFF) { Flash_Flag0 = 0; Led_OFF(0); } if(event_msg & EVENT_TEMP_HUMI_ALERT) { Flash_Flag0 = 1; } if(event_msg & EVENT_ADC_ON) { Flash_Flag1 = 0; Led_ON(1); } if(event_msg & EVENT_ADC_OFF) { Flash_Flag1 = 0; Led_OFF(1); } if(event_msg & EVENT_ADC_ALERT) { Flash_Flag1 = 1; } } } } /*创建led闪烁线程 独立出来*/ static void Flash_Entry(void *param) { rt_uint32_t Flash0_Cnt = 0,Flash1_Cnt = 0;//闪烁2次后熄灭 while(1) { if(Flash_Flag0) { if(rt_pin_read(LED0)) { rt_pin_write(LED0,PIN_LOW); } else { rt_pin_write(LED0,PIN_HIGH); } Flash0_Cnt ++; if(Flash0_Cnt >= 2) { Flash0_Cnt = 0; Flash_Flag0 = 0; rt_pin_write(LED0,PIN_HIGH); } } if(Flash_Flag1) { if(rt_pin_read(LED1)) { rt_pin_write(LED1,PIN_LOW); } else { rt_pin_write(LED1,PIN_HIGH); } Flash1_Cnt ++; if(Flash1_Cnt >= 2) { Flash1_Cnt = 0; Flash_Flag1 = 0; rt_pin_write(LED1,PIN_HIGH); } } rt_thread_delay(200); } } /*Led相关线程初始化*/ void Led_Init(void) { rt_err_t result; rt_thread_t event_th; rt_thread_t led_th; result = rt_event_init(&Led_Event, "event", RT_IPC_FLAG_FIFO);//初始化事件集 if (result != RT_EOK) { rt_kprintf("init event failed.\n"); return ; } rt_pin_mode(LED0, PIN_MODE_OUTPUT); rt_pin_mode(LED1, PIN_MODE_OUTPUT); rt_pin_write(LED0, PIN_HIGH); rt_pin_write(LED1, PIN_HIGH); event_th = rt_thread_create("Event_th",Event_Entry,RT_NULL,1024, RT_THREAD_PRIORITY_MAX / 2,20); rt_thread_startup(event_th); led_th = rt_thread_create("Flash_th",Flash_Entry,RT_NULL,1024, RT_THREAD_PRIORITY_MAX / 2,20); rt_thread_startup(led_th); } /*led线程事件集的发送——由相应的传感器模块调用*/ void led_note(rt_uint32_t opt) { switch(opt) { case EVENT_TEMP_HUMI_ON: rt_event_send(&Led_Event, EVENT_TEMP_HUMI_ON);break; case EVENT_TEMP_HUMI_OFF: rt_event_send(&Led_Event, EVENT_TEMP_HUMI_OFF);break; case EVENT_TEMP_HUMI_ALERT: rt_event_send(&Led_Event, EVENT_TEMP_HUMI_ALERT);break; case EVENT_ADC_ON: rt_event_send(&Led_Event, EVENT_ADC_ON);break; case EVENT_ADC_OFF: rt_event_send(&Led_Event, EVENT_ADC_OFF);break; case EVENT_ADC_ALERT: rt_event_send(&Led_Event, EVENT_ADC_ALERT);break; } } ```
尤一农
2019-11-01
这家伙很懒,什么也没写!
``` #include "key.h" #define KEY0 GET_PIN(C, 8) #define KEY1 GET_PIN(C, 9) static void Key_Mode(void) { /* 按键0引脚为输入模式 */ rt_pin_mode(KEY0, PIN_MODE_INPUT_PULLUP); rt_pin_mode(KEY1, PIN_MODE_INPUT_PULLUP); } static void Key0_Entry(void *para) { static rt_uint8_t Key_Status = 0; static rt_uint8_t Key_Cnt = 0; while(1) { switch(Key_Status) { case 0: if(rt_pin_read(KEY0) == PIN_LOW) { Key_Status ++; } break; case 1: if(rt_pin_read(KEY0) == PIN_LOW) { Key_Status ++; if(Key_Cnt == 0) { Key_Cnt = 1; DHT11_Status(1); } else { Key_Cnt = 0; DHT11_Status(0); } } else { Key_Status = 0; } break; case 2: if(rt_pin_read(KEY0)) { Key_Status = 0; } break; default:break; } rt_thread_delay(20); } } static void Key1_Entry(void *para) { static rt_uint8_t Key_Status = 0; static rt_uint8_t Key_Cnt = 0; while(1) { switch(Key_Status) { case 0: if(rt_pin_read(KEY1) == PIN_LOW) { Key_Status ++; } break; case 1: if(rt_pin_read(KEY1) == PIN_LOW) { Key_Status ++; if(Key_Cnt == 0) { Key_Cnt = 1; led_note(EVENT_ADC_ON); } else { Key_Cnt = 0; led_note(EVENT_ADC_OFF); } } else { Key_Status = 0; } break; case 2: if(rt_pin_read(KEY1)) { Key_Status = 0; } break; default:break; } rt_thread_delay(20); } } /*按键相关线程初始化*/ void Key_Init(void) { rt_thread_t key0_th; rt_thread_t key1_th; Key_Mode(); key0_th = rt_thread_create("key0_th",Key0_Entry,RT_NULL,512, RT_THREAD_PRIORITY_MAX / 2 + 2,20); rt_thread_startup(key0_th); key1_th = rt_thread_create("key1_th",Key1_Entry,RT_NULL,512, RT_THREAD_PRIORITY_MAX / 2 + 2,20); rt_thread_startup(key1_th); } ```
尤一农
2019-11-01
这家伙很懒,什么也没写!
``` #include "temp_humi_th.h" struct rt_event DHT11_Event;//温湿度事件集 static rt_uint32_t event_msg;//存放接收到的事件 /* Modify this pin according to the actual wiring situation */ #define DHT11_DATA_PIN GET_PIN(B, 9) static void dht11_event_entry(void *para) { rt_err_t result; result = rt_event_init(&DHT11_Event, "DHT11_event", RT_IPC_FLAG_FIFO);//初始化事件集 if (result != RT_EOK) { rt_kprintf("init DHT11_event failed.\n"); return ; } while(1) { rt_event_recv(&DHT11_Event,(EVENT_TEMP_HUMI_ON|EVENT_TEMP_HUMI_OFF|EVENT_TEMP_HUMI_ALERT),RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,RT_WAITING_FOREVER,&event_msg); } } static void read_temp_entry(void *parameter) { rt_device_t dev = RT_NULL; struct rt_sensor_data sensor_data; rt_size_t res; rt_uint8_t get_data_freq = 1; /* 1Hz */ struct rt_sensor_config cfg; cfg.intf.user_data = (void *)DHT11_DATA_PIN; rt_hw_dht11_init("dht11", &cfg); dev = rt_device_find("temp_dht11"); if (dev == RT_NULL) { return; } if (rt_device_open(dev, RT_DEVICE_FLAG_RDWR) != RT_EOK) { rt_kprintf("open device failed!\n"); return; } rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)(&get_data_freq)); while (1) { if(event_msg & EVENT_TEMP_HUMI_ON) { led_note(EVENT_TEMP_HUMI_ALERT);//led闪烁 res = rt_device_read(dev, 0, &sensor_data, 1); if (res != 1) { rt_kprintf("read data failed! result is %d\n", res); rt_device_close(dev); return; } else { if (sensor_data.data.temp >= 0) { uint8_t temp = (sensor_data.data.temp & 0xffff) >> 0; // get temp uint8_t humi = (sensor_data.data.temp & 0xffff0000) >> 16; // get humi //rt_kprintf("temp:%d, humi:%d\n" ,temp, humi); mylog("Temp ", temp); mylog("Humi ", humi); //温度判断 if(temp >= 30) { led_note(EVENT_TEMP_HUMI_ON); } } } } else { led_note(EVENT_TEMP_HUMI_OFF); } rt_thread_delay(1000); } } void dht11_read_Init(void) { rt_thread_t dht11_thread; rt_thread_t event_thread; dht11_thread = rt_thread_create("dht_tem", read_temp_entry, RT_NULL, 1024, RT_THREAD_PRIORITY_MAX / 2, 20); if (dht11_thread != RT_NULL) { rt_thread_startup(dht11_thread); } else { rt_kprintf("rt_thread_startup failed!\r\n"); } event_thread = rt_thread_create("dht11_event", dht11_event_entry, RT_NULL, 1024, RT_THREAD_PRIORITY_MAX / 2 + 5, 20); if (event_thread != RT_NULL) { rt_thread_startup(event_thread); } else { rt_kprintf("rt_thread_startup failed!\r\n"); } } void DHT11_Status(rt_uint32_t Switch_Flag) { if(Switch_Flag == 0) { rt_event_send(&DHT11_Event, EVENT_TEMP_HUMI_OFF); } else { rt_event_send(&DHT11_Event, EVENT_TEMP_HUMI_ON); } } ```
fc55726298
2019-11-02
这家伙很懒,什么也没写!
你用全局变量调通了??
撰写答案
登录
注册新账号
关注者
0
被浏览
959
关于作者
尤一农
这家伙很懒,什么也没写!
提问
3
回答
4
被采纳
0
关注TA
发私信
相关问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
【24嵌入式设计大赛】基于RT-Thread星火一号的智慧家居系统
2
RT-Thread EtherKit开源以太网硬件正式发布
3
如何在master上的BSP中添加配置yml文件
4
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
5
RT-Thread 发布 EtherKit开源以太网硬件!
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
MicroPython
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
15
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
5
次点赞
RTT_逍遥
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部