打印
[LOOK]

abin0415的LOOK第一帖

[复制链接]
1210|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
abin0415|  楼主 | 2012-5-22 21:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
目标要求:按键1控制LED1亮灭,当按下次数为3或3的倍数时,LED3亮0.5秒后熄灭,按键2控制LED2的亮灭,当按下次数为3或3的倍数时,LED4亮0.5秒后熄灭。两个按键相互独立计数,互补干扰。
任务分析:1.按键1和按键2分别是外部中断0和外部中断1,因此可以考虑用中断的方法控制按键。建立两个中断对象,每个对象管理一个中断。
2.定义一个全局flag_t对象,使用其两个bit位,每个中断管理一个bit位。
3.在中断对象的dsr()函数里,使用do_set_bits()函数,置位对应的bit。
4.主任务等待两个事件,负责LED1和LED2,因为这两个事件的处理不耗时间,并且为这两个事件各自设置一个计数器,计数为3或3的倍数时,发送一个事件到flag。flag还需再增加两个bit ,用于任务同步。
5.另外再建两个任务专门负责LED3和LED4的亮灭。这两个任务各自阻塞等待一个bit,然后点亮LED,延时0.5s,熄灭。
具体代码见附件
Look_cond.tar (4.99 MB)

相关帖子

沙发
hotpower| | 2012-5-22 22:28 | 只看该作者
请将主程序贴出来

使用特权

评论回复
板凳
abin0415|  楼主 | 2012-5-23 08:06 | 只看该作者
#include "Look_cond.h"
#include "utils/debug.h"
#include "numicro/sfr/gpio"

#define FLAG_KEY1 1     
#define FLAG_KEY2 1<<1
#define FLAG_LED3 1<<2
#define FLAG_LED4 1<<3

flag_t Flag(0);

// eint_t 类提供了 INT0/INT1 的接口
// 当 INT0/INT1 发生时,对象将发送相应的 int 消息到 mbox。
class eint_t : public interrupt_t {
public:
        __INLINE eint_t();

protected:
        bool isr(int vector);
        void dsr(int vector, uintptr_t count);
};

// eint 构造函数
__DEBUG//debug调试不优化便于调试
__INLINE eint_t::eint_t()
{
        using namespace sfr::gpio;
        attach(EINT0_IRQn);//绑定外部中断0
        attach(EINT1_IRQn);//绑定外部中断1
        GPIOB.IEN(0).IF_EN15(1).IF_EN14(1);//开启Key1,Key2中断
        vector_t::enable(EINT0_IRQn);//使能外部中断0即Key1中断
        vector_t::enable(EINT1_IRQn);//使能外部中断1即Key2中断
}

// eint 中断服务例程
__DEBUG//debug调试不优化便于调试
bool eint_t::isr(int vector)
{
        using namespace sfr::gpio;
        GPIOB.ISRC = GPIOB.ISRC;                        // 清中断 flag
        return true;
}

// eint 中断滞后服务例程
__DEBUG//debug调试不优化便于调试
void eint_t::dsr(int vector, uintptr_t count)
{
        using namespace sfr::gpio;
        if (vector == EINT0_IRQn)//Key2中断
        {
                Flag.do_set_bits(2);//在中断中唤醒任务2
        }
        else if (vector == EINT1_IRQn)//Key1中断
        {
                Flag.do_set_bits(1);//在中断中唤醒任务1
        }
}

eint_t eint;                                                                        // 创建 eint 对象

instance_task1_Look_cond_t task1_Look_cond(1);        // 任务实例

// 任务类 task1_Look_cond_t 的例程
__DEBUG//debug调试不优化便于调试
void task1_Look_cond_t::routine()
{
        // TODO: 在此编写 task1_Look_cond_t 例程的内容
        using namespace sfr::gpio;
        int cnt1 = 0;//按键1的计数变量
        int cnt2 = 0;//按键2的计数变量
        while (true) {
                // TODO: 在此编写 task1_Look_cond_t 例程的内容
                int flag = Flag.wait(FLAG_KEY1|FLAG_KEY2, flag_t::ANY_CONSUME);//阻塞等待Key1中断
                if (flag & FLAG_KEY1)
                {
                        GPIOA.DOUT().DOUT2 ^= 1;//LED1闪烁
                        cnt1 ++;
                        if (cnt1%3 == 0)//每按键3次,LED3 亮0.5秒钟
                        {
                                Flag.do_set_bits(FLAG_LED3);//唤醒任务2
                        }
                }
                else if (flag & FLAG_KEY2)
                {
                                GPIOA.DOUT().DOUT3 ^= 1;//LED2闪烁
                                cnt2 ++;
                                if (cnt2%3 == 0)//每按键3次,LED4 亮0.5秒钟
                                {
                                        Flag.do_set_bits(FLAG_LED4);//唤醒任务3
                                }
                }
        }
}

instance_task2_Look_cond_t task2_Look_cond(2);        // 任务实例

// 任务类 task1_Look_cond_t 的例程
__DEBUG//debug调试不优化便于调试
void task2_Look_cond_t::routine()
{
                using namespace sfr::gpio;
          while (true)
                {
                                int flag = Flag.wait(FLAG_LED3,flag_t::ANY_CONSUME);//阻塞等待LED3的标志
                          if (flag)
                                {
                                                GPIOA.DOUT().DOUT4(0);//LED3亮
                                    delay(LOOK_TICKS_PER_SEC / 2);//延时亮0.5S
                                    GPIOA.DOUT().DOUT4(1);//LED3灭
                                }
                }
}

instance_task3_Look_cond_t task3_Look_cond(3);        // 任务实例

// 任务类 task3_Look_cond_t 的例程
__DEBUG//debug调试不优化便于调试
void task3_Look_cond_t::routine()
{
        // TODO: 在此编写 task3_Look_cond_t 例程的内容
        using namespace sfr::gpio;
        while (true)
        {
                        int flag = Flag.wait(FLAG_LED4, flag_t::ANY_CONSUME);//阻塞等待LED4的标志
                        if (flag)
                        {
                                GPIOA.DOUT().DOUT5(0);//LED4亮
                                delay(LOOK_TICKS_PER_SEC / 2);//延时亮0.5S
                                GPIOA.DOUT().DOUT5(1);//LED4灭
                        }
        }
}

使用特权

评论回复
地板
hotpower| | 2012-5-23 09:45 | 只看该作者
在板子上全速运行通过否?

使用特权

评论回复
5
abin0415|  楼主 | 2012-5-23 10:25 | 只看该作者
能达到设计的效果

使用特权

评论回复
6
hotpower| | 2012-5-23 11:46 | 只看该作者
继续,look

使用特权

评论回复
7
abin0415|  楼主 | 2012-5-23 13:28 | 只看该作者
谢谢大叔支持。:)

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:细节决定成败,态度决定高度。

17

主题

2105

帖子

5

粉丝