#define BEEP 1 << 7 // P0.7控制蜂鸣器BEEP
#define HC595_CS (1 << 29) //P0.29口为74HC595的片选 #define TaskStkLengh 栈长度
int semaphore[7] = {0, 0, 0, 0, 0, 0, 0}; //定义一个信号量数组 int current_floor; int work_count = 0; int direction; int is_working;
uint8 const DISP_TAB[10] = {0XC0, 0XF9, 0XA4, 0XB0, 0X99, 0X92, 0X82, 0XF8, 0X80, 0X90}; //数码管显示数字列表 OS_STK TaskStk [TaskStkLengh]; OS_STK Task0Stk [TaskStkLengh]; OS_STK Task1Stk [TaskStkLengh]; OS_STK Task2Stk [TaskStkLengh];
OS_FLAG_GRP *direct_chan; //事件标志组 OS_EVENT *u_d; void void void void
void MSPI_Init(void) { //
PINSEL0 = (PINSEL0 & 0xFFFF00FF) | 0x00005500; // 设置管脚连接SPI PINSEL0 = (PINSEL0 & (~(0xFF << 8))) | (0x15 << 8) ;
// 设置SPI时钟分频
// CPHA = 0, 数据在SCK 的第一个时钟沿采
Elevator(void *pdata); //电梯总任务声明 Is_button_press(void *pdata); //检测按键任务声明 Direction_change(void *pdata); //电梯方向改变任务声明 Up_down(void *pdata);
//电梯向上、向下运行任务声明
//Define the Task0 stack 定义用户任务0的堆栈
64
//Define the Task0 stack length 定义用户任务0的堆
SPI_SPCCR = 0x52; 样
(1 << 4) |
SPI_SPCR = (0 << 3) |
// CPOL = 1, SCK 为低有效
}
(1 << 5) | (0 << 6) | (0 << 7);
// MSTR = 1, SPI 处于主模式
// LSBF = 0, SPI 数据传输MSB (位7)在先 // SPIE = 0, SPI 中断被禁止
uint8 MSPI_SendData(uint8 data) {
IOCLR = HC595_CS;
SPI_SPDR = data;
while( 0 == (SPI_SPSR & 0x80));
IOSET = HC595_CS; return(SPI_SPDR); }
int main(void) { }
void Elevator(void *pdata) {
pdata = pdata;
OSStart (); //启动多任务环境 return 0;
INT8U error;
OSInit ();
u_d = OSSemCreate(0); //创建向上或向下的信号量 direct_chan = OSFlagCreate(0, &error); //创建方向改变的事件标志组
OSTaskCreate (Elevator,(void *)0, &TaskStk[TaskStkLengh - 1], 2); //创建电梯总任务
// 等待SPIF置位,即等待数据发送完毕
// 片选74HC595
}
TargetInit (); //初始化目标板
PINSEL1 = 0x00000000;
IO0DIR = BEEP;
IO0DIR = ~(0x3F) << 16; //选择按键作为输入
PINSEL2 &= ~0x08; //选择管脚连接到GPIO IO1DIR = 0xFF << 18; //选择流水灯作为输出
IO1SET = 0xFF << 18; //使流水灯处于高电平,灯熄灭
MSPI_Init(); //SPI初始化
IODIR = HC595_CS; //将SPI作为输出 IO0DIR = ~(0x3F) << 16; //将p0.16~p0.21作为输入
//设置蜂鸣器为输出 //选择管脚连接到GPIO
OSTaskCreate (Is_button_press,(void *)0, &Task0Stk[TaskStkLengh - 1], 4); //创建任务 OSTaskCreate (Direction_change,(void *)0, &Task1Stk[TaskStkLengh - 1], 5); OSTaskCreate (Up_down,(void *)0, &Task2Stk[TaskStkLengh - 1], 3); while (1) { }
OSTimeDly(10); //延时
void Is_button_press(void *pdata) //判断按键任务 {
INT8U error;
pdata = pdata;
TargetInit (); //目标板初始化化 while (1) {
if ((IO0PIN & KEY1) == 0) //按下1号键 }
else if ((IO0PIN & KEY2) == 0) //按下2号键时 }
else if ((IO0PIN & KEY3) == 0) //按下3号键时 }
else if ((IO0PIN & KEY4) == 0) //按下4号键时
if (semaphore[4] != 1) if (semaphore[3] != 1) }
IO1CLR = 1 << 20; //使第三个流水灯点亮 semaphore[3] = 1; work_count++;
if (semaphore[2] != 1) }
IO1CLR = 1 << 19; //使第二个流水灯点亮 semaphore[2] = 1; work_count++;
if (semaphore[1] != 1) // }
IO1CLR = 1 << 18; //使第一个流水灯点亮 semaphore[1] = 1; //将信号量置位 work_count++; //电梯工作量增加
{ {
{ {
{ {
{ {
}
}
IO1CLR = 1 << 21; //使第四个流水灯点亮 semaphore[4] = 1; work_count++;
else if ((IO0PIN & KEY5) == 0) //按下5号键时 }
else if ((IO0PIN & KEY6) == 0) //按下6号键时
if (semaphore[5] != 1) }
IO1CLR = 1 << 22; //使第五个流水灯点亮 semaphore[5] = 1; work_count++;
{ {
{
}
if (is_working == 1) //判断电梯是否运行
if (semaphore[6] != 1) }
IO1CLR = 1 << 23; semaphore[6] = 1; work_count++;
{
{
}
else if (work_count != 0) } else
OSFlagPost(direct_chan, 0x02, OS_FLAG_SET, &error); //事件标志组发送出去 OSTimeDly(OS_TICKS_PER_SEC * 0.2);
//延时0.2秒
OSTimeDly(OS_TICKS_PER_SEC * 0.2);
//延时0.2秒
{