本帖最后由 hotpower 于 2011-6-19 01:24 编辑
在第二帖基础上,用事件标志代替全局变量,增加蜂鸣器任务,完成该例程练习,望各位高手不吝赐教!
LOOK实现四个小任务:
① task_led_t: 助学板上四个LED小灯轮流点亮,有两种显示模式,方式1为LED1--->LED2--->LED3--->LED4--->LED1循环,方式2为LED4--->LED3--->LED2--->LED1--->LED4循环,初始化为方式2;
② task_key_t: 助学板上KEY2通过查询的方式判断按下调整LED的循环方式;
③ 继承于interrupt_t的中断抽象类Key_t: 助学板上KEY1设置为下降沿中断,中断滞后服务函数内置位蜂鸣器鸣叫事件标志;
④ task_beep_t: 助学板上蜂鸣器响3声,该任务由KEY1同步。
初始化设置:时钟配置为 XTL12M_EN: 外部 4~24MHz 晶振使能
GPA2~5 GPB10 配置为输出模式
GPB14~15 配置为输入模式
关于flag_t:
ANY是wait()事件标志的集合中,任何一个事件到达都可以唤醒任务,相当于“或”运算;
ALL是wait()事件标志的集合中,所有事件全部到达时才能唤醒任务,相当于“与”运算;
当期待的事件标志只有一位时,无所谓ANY,ALL。
KEEP表示到达的事件标志,在唤醒了等待的任务后,该事件不消失(可以继续唤醒其它任务);
COSUME表示到达的事件标志,在唤醒了等待的任务后,该事件消失。
源程序:
led.h
#include "look_config.h"
#include <look.h>
#include <instantiate>
// 任务类 task_led_t 的定义
class task_led_t : public task_t {
public:
task_led_t() __OPT_ATTR__; // 构造函数
protected:
void routine(); // 任务例程
};
// 任务类 task_led_t 的构造函数
__OPT_INLINE__ task_led_t::task_led_t()
{
// TODO: 在此初始化 task_led_t 的类成员
}
// 任务类 task_key_t 的定义
class task_key_t : public task_t {
public:
task_key_t() __OPT_ATTR__; // 构造函数
int8_t key_read() __OPT_ATTR__;
protected:
void routine(); // 任务例程
};
// 任务类 task_key_t 的构造函数
__OPT_INLINE__ task_key_t::task_key_t()
{
// TODO: 在此初始化 task_led_t 的类成员
}
// 任务类 task_beep_t 的定义
class task_beep_t : public task_t {
public:
task_beep_t() __OPT_ATTR__; // 构造函数
protected:
void routine(); // 任务例程
};
// 任务类 task_key_t 的构造函数
__OPT_INLINE__ task_beep_t::task_beep_t()
{
// TODO: 在此初始化 task_led_t 的类成员
}
extern instantiate::task<task_led_t, LOOK_STACK_SIZE> task_led;
extern instantiate::task<task_key_t, LOOK_STACK_SIZE> task_key;
extern instantiate::task<task_beep_t, LOOK_STACK_SIZE> task_beep;
led.cpp
#include "NUC1xx.h"
#include "NUC1xxM051Seriescfg.h"
#include "led.h"
flag_t Flag(0); //位0为LED闪烁模式 位1为蜂鸣器任务同步标志
class Key_t : public interrupt_t { //创建继承于interrupt_t的中断抽象类
public:
Key_t() __OPT_ATTR__; //构造函数
protected:
bool isr(int vector); //中断服务例程
void dsr(int vector, uintptr_t count); //中断滞后服务例程
};
// Key_t 构造函数
inline Key_t::Key_t()
{
attach(EINT1_IRQn); //连接外部中断1
GPIOBs.IEN.Bits.Bit15 = 1; //GB15 使能下降沿或低电平中断
GPIOBs.IMD.Bits.Pin15 = 0; //GB15 中断模式为边沿触发中断
vector_t::enable(EINT1_IRQn); //使能外部中断1
}
// Key_t 中断服务例程
bool Key_t::isr(int vector)
{
GPIOBs.ISRC.Regs = GPIOBs.ISRC.Regs; // 清中断 flag
return true; //返回true 表示需要调度器调度本对象的 dsr() 例程,进行后续处理。
}
// Key1_t 中断滞后服务例程
void Key_t::dsr(int vector, uintptr_t count)
{
if (vector == EINT1_IRQn)
{
Flag.do_set_bits(0b010);;
}
}
Key_t Key; // 创建Key对象
// 任务类 task_led_t 的例程
void task_led_t::routine()
{
// TODO: 在此编写 task_led_t 例程的内容
GPIOAs.DMASK.Regs = ~0b111100;
GPIOAs.DOUT.Regs = ~0b100;
while (true)
{
// TODO: 在此编写 task_led_t 例程的内容
uint32_t data = GPIOAs.DOUT.Regs & 0b111100;
int flag = Flag.peek();//Flag.wait(0b01, flag_t::ANY_KEEP);
if (flag)
{
data <<= 1;
data += data >> 4;
}
else
{
data >>= 1;
data += data << 4;
}
GPIOAs.DOUT.Regs = data;
delay(LOOK_TICKS_PER_SEC);
}
}
// 任务类 task_key_t 的例程
void task_key_t::routine()
{
// TODO: 在此编写 task_led_t 例程的内容
while (true)
{
// TODO: 在此编写 task_led_t 例程的内容
if (key_read())
{
int ** = Flag.peek();
if (**&0b01)
Flag.mask_bits(~0b01); //清除事件标志 位0
else
Flag.set_bits(0b01); //置位事件标志 位0
}
delay(LOOK_TICKS_PER_SEC/10);
}
}
// 任务类 task_key_t 的成员函数
__OPT_INLINE__ int8_t task_key_t::key_read()
{
uint32_t Key_Tmp = TRUE;
static uint32_t Key_Record = TRUE; //按键记录
Key_Tmp = GPIOBs.PIN.Bits.Pin14;
if(Key_Tmp==TRUE) //无有效按键按下
{
Key_Record = TRUE; //清除按键记录
return FALSE; //程序退出
}
if(Key_Record!=Key_Tmp) //为新按键
{
Key_Record=Key_Tmp; //保存本次结果
delay(LOOK_TICKS_PER_SEC/100); //延时去抖动
Key_Tmp = GPIOBs.PIN.Bits.Pin14;
if(Key_Tmp==Key_Record)
return TRUE;
}
return FALSE;
}
// 任务类 task_beep_t 的例程
void task_beep_t::routine()
{
// TODO: 在此编写 task_led_t 例程的内容
GPIOBs.DOUT.Bits.Pin10 = 0;//蜂鸣器不响
while (true)
{
// TODO: 在此编写 task_led_t 例程的内容
int flag = Flag.wait(0b010, flag_t::ANY_CONSUME);
if (flag)
{
for (uint32_t i = 0; i < 6; i ++)
{ //蜂鸣器响三次
GPIOBs.DOUT.Bits.Pin10 ^= 1; //蜂鸣器响PB10=1,不响PB10=0
delay(LOOK_TICKS_PER_SEC ); //断续间隔
}
}
}
}
#ifdef LOOK_SCHEDULING_PRIORITY
instantiate::task<task_key_t, LOOK_STACK_SIZE> task_key(0);
instantiate::task<task_beep_t, LOOK_STACK_SIZE> task_beep(1);
instantiate::task<task_led_t, LOOK_STACK_SIZE> task_led(2);
#else
instantiate::task<task_key_t, LOOK_STACK_SIZE> task_key;
instantiate::task<task_beep_t, LOOK_STACK_SIZE> task_beep;
instantiate::task<task_led_t, LOOK_STACK_SIZE> task_led;
#endif
|