基于uC/OSII多任务的STM32报警模块
来源:互联网 发布:小说改编的网络剧2015 编辑:程序博客网 时间:2024/06/05 08:46
小作品简介
这个小作品是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
由于是该模块与其他模块有通讯,工程中添加了无线模块驱动和初始化程序。假设不需要无线模块,注释初始化代码即可。硬件模块是一些常用模块,可以在网络上查看其简介
- 元件清单
- MQ2烟雾传感器
- NRF24L01无线模块
- 火焰传感器(2个)
- 蜂鸣器
- 直流电机
- 三色LED灯
- L298N电机驱动模块
- STM32F103c8t6最小系统
- 硬件连线
- 电机信号线 -> PB0
- MQ2数字接口 -> GPIOA.1 (模数转化)
- 火焰传感器
- A:DO -> GPIOB.5
- B : DO -> GPIOB.6
- 无线模块:
- 1号引脚 -> GND
- 2号引脚 -> VCC
- 3号引脚 -> PA4
- 4号引脚 -> PB9
- 5号引脚 -> PA5
- 6号引脚 -> PA7
- 7号引脚 -> PA6
- 8号引脚 -> PA10
主要程序
#define START_TASK_PRIO 10#define START_STK_SIZE 64OS_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("%d\t",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!\r\n"); BEE = 1; MOTOR = 1; } else { printf("OK\r\n"); 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。
源码下载
点击下载
密码: w847
- 基于uC/OSII多任务的STM32报警模块
- uC/OSII的任务 学习笔记
- uC/osii移植到stm32的详细步骤
- STM32和uc/osii学习笔记之开始规划篇
- uC/OSii 的学习笔记 (1 )
- uC/OSii 的学习笔记 ( 2 )
- uc-osII实时操作
- 对uC/OSII 事件标志管理的理解
- uC/OSII 中各种事件管理方式的一般规律
- 基于stm32的简单多任务切换设计
- 基于stm32的多任务系统设计日记12.20-12.24
- 学着使用uC/OSII
- uc-osII实时操作1
- uc-osII实时操作2
- uc-osII实时操作3
- 嵌入式用户图形接口uC/GUI在uC/OSII上的嵌入
- 基于STM32的uC/OS-III 初学(1) - uC/OS-III介绍和下载
- 基于STM32的AD9854模块调试总结
- HBase超详细介绍
- ubuntu14.04安装与配置cloudmonkey
- Cocoa Touch事件处理流程--响应者链
- 9. UIActionSheet
- iOS 自定制搜索栏,保存历史搜索
- 基于uC/OSII多任务的STM32报警模块
- Where is the xm Command in XenServer
- 细说Java
- 循序渐进linux-笔记
- C语言学习笔记2-变量
- ant用法;
- linux笔记
- Leetcode 175 Combine Two Table
- qemu,kvm,qemu-kvm,xen,libvir 区别