程序功能:
任务2给串口发送数据,同时给任务3发送信号量,任务3收到信号量后,向串口发送数据。
如果任务2不向任务3发信号量,那么任务3不向串口发送数据。
程序主体如下:
#include "STM32Lib\\stm32f10x.h"
#include "hal.h"
#include "UCOSII\\ucos_ii.h"
/******************************
** 任务堆栈
*******************************/
OS_STK Task0Stk[128];
OS_STK Task1Stk[128];
OS_STK Task2Stk[128];
OS_STK Task3Stk[128];
/******************************
任务函数
******************************/
void Task0 (void *p_arg);
void Task1 (void *p_arg);
void Task2 (void *p_arg);
void Task3 (void *p_arg);
OS_EVENT *sem;
int main(void)
{
u8 os_err;
//由于使用UCOS,一下的初始化虽然可以在OS运行之前运行,但注意别使能任何中断.
ChipHalInit(); //片内硬件初始化
ChipOutHalInit(); //片外硬件初始化
OSInit(); //UCOS INIT~
os_err = OSTaskCreate( Task0, //第一个任务0
(void * ) 0, //不带参数
(OS_STK * )&Task0Stk[128 - 1], //堆栈指针
(INT8U ) 5 //优先级
);
OSStart();
while(1);
}
void Task0(void *p_arg)
{
u8 os_err;
char DATA_1[]="TASK1_ON\r\n";
OS_CPU_SysTickInit(); //使能SYSTICK中断
#if (OS_TASK_STAT_EN > 0)
OSStatInit(); /*这东西可以测量CPU使用量 */
#endif
//使能其他板上中断
//NVIC_Configuration();
os_err = OSTaskCreate( Task2, //任务2
&DATA_1, //不带参数
(OS_STK * )&Task2Stk[128 - 1], //堆栈指针
(INT8U ) 6 //优先级
);
os_err = OSTaskCreate( Task3, //任务3
(void * ) 0, //不带参数
(OS_STK * )&Task3Stk[128 - 1], //堆栈指针
(INT8U ) 7 //优先级
);
#if 0
os_err = OSTaskCreate( Task1, //任务1
(void * ) 0, //不带参数
(OS_STK * )&Task1Stk[128 - 1], //堆栈指针
(INT8U ) 8 //优先级
);
#endif
for(;;)
{
//OSTaskDel(2);
OSTimeDly(OS_TICKS_PER_SEC/2);
//USART1_Puts("TASK0_ON\r\n");
//LED1_ON;
//OSTimeDly(OS_TICKS_PER_SEC/10);
//LED1_OFF;
//USART1_Puts("TASK0_OFF\r\n");
}
}
void Task1(void *p_arg)
{
for(;;)
{
OSTimeDly(OS_TICKS_PER_SEC/10);
USART1_Puts(p_arg);
SendCan(0x1111);
LED2_ON;
OSTimeDly(OS_TICKS_PER_SEC/10);
USART1_Puts("TASK1_OFF\r\n");
LED2_OFF;
}
}
void Task2(void *p_arg)
{
sem=OSSemCreate(0);
for(;;)
{
USART1_Puts("1\r\n");
//OSTimeDly(OS_TICKS_PER_SEC/10);
OSSemPost(sem);
OSTimeDly(OS_TICKS_PER_SEC/10);
}
}
void Task3(void *p_arg)
{
INT8U err;
for(;;)
{
OSSemPend(sem,0,&err);
USART1_Puts("3\r\n");
OSTimeDly(OS_TICKS_PER_SEC/10);
}
}
效果如下:
假如把任务2中的OSSemPost(sem)注释,那么效果如下:
也可以中断中发送信号量,例如:当串口接收到数据后,在中断函数中想任务3发送信号量。
void USART1_IRQHandler(void)
{
CPU_SR cpu_sr;
OS_ENTER_CRITICAL();
OSIntNesting ;
OS_EXIT_CRITICAL();
//用户程序..
//接收中断
if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)
{
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
///Uart1_Get_Data=USART_ReceiveData(USART1);
OSSemPost(sem);
}
//溢出-如果发生溢出需要先读SR,再读DR寄存器 则可清除不断入中断的问题
if(USART_GetFlagStatus(USART1,USART_FLAG_ORE)==SET)
{
USART_ClearFlag(USART1,USART_FLAG_ORE); //读SR
///USART_ReceiveData(USART1); //读DR
}
OSIntExit();
}
需要特别说明的是:
任务2在创建信号量的时候,要在for(;;)的外面,一开始由于将创建信号量在for里面,导致程序不停地创建信号量,导致程序出错。
阅读(2838) | 评论(0) | 转发(1) |