8、uCOS-Ⅱ 邮箱
1、 邮箱是信号量的扩展,相当于把一个指针定义的变量从一个任务传递到另一个或多个任务中去,这个指针是先发到邮箱,然后等待任务从邮箱里提取指针,这也就传递了指针指向的具体变量值。 等待邮箱的任务是可以设置无限等待和等待若干个时钟节拍后任务自动恢复执行。
2、实例代码
1 /***************************************************************************************************************************** 2 * 3 * 文件名称:main.c 4 * 文件功能:主函数 5 * 文件说明:无 6 * 7 *****************************************************************************************************************************/ 8 /********************************************************** 9 * 10 * 头文件声明 11 * 12 **********************************************************/ 13 14 #include "pbdata.h" 15 16 17 18 19 20 21 /********************************************************** 22 * 23 * 调用函数声明 24 * 25 **********************************************************/ 26 void RCC_Configuration(void);//时钟配置函数 27 28 void start_task(void *pdata);//开始任务函数 29 30 31 32 33 34 /********************************************************** 35 * 36 * 主函数 37 * 38 **********************************************************/ 39 int main(void) 40 { 41 Delay_Init();//延时函数初始化 42 43 RCC_Configuration();//时钟配置 44 45 LED_GPIO();//LED的GPIO引脚配置 46 47 48 49 /*操作系统的处理*/ 50 OSInit();//初始化UCOS操作系统 51 led1_MBOX=OSMboxCreate((void *)0);//建立一个消息邮箱 52 OSTaskCreate( 53 start_task, //指向任务代码的指针 54 (void *)0, //任务开始执行时,传递给任务参数的指针 55 (OS_STK *) & START_TASK_STK[START_STK_SIZE-1],//分配给任务堆栈的栈顶指针 56 START_TASK_PRIO//分配给任务的优先级 57 ); 58 OSStart();//启动OS操作系统 59 60 61 62 63 } 64 65 66 67 /********************************************************** 68 * 69 * 函数名称:RCC_Configuration(void) 70 * 函数功能:时钟配置 71 * 输入参数:无 72 * 输出参数:无 73 * 函数说明:无 74 * 75 **********************************************************/ 76 void RCC_Configuration(void) 77 { 78 SystemInit();//系统初始化 79 80 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//LED1对应GPIO时钟使能 81 82 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//按键对应GPIO时钟使能 83 } 84 85 86 87 88 89 90 /********************************************************** 91 * 92 * 函数名称:start_task(void *pdata) 93 * 函数功能:开始任务 94 * 输入参数:*pdata 95 * 输出参数:无 96 * 函数说明:无 97 * 98 **********************************************************/ 99 void start_task(void *pdata) 100 { 101 u8 msg[2]; 102 103 OS_CPU_SR cpu_sr=0; 104 105 pdata=pdata;//防止编译器报错 106 107 OSStatInit();//初始化统计任务 108 109 OS_ENTER_CRITICAL();//进入临界区,中断无法打断 110 111 /*创建任务*/ 112 /*LED1任务*/ 113 OSTaskCreate( 114 led1_task, //指向任务代码的指针 115 (void *)0, //任务开始执行时,传递给任务参数的指针 116 (OS_STK *) & LED1_TASK_STK[LED1_STK_SIZE-1],//分配给任务堆栈的栈顶指针 117 LED1_TASK_PRIO//分配给任务的优先级 118 ); 119 120 //OSTaskSuspend(START_TASK_PRIO);//挂起开始任务 121 122 OS_EXIT_CRITICAL();//退出临界区,可以被中断打断 123 124 while(1) 125 { 126 /*100ms*/ 127 msg[0]=0x00; 128 msg[1]=0x64; 129 /*发送出去*/ 130 OSMboxPost(led1_MBOX,(void *)&msg); 131 delay_ms(1000); 132 delay_ms(1000); 133 delay_ms(1000); 134 delay_ms(1000); 135 delay_ms(1000); 136 137 /*500ms*/ 138 msg[0]=0x01; 139 msg[1]=0xf4; 140 /*发送出去*/ 141 OSMboxPost(led1_MBOX,(void *)&msg); 142 delay_ms(1000); 143 delay_ms(1000); 144 delay_ms(1000); 145 delay_ms(1000); 146 delay_ms(1000); 147 148 } 149 150 }
1 /***************************************************************************************************************************** 2 * 3 * 文件名称:pbdata.c 4 * 文件功能:自定义函数 5 * 文件说明:无 6 * 7 *****************************************************************************************************************************/ 8 9 10 11 #include "pbdata.h" 12 13 u8 dt=0; 14 static u8 fac_us=0;//us延时倍乘数 15 static u16 fac_ms=0;//ms延时倍乘数 16 17 OS_EVENT* led1_MBOX;//定义一个邮箱指针变量 18 19 /********************************************************** 20 * 21 * 函数名称:Delay_Init(void) 22 * 函数功能:初始化延时函数 23 * 输入参数:无 24 * 输出参数:无 25 * 函数说明:当使用ucos的时候,此函数会初始化ucos的时钟节拍 26 * SYSTICK的时钟固定为HCLK时钟的1/8 27 * SYSCLK:系统时钟 28 * 29 **********************************************************/ 30 void Delay_Init(void) 31 { 32 u32 reload; 33 SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟,HCLK/8 34 fac_us=SystemCoreClock/8000000; //为系统时钟的1/8 35 36 reload=SystemCoreClock/8000000; //每秒钟的计数次数,单位为K 37 reload*=1000000/OS_TICKS_PER_SEC;//根据OS_TICKS_PER_SEC设定溢出事件,reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右 38 39 fac_ms=1000/OS_TICKS_PER_SEC;// 代表ucos可以延时的最少单位 40 SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断 41 SysTick->LOAD=reload; //每1/OS_TICKS_PER_SEC秒中断一次 42 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK 43 } 44 45 46 47 48 49 /********************************************************** 50 * 51 * 函数名称:delay_us(u32 nus) 52 * 函数功能:延时微秒子程序 53 * 输入参数:nus, 延时微秒数 54 * 输出参数:无 55 * 函数说明:无 56 * 57 **********************************************************/ 58 void delay_us(u32 nus) 59 { 60 u32 ticks; 61 u32 told,tnow,tcnt=0; 62 u32 reload=SysTick->LOAD; //LOAD的值 63 ticks=nus*fac_us; //需要的节拍数 64 tcnt=0; 65 told=SysTick->VAL; //刚进入时的计数器值 66 while(1) 67 { 68 tnow=SysTick->VAL; 69 if(tnow!=told) 70 { 71 if(tnow<told)tcnt+=told-tnow;//这里注意一下SYSTICK是一个递减的计数器就可以了 72 else tcnt+=reload-tnow+told; 73 told=tnow; 74 if(tcnt>=ticks)break;//时间超过/等于要延时的事件,则退出 75 } 76 }; 77 } 78 79 80 81 82 83 84 /********************************************************** 85 * 86 * 函数名称:delay_ms(u16 nms) 87 * 函数功能:延时毫秒子程序 88 * 输入参数:nms, 延时微秒数 89 * 输出参数:无 90 * 函数说明:无 91 * 92 **********************************************************/ 93 void delay_ms(u16 nms) 94 { 95 if(OSRunning==TRUE)//如果os已经在跑了 96 { 97 if(nms>=fac_ms)//延时的事件大于ucos的最少时间周期 98 { 99 OSTimeDly(nms/fac_ms);//ucos延时 100 } 101 nms%=fac_ms; //ucos已经无法提供这么小的延时了,采用普通方式延时 102 } 103 delay_us((u32)(nms*1000)); //普通方式延时,此时ucos无法启动调度 104 } 105 106 107 108 109 /********************************************************** 110 * 111 * 函数名称:delay(u32 nCount) 112 * 函数功能:普通不精确延时 113 * 输入参数:nCount, 延时时间长短 114 * 输出参数:无 115 * 函数说明:无 116 * 117 **********************************************************/ 118 void delay(u32 nCount) 119 { 120 for(;nCount!=0;nCount--); 121 }
1 /***************************************************************************************************************************** 2 * 3 * 文件名称:pbdata.h 4 * 文件功能:自定义函数的头文件声明 5 * 文件说明:无 6 * 7 *****************************************************************************************************************************/ 8 9 10 #ifndef _pbdata_H 11 #define _pbdata_H 12 13 14 15 16 17 18 /********************************************************** 19 * 20 * 需要引入的头文件 21 * 22 **********************************************************/ 23 #include "stm32f10x.h" 24 #include "includes.h" 25 #include "misc.h" 26 27 #include "led.h"//LED相关头文件 28 #include "key.h"//key相关头文件 29 30 31 /********************************************************** 32 * 33 * 任务相关设置 34 * 35 **********************************************************/ 36 /*开始任务*/ 37 #define START_TASK_PRIO 9 //设置任务优先级 38 #define START_STK_SIZE 64 //空间大小=64*4(字节) 39 static OS_STK START_TASK_STK[START_STK_SIZE];//创建任务堆栈空间 40 41 42 /*LED1任务*/ 43 #define LED1_TASK_PRIO 6 //设置任务优先级 44 #define LED1_STK_SIZE 64 //空间大小=64*4(字节) 45 static OS_STK LED1_TASK_STK[LED1_STK_SIZE];//创建任务堆栈空间 46 47 48 49 50 51 52 /********************************************************** 53 * 54 * 外部变量声明 55 * 56 **********************************************************/ 57 58 extern OS_EVENT* led1_MBOX;//定义一个邮箱指针变量 59 60 61 /********************************************************** 62 * 63 * 子函数程序声明 64 * 65 **********************************************************/ 66 void delay(u32 nCount);//普通不精确延时 67 void Delay_Init(void);//延时函数初始化 68 void delay_us(u32 nus);//微秒延时 69 void delay_ms(u16 nms);//毫秒延时 70 71 72 73 74 #endif
1 /***************************************************************************************************************************** 2 * 3 * 文件名称:led.c 4 * 文件功能:led相关函数 5 * 文件说明:无 6 * 7 *****************************************************************************************************************************/ 8 9 10 11 12 #include "pbdata.h" 13 14 15 16 /********************************************************** 17 * 18 * 函数名称:LED_GPIO(void) 19 * 函数功能:LED的GPIO配置 20 * 输入参数:无 21 * 输出参数:无 22 * 函数说明:无 23 * 24 **********************************************************/ 25 26 void LED_GPIO(void)//GPIO初始化函数 27 { 28 GPIO_InitTypeDef GPIO_InitStructure;//定义一个GPIO设置的结构体变量 29 30 /*LED1配置*/ 31 /*结构体变量赋值*/ 32 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;////引脚配置 33 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//配置频率 34 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出 35 /*对应的GPIO初始化*/ 36 GPIO_Init(GPIOB,&GPIO_InitStructure); 37 } 38 39 40 41 42 43 44 45 /********************************************************** 46 * 47 * 函数名称:led1_task(void *pdata) 48 * 函数功能:led1任务处理函数 49 * 输入参数:*pdata 50 * 输出参数:无 51 * 函数说明:无 52 * 53 **********************************************************/ 54 55 void led1_task(void *pdata) 56 { 57 INT8U err; 58 u16 led1_timer=500; 59 u8 *msg; 60 pdata=pdata; 61 62 63 while(1) 64 { 65 msg=(u8 *)OSMboxPend(led1_MBOX,10,&err);//等待消息邮箱,获取延时时间 66 67 if(err==OS_ERR_NONE) 68 { 69 led1_timer=(msg[0]<<8)+msg[1]; 70 71 if(led1_timer>1000) led1_timer=1000; 72 if(led1_timer<100) led1_timer=100; 73 } 74 75 GPIO_SetBits(GPIOB,GPIO_Pin_5); 76 delay_ms(led1_timer);// 77 GPIO_ResetBits(GPIOB,GPIO_Pin_5); 78 delay_ms(led1_timer);// 79 } 80 }
1 /***************************************************************************************************************************** 2 * 3 * 文件名称:led.h 4 * 文件功能:led相关函数的头文件 5 * 文件说明:无 6 * 7 *****************************************************************************************************************************/ 8 9 10 #ifndef _LED_H 11 #define _LED_H 12 13 #include "pbdata.h" 14 15 16 void LED_GPIO(void);//LED的GIPO引脚配置 17 18 void led1_task(void *pdata);//LED1任务 19 20 21 22 23 #endif
3、工程下载:
http://download.csdn.net/detail/a1181803348/8852095