完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛扫一扫,分享给好友
|
小作品简介
这个小作品是uCOSII多任务系统的简单应用,使MCU(STM32F103)可以“同时”执行多个任务。并使用邮箱在多任务系统中通信。如果需要可以在文字末尾下载到完整的工程,其中System文件夹中3个文件由原子提供,提供了一些函数,便于编程和debug,具体可参看原子官方的教程。 (本作品由于没有电机驱动,所以用三个三极管将就,这是不规范操作,效果也一般) 本工程中创建了5个任务,并设置最多为12个任务。分别是: 1. led0_task:控制LED灯的亮灭 2. MQ2_task : 检测烟雾传感器的值 3. FC_task : 检测是否有火焰 4. Alter_task : 接受邮箱信息,决定是否分通过蜂鸣器报警,启动电风扇。 5. LIGHT_task : 控制一个三色LED 由于是该模块与其他模块有通讯,工程中添加了无线模块驱动和初始化程序。假设不需要无线模块,注释初始化代码即可。硬件模块是一些常用模块,可以在网络上查看其简介
主要程序 #define START_TASK_PRIO 10 #define START_STK_SIZE 64 OS_STK START_TASK_STK[START_STK_SIZE]; void start_task(void *pdata); 这部分定义了开始任务的堆栈大小和任务函数,其他任务同理。 OS_EVENT *msg_mq2; OS_EVENT *msg_fire; OS_EVENT *msg_light; OS_EVENT *msg_Wcolor; 这里定义了OS_EVENT类型的指针,用来创建邮箱。 int main(void) { Sys_Init(); //ÍâÉè³õʼ»¯ OSInit(); //ϵͳ³õʼ»¯ OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO); OSStart(); //ucosIIÔËÐÐ } 主函数非常简单,首先对外设进行初始化,比如配置IO口模式,初始化无线模块等,然后初始化ucos系统,创建开始任务,最后开始多任务操作系统,注意OSStart()函数必须有一个以上任务后,才可以调用。 void start_task(void *pdata) { OS_CPU_SR cpu_sr = 0; pdata = pdata; msg_mq2 = OSMboxCreate((void*)0); //´´½¨ÓÊÏä msg_fire = OSMboxCreate((void*)0); msg_light = OSMboxCreate((void*)0); msg_Wcolor = OSMboxCreate((void*)0); OS_ENTER_CRITICAL(); OSTaskCreate(led0_task, (void *)0,(OS_STK *)&LED0_TASK_STK[LED0_STK_SIZE-1], LED0_TASK_PRIO); OSTaskCreate(MQ2_task, (void *)0,(OS_STK *)&MQ2_TASK_STK[MQ2_STK_SIZE-1], MQ2_TASK_PRIO); OSTaskCreate(FC_task, (void *)0,(OS_STK *)&FC_TASK_STK[FC_STK_SIZE-1], FC_TASK_PRIO); OSTaskCreate(Alter_task,(void *)0,(OS_STK *)&Alter_TASK_STK[ALTER_STK_SIZE-1],Alter_TASK_PRIO); OSTaskCreate(LIGHT_task,(void *)0,(OS_STK *)&LIGHT_TASK_STK[LIGHT_STK_SIZE-1],LIGHT_TASK_PRIO); OSTaskSuspend(START_TASK_PRIO); OS_EXIT_CRITICAL(); } 开始函数一个OS_CPU_SR类型的变量,用来存放中断时候任务的状态,然后使用一次pdata,避免因为该指针不被使用,编译器报错或警告。然后创建4个邮箱,任务可以通过向邮箱投递信息或读取信息,来完成任务就的信息交流。接着使用宏关闭中断,确保任务正确的创建,最后开启中断。 void FC_task(void *pdata) { bool fire_alter = false; enum color_list test; // test = blue; for(;;) { if(FIRE1&&FIRE2) //判断火源 fire_alter = false; //没有火源 else fire_alter = true; OSMboxPost(msg_fire,(void *)&fire_alter); // OSMboxPost(msg_Wcolor,(void *)&test); printf("%dt",fire_alter); delay_ms(1000); } } 这一部分是发送邮箱的应用,火焰传感模块一旦检测到火焰,就会输出高电平,这个时候通过读取IO口(FIRE1通过一些宏操作,值1表示读取IO为高电平,反之为低电平)的值,判断是否有火焰,并将值赋给bool变量fire_alter。最后通过函数,将fire_alter的值发送给msq_fire邮箱。 void Alter_task(void *pdata) { bool alter = false; bool *fire = false; bool *mq2 = false; for(;;) { INT8U err; fire = (bool *)OSMboxPend(msg_fire,200,&err); //¶ÁÈ¡ÓÊÏäµÄÖµ mq2 = (bool *)OSMboxPend(msg_mq2, 200,&err); alter = *fire || *mq2; if(alter) { printf("Warning!rn"); BEE = 1; MOTOR = 1; } else { printf("OKrn"); BEE = 0; MOTOR = 0; } delay_ms(800); } } 这部分对环境异常做出处理。首先定义bool*来读取邮箱的值(读取邮箱返回值的类型是指针变量的) fire = (bool *)OSMboxPend(msg_fire,200,&err); 这段表示读取msg_fire邮箱的值,并将返回值强制转化为bool 指针,并赋值给fire。 alter = *fire || *mq2; fire或mq2指向的值有异常,alter就为真。最后延时800ms。 |
|
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
4194 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
3256 浏览 1 评论
2788 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
2221 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
15119 浏览 2 评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
3159浏览 4评论
stm32f4下spi+dma读取数据不对是什么原因导致的?
1933浏览 3评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
2103浏览 3评论
2016浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
2207浏览 3评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-11 17:21 , Processed in 0.641705 second(s), Total 74, Slave 57 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
2117