基于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

0 0
原创粉丝点击