ucos的按键任务通信设计
2018-03-09 22:05
127 查看
按键任务检测是否有键按下,有键按下即发送消息邮箱。响应任务检测消息邮箱,有消息则在串口打印输出。
按键任务检测是否有键按下,有键按下即发送消息邮箱。响应任务检测消息邮箱,有消息则控制步进电机的正转,反转,停止、加速和减速。
两个按键任务一个响应任务。有键按下即发送消息邮箱。任一消息均控制响应任务运行。两个按键任务中任意一个按键按下,则发送一个消息邮箱给响应任务。若按下是数字(0-9),则在串口打印输出,并在数码管显示;如为非数字(其他),则分别对应 LED 灯的闪烁、步进电机的正转,反转,停止、加速和减速。
#include "Includes.h" /* uC/OS interface */
#include "option.h"
#include "2410lib.h"
#include "uhal.h"
/* 任务栈 */
OS_STK StackLED[STACKSIZE]= {0, }; // 任务LED任务栈
OS_STK StackSEG[STACKSIZE]= {0, }; // 任务SEG任务栈
OS_STK StackSEG1[STACKSIZE]= {0, }; // 任务SEG任务栈
/* 任务ID */
char IdLED = '1'; // 任务LED ID
char IdSEG = '2'; // 任务SEG ID
char IdSEG1 = '3'; // 任务SEG ID
/* 任务处理函数 */
void TaskLED(void *Id); // 任务LED任务处理函数
void TaskSEG(void *Id); // 任务SEG任务处理函数
void TaskSEG1(void *Id); // 任务SEG任务处理函数
/* 邮箱 */
OS_EVENT *Mbox1;
INT8U ch;
INT8U i;
/*
* 跑马灯闪烁函数,调用一次,四个跑马灯由亮变灭或者由灭变亮
*/
void User_LED_Blink( void)
{
static int led_status = 0;
led_status += 1;
if(led_status % 2 == 0)
Led_Display(0x03);
else
Led_Display(0x00);
}
void User_LED_Blink1(void)
{
static int led_status = 0;
led_status += 1;
if(led_status % 2 == 0)
Led_Display(0x0c);
else
Led_Display(0x00);
}
/*
* 数码管显示实验,由0到F依次显示
*/
void User_SEG_Blink(a)
{
static unsigned char seg_value[] = { 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e };
static int seg_status = 0;
*((unsigned char *)0x20007000) = 0x00;
*((unsigned char *)0x20006000) = seg_value[a];
seg_status += 1;
if(seg_status > 15)
seg_status = 0;
}
/*
* 任务LED任务处理函数
* 1、OSStart调用之前创建的最高优先级任务,在该函数重启动时钟节拍定时器
* 2、调用Key_GetKey函数接收键盘输入,并处理键盘输入,处理了如下键:
* '1' - LED1 ON/OFF
* '2' - LED2 ON/OFF
* '3' - LED3 ON/OFF
* '4' - LED4 ON/OFF
*/
void TaskLED(void *Id)
{
char *Msg;
INT8U err;
int benable = STEP_MOTOR_ENABLE;
int direct = STEP_MOTOR_CLOCKWISE;
uHALr_printf("Task1() called\n");
uHALr_printf("步进电机测试!\n");
uHALr_printf("1 -- 正反转 2 -- 起停\n");
uHALr_printf("UP -- 加速 DOWN -- 减速\n");
/* 初始化步进电机 */
DRVStepperInit();
for (;;) {
/* 等待邮箱中的消息,如果没有消息则挂起该任务 */
Msg = (char *)OSMboxPend(Mbox1, 0, &err);
switch( ch )
{
case 'C': // 加速
uHALr_printf("\n加速");
DRVStepperSpeedUp();
break;
case 'D': // 减速
uHALr_printf("\n减速");
DRVStepperSpeedDown();
break;
case 'F': // 正反转控制
if(direct == STEP_MOTOR_CLOCKWISE)
{
uHALr_printf("\n正转");
direct = STEP_MOTOR_ANTICLOCKWISE;
}
else
{
uHALr_printf("\n反转");
direct = STEP_MOTOR_CLOCKWISE;
}
break;
case 'E': // 使能控制
if(benable == STEP_MOTOR_DISABLE)
{
uHALr_printf("\n启动");
benable = STEP_MOTOR_ENABLE;
}
else
{
uHALr_printf("\n停止");
benable = STEP_MOTOR_DISABLE;
}
DRVStepperControl(benable);
uHALr_printf(Msg);
break;
case 'A':User_LED_Blink1();break;
case 'B':User_LED_Blink();break;
case '0': uHALr_printf(Msg);User_SEG_Blink(0);break;
case '1': uHALr_printf(Msg);User_SEG_Blink(1);break;
case '2': uHALr_printf(Msg);User_SEG_Blink(2);break;
case '3': uHALr_printf(Msg);User_SEG_Blink(3);break;
case '4': uHALr_printf(Msg);User_SEG_Blink(4);break;
case '5': uHALr_printf(Msg);User_SEG_Blink(5);break;
case '6': uHALr_printf(Msg);User_SEG_Blink(6);break;
case '7': uHALr_printf(Msg);User_SEG_Blink(7);break;
case '8': uHALr_printf(Msg);User_SEG_Blink(8);break;
case '9': uHALr_printf(Msg);User_SEG_Blink(9);break;
default:
uHALr_printf(Msg);
}
//OSTimeDly(10);
}
}
/*
* 任务SEG任务处理函数
* 1、每隔100 ticks即1000ms,闪烁数码管
*/
void TaskSEG(void *Id)
{
char Msg[100];
/* 启动时钟节拍定时器,开始多任务调度 */
ARMTargetStart();
uHALr_printf("Task1() called\n");
for (;;) {
ch = Key_GetKey();
switch( ch )
{
case '0': sprintf(Msg, "按键 %d", 0); OSMboxPost(Mbox1, Msg);break;
case '1': sprintf(Msg, "按键 %d", 1); OSMboxPost(Mbox1, Msg);break;
case '2': sprintf(Msg, "按键 %d", 2); OSMboxPost(Mbox1, Msg);break;
case '3': sprintf(Msg, "按键 %d", 3); OSMboxPost(Mbox1, Msg);break;
case '4': sprintf(Msg, "按键 %d", 4); OSMboxPost(Mbox1, Msg);break;
case '5': sprintf(Msg, "按键 %d", 5); OSMboxPost(Mbox1, Msg);break;
case '6': sprintf(Msg, "按键 %d", 6); OSMboxPost(Mbox1, Msg);break;
case '7': sprintf(Msg, "按键 %d", 7); OSMboxPost(Mbox1, Msg);break;
case '8': sprintf(Msg, "按键 %d", 8); OSMboxPost(Mbox1, Msg);break;
case '9': sprintf(Msg, "按键 %d", 9); OSMboxPost(Mbox1, Msg);break;
default: sprintf(Msg, "按键 %d", 9); OSMboxPost(Mbox1, Msg);
}
}
/* 延迟1000ms */
OSTimeDly(10);
}
}
void TaskSEG1(void *Id)
{
char Msg[1oo];
INT8U err;
uHALr_printf("Task3() called\n");
for (;;)
{
ch = Key_GetKey();
switch( ch )
{
case 'A': sprintf(Msg, "TaskSEG1 %d", A); OSMboxPost(Mbox1, Msg);break;
case 'B': sprintf(Msg, "TaskSEG1 %d", B); OSMboxPost(Mbox1, Msg);break;
case 'C': sprintf(Msg, "TaskSEG1 %d", C); OSMboxPost(Mbox1, Msg);break;
case 'D': sprintf(Msg, "TaskSEG1 %d", D); OSMboxPost(Mbox1, Msg);break;
case 'E': sprintf(Msg, "TaskSEG1 %d", E); OSMboxPost(Mbox1, Msg);break;
case 'F': sprintf(Msg, "TaskSEG1 %d", F);OSMboxPost(Mbox1, Msg);break;
default: sprintf(Msg, "TaskSEG1 %d", A); OSMboxPost(Mbox1, Msg);
}
/* 闪烁数码管 */
// User_SEG_Blink();
}
/* 延迟1000ms */
OSTimeDly(5);
}
}
/*
* Main函数.
* 1、初始化目标系统,初始化硬件定时器等,与操作系统无关
* 2、调用OSInit初始化uC/OS-II软件数据结构等,必须在打开时钟节拍中断之前调用
* 3、创建两个任务,TaskLED和TaskSEG,TaskLED的优先级为5,TaskSEG的优先级为13,TaskLED的优先级高于TaskSEG
* 4、调用OSStart启动uC/OS-II
*/
void Main(void)
{
/*
* 目标系统初始化
*/
ARMTargetInit();
/*
* uC/OS-II软件初始化
*/
OSInit();
/*
* 创建一个邮箱
*/
Mbox1 = OSMboxCreate((void *)0);
/*
* 创建两个任务,TaskLED和TaskSEG,TaskLED的优先级为5,TaskSEG的优先级为13,TaskLED的优先级高于TaskSEG
*/
OSTaskCreate(TaskLED, (void *)&IdLED, (OS_STK *)&StackLED[STACKSIZE - 1], 5);
OSTaskCreate(TaskSEG, (void *)&IdSEG, (OS_STK *)&StackSEG[STACKSIZE - 1], 13);
OSTaskCreate(TaskSEG1, (void *)&IdSEG1, (OS_STK *)&StackSEG1[STACKSIZE - 1], 14);
/*
* 启动多任务调度
*/
OSStart();
/*
* 正常情况下,永远不会执行到这里
*/
return;
}
按键任务检测是否有键按下,有键按下即发送消息邮箱。响应任务检测消息邮箱,有消息则控制步进电机的正转,反转,停止、加速和减速。
两个按键任务一个响应任务。有键按下即发送消息邮箱。任一消息均控制响应任务运行。两个按键任务中任意一个按键按下,则发送一个消息邮箱给响应任务。若按下是数字(0-9),则在串口打印输出,并在数码管显示;如为非数字(其他),则分别对应 LED 灯的闪烁、步进电机的正转,反转,停止、加速和减速。
#include "Includes.h" /* uC/OS interface */
#include "option.h"
#include "2410lib.h"
#include "uhal.h"
/* 任务栈 */
OS_STK StackLED[STACKSIZE]= {0, }; // 任务LED任务栈
OS_STK StackSEG[STACKSIZE]= {0, }; // 任务SEG任务栈
OS_STK StackSEG1[STACKSIZE]= {0, }; // 任务SEG任务栈
/* 任务ID */
char IdLED = '1'; // 任务LED ID
char IdSEG = '2'; // 任务SEG ID
char IdSEG1 = '3'; // 任务SEG ID
/* 任务处理函数 */
void TaskLED(void *Id); // 任务LED任务处理函数
void TaskSEG(void *Id); // 任务SEG任务处理函数
void TaskSEG1(void *Id); // 任务SEG任务处理函数
/* 邮箱 */
OS_EVENT *Mbox1;
INT8U ch;
INT8U i;
/*
* 跑马灯闪烁函数,调用一次,四个跑马灯由亮变灭或者由灭变亮
*/
void User_LED_Blink( void)
{
static int led_status = 0;
led_status += 1;
if(led_status % 2 == 0)
Led_Display(0x03);
else
Led_Display(0x00);
}
void User_LED_Blink1(void)
{
static int led_status = 0;
led_status += 1;
if(led_status % 2 == 0)
Led_Display(0x0c);
else
Led_Display(0x00);
}
/*
* 数码管显示实验,由0到F依次显示
*/
void User_SEG_Blink(a)
{
static unsigned char seg_value[] = { 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e };
static int seg_status = 0;
*((unsigned char *)0x20007000) = 0x00;
*((unsigned char *)0x20006000) = seg_value[a];
seg_status += 1;
if(seg_status > 15)
seg_status = 0;
}
/*
* 任务LED任务处理函数
* 1、OSStart调用之前创建的最高优先级任务,在该函数重启动时钟节拍定时器
* 2、调用Key_GetKey函数接收键盘输入,并处理键盘输入,处理了如下键:
* '1' - LED1 ON/OFF
* '2' - LED2 ON/OFF
* '3' - LED3 ON/OFF
* '4' - LED4 ON/OFF
*/
void TaskLED(void *Id)
{
char *Msg;
INT8U err;
int benable = STEP_MOTOR_ENABLE;
int direct = STEP_MOTOR_CLOCKWISE;
uHALr_printf("Task1() called\n");
uHALr_printf("步进电机测试!\n");
uHALr_printf("1 -- 正反转 2 -- 起停\n");
uHALr_printf("UP -- 加速 DOWN -- 减速\n");
/* 初始化步进电机 */
DRVStepperInit();
for (;;) {
/* 等待邮箱中的消息,如果没有消息则挂起该任务 */
Msg = (char *)OSMboxPend(Mbox1, 0, &err);
switch( ch )
{
case 'C': // 加速
uHALr_printf("\n加速");
DRVStepperSpeedUp();
break;
case 'D': // 减速
uHALr_printf("\n减速");
DRVStepperSpeedDown();
break;
case 'F': // 正反转控制
if(direct == STEP_MOTOR_CLOCKWISE)
{
uHALr_printf("\n正转");
direct = STEP_MOTOR_ANTICLOCKWISE;
}
else
{
uHALr_printf("\n反转");
direct = STEP_MOTOR_CLOCKWISE;
}
break;
case 'E': // 使能控制
if(benable == STEP_MOTOR_DISABLE)
{
uHALr_printf("\n启动");
benable = STEP_MOTOR_ENABLE;
}
else
{
uHALr_printf("\n停止");
benable = STEP_MOTOR_DISABLE;
}
DRVStepperControl(benable);
uHALr_printf(Msg);
break;
case 'A':User_LED_Blink1();break;
case 'B':User_LED_Blink();break;
case '0': uHALr_printf(Msg);User_SEG_Blink(0);break;
case '1': uHALr_printf(Msg);User_SEG_Blink(1);break;
case '2': uHALr_printf(Msg);User_SEG_Blink(2);break;
case '3': uHALr_printf(Msg);User_SEG_Blink(3);break;
case '4': uHALr_printf(Msg);User_SEG_Blink(4);break;
case '5': uHALr_printf(Msg);User_SEG_Blink(5);break;
case '6': uHALr_printf(Msg);User_SEG_Blink(6);break;
case '7': uHALr_printf(Msg);User_SEG_Blink(7);break;
case '8': uHALr_printf(Msg);User_SEG_Blink(8);break;
case '9': uHALr_printf(Msg);User_SEG_Blink(9);break;
default:
uHALr_printf(Msg);
}
//OSTimeDly(10);
}
}
/*
* 任务SEG任务处理函数
* 1、每隔100 ticks即1000ms,闪烁数码管
*/
void TaskSEG(void *Id)
{
char Msg[100];
/* 启动时钟节拍定时器,开始多任务调度 */
ARMTargetStart();
uHALr_printf("Task1() called\n");
for (;;) {
ch = Key_GetKey();
switch( ch )
{
case '0': sprintf(Msg, "按键 %d", 0); OSMboxPost(Mbox1, Msg);break;
case '1': sprintf(Msg, "按键 %d", 1); OSMboxPost(Mbox1, Msg);break;
case '2': sprintf(Msg, "按键 %d", 2); OSMboxPost(Mbox1, Msg);break;
case '3': sprintf(Msg, "按键 %d", 3); OSMboxPost(Mbox1, Msg);break;
case '4': sprintf(Msg, "按键 %d", 4); OSMboxPost(Mbox1, Msg);break;
case '5': sprintf(Msg, "按键 %d", 5); OSMboxPost(Mbox1, Msg);break;
case '6': sprintf(Msg, "按键 %d", 6); OSMboxPost(Mbox1, Msg);break;
case '7': sprintf(Msg, "按键 %d", 7); OSMboxPost(Mbox1, Msg);break;
case '8': sprintf(Msg, "按键 %d", 8); OSMboxPost(Mbox1, Msg);break;
case '9': sprintf(Msg, "按键 %d", 9); OSMboxPost(Mbox1, Msg);break;
default: sprintf(Msg, "按键 %d", 9); OSMboxPost(Mbox1, Msg);
}
}
/* 延迟1000ms */
OSTimeDly(10);
}
}
void TaskSEG1(void *Id)
{
char Msg[1oo];
INT8U err;
uHALr_printf("Task3() called\n");
for (;;)
{
ch = Key_GetKey();
switch( ch )
{
case 'A': sprintf(Msg, "TaskSEG1 %d", A); OSMboxPost(Mbox1, Msg);break;
case 'B': sprintf(Msg, "TaskSEG1 %d", B); OSMboxPost(Mbox1, Msg);break;
case 'C': sprintf(Msg, "TaskSEG1 %d", C); OSMboxPost(Mbox1, Msg);break;
case 'D': sprintf(Msg, "TaskSEG1 %d", D); OSMboxPost(Mbox1, Msg);break;
case 'E': sprintf(Msg, "TaskSEG1 %d", E); OSMboxPost(Mbox1, Msg);break;
case 'F': sprintf(Msg, "TaskSEG1 %d", F);OSMboxPost(Mbox1, Msg);break;
default: sprintf(Msg, "TaskSEG1 %d", A); OSMboxPost(Mbox1, Msg);
}
/* 闪烁数码管 */
// User_SEG_Blink();
}
/* 延迟1000ms */
OSTimeDly(5);
}
}
/*
* Main函数.
* 1、初始化目标系统,初始化硬件定时器等,与操作系统无关
* 2、调用OSInit初始化uC/OS-II软件数据结构等,必须在打开时钟节拍中断之前调用
* 3、创建两个任务,TaskLED和TaskSEG,TaskLED的优先级为5,TaskSEG的优先级为13,TaskLED的优先级高于TaskSEG
* 4、调用OSStart启动uC/OS-II
*/
void Main(void)
{
/*
* 目标系统初始化
*/
ARMTargetInit();
/*
* uC/OS-II软件初始化
*/
OSInit();
/*
* 创建一个邮箱
*/
Mbox1 = OSMboxCreate((void *)0);
/*
* 创建两个任务,TaskLED和TaskSEG,TaskLED的优先级为5,TaskSEG的优先级为13,TaskLED的优先级高于TaskSEG
*/
OSTaskCreate(TaskLED, (void *)&IdLED, (OS_STK *)&StackLED[STACKSIZE - 1], 5);
OSTaskCreate(TaskSEG, (void *)&IdSEG, (OS_STK *)&StackSEG[STACKSIZE - 1], 13);
OSTaskCreate(TaskSEG1, (void *)&IdSEG1, (OS_STK *)&StackSEG1[STACKSIZE - 1], 14);
/*
* 启动多任务调度
*/
OSStart();
/*
* 正常情况下,永远不会执行到这里
*/
return;
}
相关文章推荐
- ucos实时操作系统学习笔记——任务间通信(消息)
- UCOS-II任务间通信:邮箱
- uCOS-II任务间通信之全局变量 [转载]
- uCOS-II任务间通信之信号量
- 根据ucos任务调度方法,自己设计的一个16个任务的调度器
- uCOS-II任务间通信之信号量 [转载]
- UCOS2_STM32_任务间信号量通信(一)_应用实例描述
- UCOS-II任务设计
- uCOS-II的嵌入式串口通信模块设计
- ucos II 任务间 通信之三:信号量
- uCOS-II任务间通信之邮箱 [转载]
- ucos实时操作系统学习笔记——任务间通信(队列)
- ucos II 任务间 通信之三:信号量
- uCOS-II任务间通信之事件控制块
- ucos实时操作系统学习笔记——任务间通信(互斥锁)
- 优化设计-任务间通信-用队列而不用缓冲区
- (转载)uCOS-II的嵌入式串口通信模块设计
- uCOS-II整理之任务的同步与通信
- UCOS-II任务间通信(信号量、邮箱、消息队列)
- uCOS-II任务间通信之邮箱