嵌入式软件设计第6次实验报告
学号:140201225 姓名:刘曦洋
组别:第1组 实验地点:D19
一、实验目的:
1、了解UCOS操作系统任务调度原理。
2、掌握UCOS时间管理函数的用法。
3、掌握信号量的用法。
二、实验内容:
1.编写程序完成两个LED任务的轮流调度。
2.编写程序利用信号量完成键盘驱动LED和蜂鸣器的任务。(按键KEY0控制LED0灯的亮灭,按键KEY1控制蜂鸣器鸣叫。)
三、实验过程描述及结果展示:
实验原理:
使用时间管理函数完成各任务的并发运行:
使用信号量完成各任务间的同步:
实验代码:
//UCOSII任务的一般设置
//START_TASK任务
//设置任务的优先级
#define START_TASK 10 //设置开始任务的优先级为最低
//设置堆栈任务的大小
#define START_STK_SIZE 64
//任务堆栈
OS_STK START_TASK_STK[START_STK_SIZE];
//设置任务函数
void start_task(void *pdata);
//LED0任务
//设置任务优先级
#define LED0_TASK_PRIO 7
//设置任务堆栈大小
#define LED0_STK_SIZE 64
//任务堆栈
OS_STK LED0_TASK_STK[LED0_STK_SIZE];
//任务函数
void led0_task(void *pdata);
//任务1:LED1
//设置任务优先级
#define LED1_TASK_PRIO 6
//设置堆栈大小
#define LED1_STK_SIZE 64
//任务堆栈
OS_STK LED1_TASK_STK[LED1_STK_SIZE];
//任务函数
void led1_task(void *pdata);
int main(void)
{
delay_init(168); //初始化处理器时钟
uart_init(115200);//初始化串口
LED_Init(); //初始化LED端口
//对操作系统进行操作
{
OSInit();//操作系统初始化
//创建起始任务
OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK);
printf("ENTER MAIN ACCESS\r\n");
OSStart(); //启动操作系统,一去不回
}
}
void start_task(void * pdata)
{
OS_CPU_SR cpu_sr = 0; //临界区宏使用
pdata=pdata;
OS_ENTER_CRITICAL(); //进入临界区
OSTaskCreate(led0_task,(void *)0,(OS_STK *)&LED0_TASK_STK[LED0_STK_SIZE-1],LED0_TASK_PRIO);
OSTaskCreate(led1_task,(void *)0,(OS_STK *)&LED1_TASK_STK[LED1_STK_SIZE-1],LED1_TASK_PRIO);
OSTaskSuspend(START_TASK); //挂起开始任务
OS_EXIT_CRITICAL(); //退出临界区
}
//LED0任务
void led0_task(void *pdata)
{
pdata=pdata;
while(1)
{
printf("LED0_TASK_Running\r\n");
LED0 = 0; //点亮LED0
OSTimeDly(100);
LED0 = 1;
OSTimeDly(100);
}
}
void led1_task(void *pdata)
{
pdata=pdata;
while(1)
{
printf("LED1_TASK_Running\r\n");
LED1 = 0; //点亮LED0
OSTimeDly(100);
LED1 = 1;
OSTimeDly(100);
OSTimeDly(100);
}
}
实验二代码:(未完成)
//UCOSII任务的一般设置
//START_TASK任务
//设置任务的优先级
#define START_TASK 10 //设置开始任务的优先级为最低
//设置堆栈任务的大小
#define START_STK_SIZE 64
//任务堆栈
OS_STK START_TASK_STK[START_STK_SIZE];
//设置任务函数
void start_task(void *pdata);
//LED0任务
//设置任务优先级
#define LED0_TASK_PRIO 7
//设置任务堆栈大小
#define LED0_STK_SIZE 64
//任务堆栈
OS_STK LED0_TASK_STK[LED0_STK_SIZE];
//任务函数
void led0_task(void *pdata);
//任务:LED1
//设置任务优先级
#define LED1_TASK_PRIO 6
//设置堆栈大小
#define LED1_STK_SIZE 64
//任务堆栈
OS_STK LED1_TASK_STK[LED1_STK_SIZE];
//任务函数
void led1_task(void *pdata);
//任务:DEEP0
//设置任务优先级
#define DEEP0_TASK_PRIO 5
//设置堆栈大小
#define DEEP0_STK_SIZE 64
//任务堆栈
OS_STK DEEP0_TASK_STK[LED1_STK_SIZE];
//任务函数
void deep0_task(void *pdata);
//任务:DEEP1
//设置任务优先级
#define DEEP1_TASK_PRIO 5
//设置堆栈大小
#define DEEP1_STK_SIZE 64
//任务堆栈
OS_STK DEEP1_TASK_STK[LED1_STK_SIZE];
//任务函数
void deep1_task(void *pdata);
OS_EVENT * sem_beep;
OS_EVENT * sem_led;
int main(void)
{
delay_init(168); //初始化处理器时钟
uart_init(115200);//初始化串口
{GPIO_InitTypeDef GPIO_InitStructure1;//??GPIO?????
GPIO_InitTypeDef GPIO_InitStructure2;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//??GPIO??
GPIO_InitStructure1.GPIO_Pin = GPIO_Pin_9;//???GPIOF8??
GPIO_InitStructure2.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_OUT;//????
GPIO_InitStructure1.GPIO_OType = GPIO_OType_PP;//????
GPIO_InitStructure1.GPIO_Speed = GPIO_Speed_100MHz;//GPIO????
GPIO_InitStructure1.GPIO_PuPd = GPIO_PuPd_UP;//???????
GPIO_InitStructure2.GPIO_Mode = GPIO_Mode_OUT;//????
GPIO_InitStructure2.GPIO_OType = GPIO_OType_PP;//????
GPIO_InitStructure2.GPIO_Speed = GPIO_Speed_100MHz;//GPIO????
GPIO_InitStructure2.GPIO_PuPd = GPIO_PuPd_UP;//???????
GPIO_Init(GPIOF,&GPIO_InitStructure1);
GPIO_Init(GPIOF,&GPIO_InitStructure2);
}
{GPIO_InitTypeDef GPIO_InitStructure;//??GPIO?????
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//??GPIO??
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;//???GPIOF8??
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//????
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//????
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//GPIO????
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//???????
GPIO_Init(GPIOF,&GPIO_InitStructure);
GPIO_SetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10); //??
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE); //???GPIOE??
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 ;//???GPIOF8??
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//????
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//GPIO????
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//???????
GPIO_Init(GPIOE,&GPIO_InitStructure);
}
LED_Init(); //初始化LED端口
//对操作系统进行操作
{
OSInit();//操作系统初始化
//创建起始任务
OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK);
printf("ENTER MAIN ACCESS\r\n");
OSStart(); //启动操作系统,一去不回
}
}
void start_task(void * pdata)
{
OS_CPU_SR cpu_sr = 0; //临界区宏使用
pdata=pdata;
sem_beep=OSSemCreate(0);
sem_led=OSSemCreate(0);
OS_ENTER_CRITICAL(); //进入临界区
OSTaskCreate(led0_task,(void *)0,(OS_STK *)&LED0_TASK_STK[LED0_STK_SIZE-1],LED0_TASK_PRIO);
OSTaskCreate(led1_task,(void *)0,(OS_STK *)&LED1_TASK_STK[LED1_STK_SIZE-1],LED1_TASK_PRIO);
OSTaskCreate(deep0_task,(void *)0,(OS_STK *)&DEEP0_TASK_STK[DEEP0_STK_SIZE-1],DEEP0_TASK_PRIO);
OSTaskCreate(deep1_task,(void *)0,(OS_STK *)&DEEP1_TASK_STK[DEEP1_STK_SIZE-1],DEEP0_TASK_PRIO);
OSTaskSuspend(START_TASK); //挂起开始任务
OS_EXIT_CRITICAL(); //退出临界区
}
//LED0任务
void led0_task(void *pdata)
{
u8 err;
u8 i=0;
pdata=pdata;
while(1)
{
OSSemPend(sem_led,0,&err);
printf("LED0_TASK_Running\r\n");
if(i==0) GPIO_ResetBits(GPIOF,GPIO_Pin_9);
else GPIO_SetBits(GPIOF,GPIO_Pin_9);
i=!i;
OSTimeDly(100);
}
}
void led1_task(void *pdata)
{
pdata=pdata;
while(1)
{
printf("LED1_TASK_Running\r\n");
LED1 = 0; //点亮LED0
OSTimeDly(100);
LED1 = 1;
OSTimeDly(100);
OSTimeDly(100);
}
}
四、总结及实验心得:
此次实验在老师的带领下,第一次写了一个操作系统。
这个实验要求我们利用系统调度完成LED灯的交替闪烁,并利用串口在PC机上显示对应提示的字符。
总的来说,完成得很顺利,但是并没有一次就成功写对,之中有几个单词写错了,编译器报错。
第二个实验由于时间关系,在老师讲完第一个后只剩下半个小时。没能完全写完。
原文:http://www.cnblogs.com/bgd140201225/p/6539103.html